Skip to content

Commit e93c8ed

Browse files
committed
Replace linear space scan with hash for update fields
closes tarantoolgh-24
1 parent 108b658 commit e93c8ed

File tree

2 files changed

+65
-64
lines changed

2 files changed

+65
-64
lines changed

src/tarantool_schema.c

+57-58
Original file line numberDiff line numberDiff line change
@@ -14,27 +14,41 @@
1414
#define MUR_SEED 13
1515
#include "third_party/msgpuck.h"
1616

17-
int mh_indexcmp_eq(
18-
const struct schema_index_value **lval,
19-
const struct schema_index_value **rval,
20-
void *arg
21-
) {
22-
(void )arg;
23-
if ((*lval)->key.id_len != (*rval)->key.id_len)
24-
return 0;
25-
return !memcmp((*lval)->key.id, (*rval)->key.id, (*rval)->key.id_len);
26-
}
17+
#define MH_DEFINE_CMPFUNC(NAME, TYPE) \
18+
int mh_##NAME##cmp_eq(const TYPE **lval, const TYPE **rval, void *arg) { \
19+
(void *) arg; \
20+
if ((*lval)->key.id_len != (*rval)->key.id_len) \
21+
return 0; \
22+
return !memcmp((*lval)->key.id, (*rval)->key.id, (*rval)->key.id_len); \
23+
} \
24+
\
25+
int mh_##NAME##cmp_key_eq(const struct schema_key *key, const TYPE **val, void *arg) { \
26+
(void *) arg; \
27+
if (key->id_len != (*val)->key.id_len) \
28+
return 0; \
29+
return !memcmp(key->id, (*val)->key.id, key->id_len); \
30+
}
31+
MH_DEFINE_CMPFUNC(field, struct schema_field_value);
32+
MH_DEFINE_CMPFUNC(index, struct schema_index_value);
33+
MH_DEFINE_CMPFUNC(space, struct schema_space_value);
34+
#undef MH_DEFINE_CMPFUNC
2735

28-
int mh_indexcmp_key_eq(
29-
const struct schema_key *key,
30-
const struct schema_index_value **val,
31-
void *arg
32-
) {
33-
(void )arg;
34-
if (key->id_len != (*val)->key.id_len)
35-
return 0;
36-
return !memcmp(key->id, (*val)->key.id, key->id_len);
37-
}
36+
#define mh_arg_t void *
37+
38+
#define mh_eq(a, b, arg) mh_fieldcmp_eq(a, b, arg)
39+
#define mh_eq_key(a, b, arg) mh_fieldcmp_key_eq(a, b, arg)
40+
#define mh_hash(x, arg) PMurHash32(MUR_SEED, (*x)->key.id, (*x)->key.id_len)
41+
#define mh_hash_key(x, arg) PMurHash32(MUR_SEED, (x)->id, (x)->id_len);
42+
43+
#define mh_node_t struct schema_field_value *
44+
#define mh_key_t struct schema_key *
45+
46+
#define MH_CALLOC(x, y) pecalloc((x), (y), 1)
47+
#define MH_FREE(x) pefree((x), 1)
48+
49+
#define mh_name _schema_field
50+
#define MH_SOURCE 1
51+
#include "third_party/mhash.h"
3852

3953
#define mh_arg_t void *
4054

@@ -79,7 +93,7 @@ schema_index_free(struct mh_schema_index_t *schema) {
7993
do {
8094
struct schema_key key_number = {
8195
(void *)&(ivalue->index_number),
82-
sizeof(uint32_t), 0
96+
sizeof(ivalue->index_number), 0
8397
};
8498
index_slot = mh_schema_index_find(schema, &key_number,
8599
NULL);
@@ -106,28 +120,6 @@ schema_index_free(struct mh_schema_index_t *schema) {
106120
}
107121
}
108122

109-
int
110-
mh_spacecmp_eq(
111-
const struct schema_space_value **lval,
112-
const struct schema_space_value **rval,
113-
void *arg) {
114-
(void )arg;
115-
if ((*lval)->key.id_len != (*rval)->key.id_len)
116-
return 0;
117-
return !memcmp((*lval)->key.id, (*rval)->key.id, (*rval)->key.id_len);
118-
}
119-
120-
int
121-
mh_spacecmp_key_eq(
122-
const struct schema_key *key,
123-
const struct schema_space_value **val,
124-
void *arg) {
125-
(void )arg;
126-
if (key->id_len != (*val)->key.id_len)
127-
return 0;
128-
return !memcmp(key->id, (*val)->key.id, key->id_len);
129-
}
130-
131123
#define mh_arg_t void *
132124

133125
#define mh_eq(a, b, arg) mh_spacecmp_eq(a, b, arg)
@@ -158,6 +150,9 @@ schema_space_value_free(const struct schema_space_value *val) {
158150
schema_index_free(val->index_hash);
159151
mh_schema_index_delete(val->index_hash);
160152
}
153+
if (val->schema_hash) {
154+
mh_schema_field_delete(val->schema_hash);
155+
}
161156
}
162157
}
163158

