From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp48.i.mail.ru (smtp48.i.mail.ru [94.100.177.108]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id 52BD6446441 for ; Wed, 23 Sep 2020 04:14:22 +0300 (MSK) From: Alexander Turenko Date: Wed, 23 Sep 2020 04:14:13 +0300 Message-Id: In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [Tarantool-patches] [PATCH 08/14] WIP: refactoring: extract key_def module API functions List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Vladislav Shpilevoy Cc: tarantool-patches@dev.tarantool.org, Alexander Turenko I plan to expand module API for key_def in further commits and mix of public and private structures and functions becomes hard to read. So it looks meaningful to extract module API wrappers into its own compilation unit. Added libtuple.a to the so called reexport libraries list, because otherwise the functions from key_def_api compilation unit are not exported on 1.10 (in the backported patch). Part of #5273 --- src/CMakeLists.txt | 4 +- src/box/CMakeLists.txt | 1 + src/box/key_def.c | 62 ++++---------------- src/box/key_def.h | 86 ++++++++++----------------- src/box/key_def_api.c | 79 +++++++++++++++++++++++++ src/box/key_def_api.h | 101 ++++++++++++++++++++++++++++++++ test/unit/vy_iterators_helper.c | 1 + test/unit/vy_mem.c | 1 + test/unit/vy_point_lookup.c | 1 + test/unit/vy_write_iterator.c | 1 + 10 files changed, 228 insertions(+), 109 deletions(-) create mode 100644 src/box/key_def_api.c create mode 100644 src/box/key_def_api.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 699536652..89e5bbc34 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -145,7 +145,7 @@ set(api_headers ${CMAKE_SOURCE_DIR}/src/lua/string.h ${CMAKE_SOURCE_DIR}/src/box/txn.h ${CMAKE_SOURCE_DIR}/src/box/tuple.h - ${CMAKE_SOURCE_DIR}/src/box/key_def.h + ${CMAKE_SOURCE_DIR}/src/box/key_def_api.h ${CMAKE_SOURCE_DIR}/src/box/lua/key_def.h ${CMAKE_SOURCE_DIR}/src/box/field_def.h ${CMAKE_SOURCE_DIR}/src/box/tuple_format.h @@ -179,7 +179,7 @@ target_link_libraries(server core coll http_parser bit uri uuid swim swim_udp # Rule of thumb: if exporting a symbol from a static library, list the # library here. set (reexport_libraries server core misc bitset csv swim swim_udp swim_ev - ${LUAJIT_LIBRARIES} ${MSGPUCK_LIBRARIES} ${ICU_LIBRARIES}) + tuple ${LUAJIT_LIBRARIES} ${MSGPUCK_LIBRARIES} ${ICU_LIBRARIES}) set (common_libraries ${reexport_libraries} diff --git a/src/box/CMakeLists.txt b/src/box/CMakeLists.txt index b8b2689d2..7d8170f93 100644 --- a/src/box/CMakeLists.txt +++ b/src/box/CMakeLists.txt @@ -104,6 +104,7 @@ add_library(tuple STATIC tuple_bloom.c tuple_dictionary.c key_def.c + key_def_api.c coll_id_def.c coll_id.c coll_id_cache.c diff --git a/src/box/key_def.c b/src/box/key_def.c index a03537227..fc1666eff 100644 --- a/src/box/key_def.c +++ b/src/box/key_def.c @@ -146,7 +146,7 @@ key_def_delete(struct key_def *def) free(def); } -static void +void key_def_set_func(struct key_def *def) { key_def_set_compare_func(def); @@ -341,56 +341,6 @@ key_def_dump_parts(const struct key_def *def, struct key_part_def *parts, return 0; } -box_key_def_t * -box_key_def_new(uint32_t *fields, uint32_t *types, uint32_t part_count) -{ - size_t sz = key_def_sizeof(part_count, 0); - struct key_def *key_def = calloc(1, sz); - if (key_def == NULL) { - diag_set(OutOfMemory, sz, "malloc", "struct key_def"); - return NULL; - } - - key_def->part_count = part_count; - key_def->unique_part_count = part_count; - - for (uint32_t item = 0; item < part_count; ++item) { - if (key_def_set_part(key_def, item, fields[item], - (enum field_type)types[item], - ON_CONFLICT_ACTION_DEFAULT, NULL, - COLL_NONE, SORT_ORDER_ASC, NULL, 0, NULL, - TUPLE_OFFSET_SLOT_NIL, 0) != 0) { - key_def_delete(key_def); - return NULL; - } - } - key_def_set_func(key_def); - return key_def; -} - -void -box_key_def_delete(box_key_def_t *key_def) -{ - key_def_delete(key_def); -} - -int -box_tuple_compare(box_tuple_t *tuple_a, box_tuple_t *tuple_b, - box_key_def_t *key_def) -{ - return tuple_compare(tuple_a, HINT_NONE, tuple_b, HINT_NONE, key_def); -} - -int -box_tuple_compare_with_key(box_tuple_t *tuple_a, const char *key_b, - box_key_def_t *key_def) -{ - uint32_t part_count = mp_decode_array(&key_b); - return tuple_compare_with_key(tuple_a, HINT_NONE, key_b, - part_count, HINT_NONE, key_def); - -} - int key_part_cmp(const struct key_part *parts1, uint32_t part_count1, const struct key_part *parts2, uint32_t part_count2) @@ -892,3 +842,13 @@ key_validate_parts(const struct key_def *key_def, const char *key, *key_end = key; return 0; } + +int +key_def_set_part_175(struct key_def *def, uint32_t part_no, uint32_t fieldno, + enum field_type type) +{ + return key_def_set_part(def, part_no, fieldno, type, + ON_CONFLICT_ACTION_DEFAULT, NULL, COLL_NONE, + SORT_ORDER_ASC, NULL, 0, NULL, + TUPLE_OFFSET_SLOT_NIL, 0); +} diff --git a/src/box/key_def.h b/src/box/key_def.h index 625bb6fea..a4be3aef7 100644 --- a/src/box/key_def.h +++ b/src/box/key_def.h @@ -287,62 +287,6 @@ key_def_copy(struct key_def *dest, const struct key_def *src); void key_def_delete(struct key_def *def); -typedef struct tuple box_tuple_t; - -/** \cond public */ - -typedef struct key_def box_key_def_t; - -/** - * Create key definition with key fields with passed typed on passed positions. - * May be used for tuple format creation and/or tuple comparison. - * - * \param fields array with key field identifiers - * \param types array with key field types (see enum field_type) - * \param part_count the number of key fields - * \returns a new key definition object - */ -API_EXPORT box_key_def_t * -box_key_def_new(uint32_t *fields, uint32_t *types, uint32_t part_count); - -/** - * Delete key definition - * - * \param key_def key definition to delete - */ -API_EXPORT void -box_key_def_delete(box_key_def_t *key_def); - -/** - * Compare tuples using the key definition. - * @param tuple_a first tuple - * @param tuple_b second tuple - * @param key_def key definition - * @retval 0 if key_fields(tuple_a) == key_fields(tuple_b) - * @retval <0 if key_fields(tuple_a) < key_fields(tuple_b) - * @retval >0 if key_fields(tuple_a) > key_fields(tuple_b) - */ -API_EXPORT int -box_tuple_compare(box_tuple_t *tuple_a, box_tuple_t *tuple_b, - box_key_def_t *key_def); - -/** - * @brief Compare tuple with key using the key definition. - * @param tuple tuple - * @param key key with MessagePack array header - * @param key_def key definition - * - * @retval 0 if key_fields(tuple) == parts(key) - * @retval <0 if key_fields(tuple) < parts(key) - * @retval >0 if key_fields(tuple) > parts(key) - */ - -API_EXPORT int -box_tuple_compare_with_key(box_tuple_t *tuple_a, const char *key_b, - box_key_def_t *key_def); - -/** \endcond public */ - static inline size_t key_def_sizeof(uint32_t part_count, uint32_t path_pool_size) { @@ -755,6 +699,36 @@ key_hint(const char *key, uint32_t part_count, struct key_def *key_def) return key_def->key_hint(key, part_count, key_def); } +/* {{{ () helpers */ + +/** + * Set key part within @a key_def. + * + * The same as module private (), but with less + * parameters. It is helper for (). + * + * 1.7.5 does not support collation, nullability and further + * key_def features. + */ +int +key_def_set_part_175(struct key_def *def, uint32_t part_no, uint32_t fieldno, + enum field_type type); + +/** + * Update compare, hash and extract functions. + * + * This function should be called after modification of + * @a key_def parts, because different compare, hash and extract + * functions should work depending of whether key parts are + * sequential, are nullable, whether a tuple may omit several + * fields at the end, whether a collation is used and so on. + * It is helper for (). + */ +void +key_def_set_func(struct key_def *def); + +/* }}} () helpers */ + #if defined(__cplusplus) } /* extern "C" */ #endif /* defined(__cplusplus) */ diff --git a/src/box/key_def_api.c b/src/box/key_def_api.c new file mode 100644 index 000000000..7f6c0ac55 --- /dev/null +++ b/src/box/key_def_api.c @@ -0,0 +1,79 @@ +/* + * Copyright 2010-2020, Tarantool AUTHORS, please see AUTHORS file. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include "key_def_api.h" +#include "key_def.h" + +box_key_def_t * +box_key_def_new(uint32_t *fields, uint32_t *types, uint32_t part_count) +{ + size_t sz = key_def_sizeof(part_count, 0); + struct key_def *key_def = calloc(1, sz); + if (key_def == NULL) { + diag_set(OutOfMemory, sz, "malloc", "struct key_def"); + return NULL; + } + + key_def->part_count = part_count; + key_def->unique_part_count = part_count; + + for (uint32_t item = 0; item < part_count; ++item) { + if (key_def_set_part_175(key_def, item, fields[item], + (enum field_type)types[item]) != 0) { + key_def_delete(key_def); + return NULL; + } + } + key_def_set_func(key_def); + return key_def; +} + +void +box_key_def_delete(box_key_def_t *key_def) +{ + key_def_delete(key_def); +} + +int +box_tuple_compare(box_tuple_t *tuple_a, box_tuple_t *tuple_b, + box_key_def_t *key_def) +{ + return tuple_compare(tuple_a, HINT_NONE, tuple_b, HINT_NONE, key_def); +} + +int +box_tuple_compare_with_key(box_tuple_t *tuple_a, const char *key_b, + box_key_def_t *key_def) +{ + uint32_t part_count = mp_decode_array(&key_b); + return tuple_compare_with_key(tuple_a, HINT_NONE, key_b, + part_count, HINT_NONE, key_def); + +} diff --git a/src/box/key_def_api.h b/src/box/key_def_api.h new file mode 100644 index 000000000..5b1c861f5 --- /dev/null +++ b/src/box/key_def_api.h @@ -0,0 +1,101 @@ +#ifndef TARANTOOL_BOX_KEY_DEF_API_H_INCLUDED +#define TARANTOOL_BOX_KEY_DEF_API_H_INCLUDED +/* + * Copyright 2010-2020, Tarantool AUTHORS, please see AUTHORS file. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(__cplusplus) +extern "C" { +#endif /* defined(__cplusplus) */ + +#include +#include "trivia/util.h" + +typedef struct tuple box_tuple_t; + +/** \cond public */ + +typedef struct key_def box_key_def_t; + +/** + * Create key definition with given field numbers and field types. + * + * May be used for tuple format creation and/or tuple comparison. + * + * \param fields array with key field identifiers + * \param types array with key field types (see enum field_type) + * \param part_count the number of key fields + * \returns a new key definition object + */ +API_EXPORT box_key_def_t * +box_key_def_new(uint32_t *fields, uint32_t *types, uint32_t part_count); + +/** + * Delete key definition + * + * \param key_def key definition to delete + */ +API_EXPORT void +box_key_def_delete(box_key_def_t *key_def); + +/** + * Compare tuples using the key definition. + * @param tuple_a first tuple + * @param tuple_b second tuple + * @param key_def key definition + * @retval 0 if key_fields(tuple_a) == key_fields(tuple_b) + * @retval <0 if key_fields(tuple_a) < key_fields(tuple_b) + * @retval >0 if key_fields(tuple_a) > key_fields(tuple_b) + */ +API_EXPORT int +box_tuple_compare(box_tuple_t *tuple_a, box_tuple_t *tuple_b, + box_key_def_t *key_def); + +/** + * @brief Compare tuple with key using the key definition. + * @param tuple tuple + * @param key key with MessagePack array header + * @param key_def key definition + * + * @retval 0 if key_fields(tuple) == parts(key) + * @retval <0 if key_fields(tuple) < parts(key) + * @retval >0 if key_fields(tuple) > parts(key) + */ +API_EXPORT int +box_tuple_compare_with_key(box_tuple_t *tuple_a, const char *key_b, + box_key_def_t *key_def); + +/** \endcond public */ + +#if defined(__cplusplus) +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + +#endif /* TARANTOOL_BOX_KEY_API_DEF_H_INCLUDED */ diff --git a/test/unit/vy_iterators_helper.c b/test/unit/vy_iterators_helper.c index 0d20f19ef..1897d341c 100644 --- a/test/unit/vy_iterators_helper.c +++ b/test/unit/vy_iterators_helper.c @@ -1,3 +1,4 @@ +#include "key_def_api.h" #include "vy_iterators_helper.h" #include "memory.h" #include "fiber.h" diff --git a/test/unit/vy_mem.c b/test/unit/vy_mem.c index 2e461f312..1ad6c9641 100644 --- a/test/unit/vy_mem.c +++ b/test/unit/vy_mem.c @@ -1,6 +1,7 @@ #include #include "memory.h" #include "fiber.h" +#include "key_def_api.h" #include "vy_history.h" #include "vy_iterators_helper.h" diff --git a/test/unit/vy_point_lookup.c b/test/unit/vy_point_lookup.c index fb075c578..e55f0edd9 100644 --- a/test/unit/vy_point_lookup.c +++ b/test/unit/vy_point_lookup.c @@ -1,5 +1,6 @@ #include "trivia/util.h" #include "unit.h" +#include "key_def_api.h" #include "vy_lsm.h" #include "vy_cache.h" #include "vy_run.h" diff --git a/test/unit/vy_write_iterator.c b/test/unit/vy_write_iterator.c index 97fb2df37..173eb600c 100644 --- a/test/unit/vy_write_iterator.c +++ b/test/unit/vy_write_iterator.c @@ -1,5 +1,6 @@ #include "memory.h" #include "fiber.h" +#include "key_def_api.h" #include "vy_write_iterator.h" #include "vy_iterators_helper.h" -- 2.25.0