Store precomputed hash when there's capacity
Co-authored-by: Jean Boussier <byroot@ruby-lang.org>
This commit is contained in:
parent
350baed6a9
commit
84a8b911c1
Notes:
git
2024-11-06 11:57:35 +00:00
21
string.c
21
string.c
@ -350,9 +350,14 @@ mustnot_wchar(VALUE str)
|
|||||||
|
|
||||||
static int fstring_cmp(VALUE a, VALUE b);
|
static int fstring_cmp(VALUE a, VALUE b);
|
||||||
|
|
||||||
static VALUE register_fstring(VALUE str, bool copy, bool precompute_hash);
|
static VALUE register_fstring(VALUE str, bool copy, bool force_precompute_hash);
|
||||||
|
|
||||||
#if SIZEOF_LONG == SIZEOF_VOIDP
|
#if SIZEOF_LONG == SIZEOF_VOIDP
|
||||||
|
#define PRECOMPUTED_FAKESTR_HASH 1
|
||||||
|
#else
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PRECOMPUTED_FAKESTR_HASH
|
||||||
static st_index_t
|
static st_index_t
|
||||||
fstring_hash(VALUE str)
|
fstring_hash(VALUE str)
|
||||||
{
|
{
|
||||||
@ -367,6 +372,7 @@ fstring_hash(VALUE str)
|
|||||||
#else
|
#else
|
||||||
#define fstring_hash rb_str_hash
|
#define fstring_hash rb_str_hash
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const struct st_hash_type rb_fstring_hash_type = {
|
const struct st_hash_type rb_fstring_hash_type = {
|
||||||
fstring_cmp,
|
fstring_cmp,
|
||||||
fstring_hash,
|
fstring_hash,
|
||||||
@ -407,7 +413,7 @@ str_store_precomputed_hash(VALUE str, st_index_t hash)
|
|||||||
struct fstr_update_arg {
|
struct fstr_update_arg {
|
||||||
VALUE fstr;
|
VALUE fstr;
|
||||||
bool copy;
|
bool copy;
|
||||||
bool precompute_hash;
|
bool force_precompute_hash;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -436,7 +442,7 @@ fstr_update_callback(st_data_t *key, st_data_t *value, st_data_t data, int exist
|
|||||||
long capa = len + sizeof(st_index_t);
|
long capa = len + sizeof(st_index_t);
|
||||||
int term_len = TERM_LEN(str);
|
int term_len = TERM_LEN(str);
|
||||||
|
|
||||||
if (arg->precompute_hash && STR_EMBEDDABLE_P(capa, term_len)) {
|
if (arg->force_precompute_hash && STR_EMBEDDABLE_P(capa, term_len)) {
|
||||||
new_str = str_alloc_embed(rb_cString, capa + term_len);
|
new_str = str_alloc_embed(rb_cString, capa + term_len);
|
||||||
memcpy(RSTRING_PTR(new_str), RSTRING_PTR(str), len);
|
memcpy(RSTRING_PTR(new_str), RSTRING_PTR(str), len);
|
||||||
STR_SET_LEN(new_str, RSTRING_LEN(str));
|
STR_SET_LEN(new_str, RSTRING_LEN(str));
|
||||||
@ -447,6 +453,11 @@ fstr_update_callback(st_data_t *key, st_data_t *value, st_data_t data, int exist
|
|||||||
else {
|
else {
|
||||||
new_str = str_new(rb_cString, RSTRING(str)->as.heap.ptr, RSTRING(str)->len);
|
new_str = str_new(rb_cString, RSTRING(str)->as.heap.ptr, RSTRING(str)->len);
|
||||||
rb_enc_copy(new_str, str);
|
rb_enc_copy(new_str, str);
|
||||||
|
#ifdef PRECOMPUTED_FAKESTR_HASH
|
||||||
|
if (rb_str_capacity(new_str) >= RSTRING_LEN(str) + term_len + sizeof(st_index_t)) {
|
||||||
|
str_store_precomputed_hash(new_str, (st_index_t)RSTRING(str)->as.heap.aux.capa);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
str = new_str;
|
str = new_str;
|
||||||
}
|
}
|
||||||
@ -515,11 +526,11 @@ rb_fstring(VALUE str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
register_fstring(VALUE str, bool copy, bool precompute_hash)
|
register_fstring(VALUE str, bool copy, bool force_precompute_hash)
|
||||||
{
|
{
|
||||||
struct fstr_update_arg args = {
|
struct fstr_update_arg args = {
|
||||||
.copy = copy,
|
.copy = copy,
|
||||||
.precompute_hash = precompute_hash
|
.force_precompute_hash = force_precompute_hash
|
||||||
};
|
};
|
||||||
|
|
||||||
#if SIZEOF_VOIDP == SIZEOF_LONG
|
#if SIZEOF_VOIDP == SIZEOF_LONG
|
||||||
|
Loading…
x
Reference in New Issue
Block a user