@@ -263,6 +258,11 @@ parse_schema_space_value(struct schema_space_value *space_string,
263258
goto error;
264259
}
265260
val->field_number = i;
261+
val->key.id = val->field_name;
262+
val->key.id_len = val->field_name_len;
263+
mh_schema_field_put(space_string->schema_hash,
264+
(const struct schema_field_value **)&val,
265+
NULL, NULL);
266266
}
267267
return 0;
268268
error:
@@ -367,6 +367,7 @@ schema_add_space(
367367
* }
368368
*/
369369
case 6:
370+
space_string->schema_hash = mh_schema_field_new();
370371
if (parse_schema_space_value(space_string, &tuple) < 0)
371372
goto error;
372373
break;
@@ -590,23 +591,21 @@ tarantool_schema_get_fid_by_string(
590591
struct tarantool_schema *schema_obj, uint32_t sid,
591592
const char *field_name, uint32_t field_name_len
592593
) {
593-
struct mh_schema_space_t *schema = schema_obj->space_hash;
594-
struct schema_key space_key = {
595-
(void *)&sid,
596-
sizeof(uint32_t), 0
597-
};
598-
mh_int_t space_slot = mh_schema_space_find(schema, &space_key, NULL);
599-
if (space_slot == mh_end(schema))
594+
struct mh_schema_space_t *sschema = schema_obj->space_hash;
595+
struct schema_key space_key = { (void *)&sid, sizeof(uint32_t), 0 };
596+
mh_int_t space_slot = mh_schema_space_find(sschema, &space_key, NULL);
597+
if (space_slot == mh_end(sschema))
600598
return -1;
601-
const struct schema_space_value *space = *mh_schema_space_node(schema,
599+
const struct schema_space_value *space = *mh_schema_space_node(sschema,
602600
space_slot);
603-
int i = 0;
604-
for (i = 0; i < space->schema_list_len; ++i) {
605-
struct schema_field_value *val = &space->schema_list[i];
606-
if (strncmp(val->field_name, field_name, field_name_len) == 0)
607-
return val->field_number;
608-
}
609-
return -1;
601+
struct schema_key field_key = { field_name, field_name_len, 0 };
602+
struct mh_schema_field_t *fschema = space->schema_hash;
603+
mh_int_t field_slot = mh_schema_field_find(fschema, &field_key, NULL);
604+
if (field_slot == mh_end(fschema))
605+
return -1;
606+
const struct schema_field_value *field = *mh_schema_field_node(fschema,
607+
field_slot);
608+
return field->field_number;
610609
}
611610

612611
struct tarantool_schema *tarantool_schema_new(int is_persistent) {

src/tarantool_schema.h

+8-6
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,18 @@ enum field_type {
1414
};
1515

1616
struct schema_field_value {
17-
uint32_t field_number;
18-
char *field_name;
19-
uint32_t field_name_len;
20-
enum field_type field_type;
17+
struct schema_key key;
18+
uint32_t field_number;
19+
char *field_name;
20+
uint32_t field_name_len;
21+
enum field_type field_type;
2122
};
2223

2324
struct schema_index_value {
2425
struct schema_key key;
26+
uint32_t index_number;
2527
char *index_name;
2628
uint32_t index_name_len;
27-
uint32_t index_number;
2829
struct schema_field_value *index_parts;
2930
uint32_t index_parts_len;
3031
};
@@ -33,10 +34,11 @@ struct mh_schema_index_t;
3334

3435
struct schema_space_value {
3536
struct schema_key key;
37+
uint32_t space_number;
3638
char *space_name;
3739
uint32_t space_name_len;
38-
uint32_t space_number;
3940
struct mh_schema_index_t *index_hash;
41+
struct mh_schema_field_t *schema_hash;
4042
struct schema_field_value *schema_list;
4143
uint32_t schema_list_len;
4244
};

0 commit comments

Comments
 (0)