From: Kirill Shcherbatov <kshcherbatov@tarantool.org> To: tarantool-patches@freelists.org, Vladimir Davydov <vdavydov.dev@gmail.com> Subject: Re: [tarantool-patches] Re: [PATCH v6 1/3] box: refactor key_def_set_compare_func routine Date: Fri, 15 Mar 2019 13:20:11 +0300 [thread overview] Message-ID: <9b725e11-1fe7-6cad-d810-5181056cde9d@tarantool.org> (raw) In-Reply-To: <20190314070447.dpdu3aocinfiwrtr@esperanza> Refactored key_def_set_compare_func routine to make it easier to read, maintain, and extend. This is necessary due to the fact that in a series of subsequent patches it will be significantly expanded. Needed for #3961 --- src/box/tuple_compare.cc | 195 +++++++++++++++++++-------------------- 1 file changed, 93 insertions(+), 102 deletions(-) diff --git a/src/box/tuple_compare.cc b/src/box/tuple_compare.cc index dfe30b190..7fe1766a8 100644 --- a/src/box/tuple_compare.cc +++ b/src/box/tuple_compare.cc @@ -986,7 +986,7 @@ struct comparator_signature { /** * field1 no, field1 type, field2 no, field2 type, ... */ -static const comparator_signature cmp_arr[] = { +static const comparator_signature precompiled_cmp_arr[] = { COMPARATOR(0, FIELD_TYPE_UNSIGNED) COMPARATOR(0, FIELD_TYPE_STRING) COMPARATOR(0, FIELD_TYPE_UNSIGNED, 1, FIELD_TYPE_UNSIGNED) @@ -1005,55 +1005,6 @@ static const comparator_signature cmp_arr[] = { #undef COMPARATOR -static const tuple_compare_t compare_slowpath_funcs[] = { - tuple_compare_slowpath<false, false, false>, - tuple_compare_slowpath<true, false, false>, - tuple_compare_slowpath<false, true, false>, - tuple_compare_slowpath<true, true, false>, - tuple_compare_slowpath<false, false, true>, - tuple_compare_slowpath<true, false, true>, - tuple_compare_slowpath<false, true, true>, - tuple_compare_slowpath<true, true, true> -}; - -static tuple_compare_t -tuple_compare_create(const struct key_def *def) -{ - int cmp_func_idx = (def->is_nullable ? 1 : 0) + - 2 * (def->has_optional_parts ? 1 : 0) + - 4 * (def->has_json_paths ? 1 : 0); - if (def->is_nullable) { - if (key_def_is_sequential(def)) { - if (def->has_optional_parts) - return tuple_compare_sequential<true, true>; - else - return tuple_compare_sequential<true, false>; - } else { - return compare_slowpath_funcs[cmp_func_idx]; - } - } - assert(! def->has_optional_parts); - if (!key_def_has_collation(def) && !def->has_json_paths) { - /* Precalculated comparators don't use collation */ - for (uint32_t k = 0; - k < sizeof(cmp_arr) / sizeof(cmp_arr[0]); k++) { - uint32_t i = 0; - for (; i < def->part_count; i++) - if (def->parts[i].fieldno != - cmp_arr[k].p[i * 2] || - def->parts[i].type != - cmp_arr[k].p[i * 2 + 1]) - break; - if (i == def->part_count && - cmp_arr[k].p[i * 2] == UINT32_MAX) - return cmp_arr[k].f; - } - } - return key_def_is_sequential(def) ? - tuple_compare_sequential<false, false> : - compare_slowpath_funcs[cmp_func_idx]; -} - /* }}} tuple_compare */ /* {{{ tuple_compare_with_key */ @@ -1215,7 +1166,7 @@ struct comparator_with_key_signature #define KEY_COMPARATOR(...) \ { TupleCompareWithKey<0, __VA_ARGS__>::compare, { __VA_ARGS__ } }, -static const comparator_with_key_signature cmp_wk_arr[] = { +static const comparator_with_key_signature precompiled_cmp_wk_arr[] = { KEY_COMPARATOR(0, FIELD_TYPE_UNSIGNED, 1, FIELD_TYPE_UNSIGNED, 2, FIELD_TYPE_UNSIGNED) KEY_COMPARATOR(0, FIELD_TYPE_STRING , 1, FIELD_TYPE_UNSIGNED, 2, FIELD_TYPE_UNSIGNED) KEY_COMPARATOR(0, FIELD_TYPE_UNSIGNED, 1, FIELD_TYPE_STRING , 2, FIELD_TYPE_UNSIGNED) @@ -1231,68 +1182,108 @@ static const comparator_with_key_signature cmp_wk_arr[] = { KEY_COMPARATOR(1, FIELD_TYPE_STRING , 2, FIELD_TYPE_STRING) }; -#undef KEY_COMPARATOR - -static const tuple_compare_with_key_t compare_with_key_slowpath_funcs[] = { - tuple_compare_with_key_slowpath<false, false, false>, - tuple_compare_with_key_slowpath<true, false, false>, - tuple_compare_with_key_slowpath<false, true, false>, - tuple_compare_with_key_slowpath<true, true, false>, - tuple_compare_with_key_slowpath<false, false, true>, - tuple_compare_with_key_slowpath<true, false, true>, - tuple_compare_with_key_slowpath<false, true, true>, - tuple_compare_with_key_slowpath<true, true, true> +#undef KEY_COMPARATORq + +#define COMPARE_SLOWPATH(...) \ + {tuple_compare_slowpath<__VA_ARGS__>, \ + tuple_compare_with_key_slowpath<__VA_ARGS__>, \ + __VA_ARGS__, false} + +#define COMPARE_SEQUENTIAL(...) \ + {tuple_compare_sequential<__VA_ARGS__>, \ + tuple_compare_with_key_sequential<__VA_ARGS__>, \ + __VA_ARGS__, false, true} + +static struct { + tuple_compare_t tuple_compare; + tuple_compare_with_key_t tuple_compare_with_key; + bool is_nullable; + bool has_optional_parts; + bool has_json_paths; + bool is_sequential; +} cmp_arr[] = { + COMPARE_SLOWPATH(false, false, false), + COMPARE_SLOWPATH(true, false, false), + COMPARE_SLOWPATH(false, true, false), + COMPARE_SLOWPATH(true, true, false), + COMPARE_SLOWPATH(false, false, true), + COMPARE_SLOWPATH(true, false, true), + COMPARE_SLOWPATH(false, true, true), + COMPARE_SLOWPATH(true, true, true), + COMPARE_SEQUENTIAL(false, false), + COMPARE_SEQUENTIAL(true, false), + COMPARE_SEQUENTIAL(false, true), + COMPARE_SEQUENTIAL(true, true), }; -static tuple_compare_with_key_t -tuple_compare_with_key_create(const struct key_def *def) +#undef COMPARE_SLOWPATH +#undef COMPARE_SEQUENTIAL + +/* }}} tuple_compare_with_key */ + +void +key_def_set_compare_func(struct key_def *def) { - int cmp_func_idx = (def->is_nullable ? 1 : 0) + - 2 * (def->has_optional_parts ? 1 : 0) + - 4 * (def->has_json_paths ? 1 : 0); - if (def->is_nullable) { - if (key_def_is_sequential(def)) { - if (def->has_optional_parts) { - return tuple_compare_with_key_sequential<true, - true>; - } else { - return tuple_compare_with_key_sequential<true, - false>; + def->tuple_compare = NULL; + def->tuple_compare_with_key = NULL; + if (!def->is_nullable && !key_def_has_collation(def) && + !def->has_json_paths) { + /* Precalculated comparators don't use collation */ + for (uint32_t k = 0; k < sizeof(precompiled_cmp_arr) / + sizeof(precompiled_cmp_arr[0]); k++) { + uint32_t i = 0; + for (; i < def->part_count; i++) { + if (def->parts[i].fieldno != + precompiled_cmp_arr[k].p[i * 2] || + def->parts[i].type != + precompiled_cmp_arr[k].p[i * 2 + 1]) + break; + } + if (i == def->part_count && + precompiled_cmp_arr[k].p[i * 2] == UINT32_MAX) { + def->tuple_compare = precompiled_cmp_arr[k].f; + break; } - } else { - return compare_with_key_slowpath_funcs[cmp_func_idx]; } - } - assert(! def->has_optional_parts); - if (!key_def_has_collation(def) && !def->has_json_paths) { - /* Precalculated comparators don't use collation */ - for (uint32_t k = 0; - k < sizeof(cmp_wk_arr) / sizeof(cmp_wk_arr[0]); - k++) { - + for (uint32_t k = 0; k < sizeof(precompiled_cmp_wk_arr) / + sizeof(precompiled_cmp_wk_arr[0]); k++) { uint32_t i = 0; for (; i < def->part_count; i++) { if (def->parts[i].fieldno != - cmp_wk_arr[k].p[i * 2] || - def->parts[i].type != - cmp_wk_arr[k].p[i * 2 + 1]) { + precompiled_cmp_wk_arr[k].p[i * 2] || + def->parts[i].type != + precompiled_cmp_wk_arr[k].p[i * 2 + 1]) break; + } + if (i == def->part_count) { + def->tuple_compare_with_key = + precompiled_cmp_wk_arr[k].f; + break; + } + } + } + if (def->tuple_compare == NULL || def->tuple_compare_with_key == NULL) { + for (uint32_t k = 0; k < sizeof(cmp_arr) / + sizeof(cmp_arr[0]); k++) { + if (def->is_nullable == cmp_arr[k].is_nullable && + def->has_optional_parts == + cmp_arr[k].has_optional_parts && + def->has_json_paths == cmp_arr[k].has_json_paths && + key_def_is_sequential(def) == + cmp_arr[k].is_sequential) { + if (def->tuple_compare == NULL) { + def->tuple_compare = + cmp_arr[k].tuple_compare; } + if (def->tuple_compare_with_key == NULL) { + def->tuple_compare_with_key = + cmp_arr[k]. + tuple_compare_with_key; + } + break; } - if (i == def->part_count) - return cmp_wk_arr[k].f; } } - return key_def_is_sequential(def) ? - tuple_compare_with_key_sequential<false, false> : - compare_with_key_slowpath_funcs[cmp_func_idx]; -} - -/* }}} tuple_compare_with_key */ - -void -key_def_set_compare_func(struct key_def *def) -{ - def->tuple_compare = tuple_compare_create(def); - def->tuple_compare_with_key = tuple_compare_with_key_create(def); + assert(def->tuple_compare != NULL && + def->tuple_compare_with_key != NULL); } -- 2.21.0
next prev parent reply other threads:[~2019-03-15 10:20 UTC|newest] Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-03-13 12:15 [PATCH v6 0/3] box: introduce hint option for memtx tree index Kirill Shcherbatov 2019-03-13 12:15 ` [PATCH v6 1/3] box: refactor key_def_set_compare_func routine Kirill Shcherbatov 2019-03-14 7:04 ` Vladimir Davydov 2019-03-15 10:20 ` Kirill Shcherbatov [this message] 2019-03-15 10:55 ` [tarantool-patches] " Kirill Shcherbatov 2019-03-19 19:38 ` Vladimir Davydov 2019-03-13 12:15 ` [PATCH v6 2/3] memtx: introduce tuple compare hint Kirill Shcherbatov 2019-03-14 8:19 ` Vladimir Davydov 2019-03-15 10:20 ` [tarantool-patches] " Kirill Shcherbatov 2019-03-20 18:08 ` Vladimir Davydov 2019-03-13 12:15 ` [PATCH v6 3/3] box: introduce multikey indexes Kirill Shcherbatov
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=9b725e11-1fe7-6cad-d810-5181056cde9d@tarantool.org \ --to=kshcherbatov@tarantool.org \ --cc=tarantool-patches@freelists.org \ --cc=vdavydov.dev@gmail.com \ --subject='Re: [tarantool-patches] Re: [PATCH v6 1/3] box: refactor key_def_set_compare_func routine' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox