rendered paste bodydiff --git a/mod/box/box.h b/mod/box/box.hindex b2cd699..3923075 100644--- a/mod/box/box.h+++ b/mod/box/box.h@@ -45,7 +45,6 @@ struct space { Index *index[BOX_INDEX_MAX]; /** Size of index array */ int key_count;- int n; int cardinality; /** Index metadata. */@@ -140,6 +139,45 @@ ENUM(messages, MESSAGES); extern iproto_callback rw_callback; +/**+ * Get space ordinal number.+ */+static inline int+space_n(struct space *sp)+{+ if (sp < space || sp >= (space + BOX_SPACE_MAX)) {+ panic("Invalid space pointer");+ }+ return sp - space;+}++/**+ * Get key_def ordinal number.+ */+static inline int+key_def_n(struct space *sp, struct key_def *kp)+{+ if (kp < sp->key_defs || kp >= (sp->key_defs + sp->key_count)) {+ panic("Invalid key_def pointer");+ }+ return kp - sp->key_defs;+}++/**+ * Get index ordinal number.+ */+static inline int+index_n(Index *index)+{+ return key_def_n(index->space, index->key_def);+}++static inline bool+index_is_primary(Index *index)+{+ return index_n(index) == 0;+}+ /* These are used to implement memcached 'GET' */ static inline struct box_txn *in_txn() { return fiber->mod_data.txn; } struct box_txn *txn_begin();diff --git a/mod/box/box.m b/mod/box/box.mindex ecd4afb..85153ad 100644--- a/mod/box/box.m+++ b/mod/box/box.m@@ -142,14 +142,13 @@ validate_indexes(struct box_txn *txn) if (index->key_def->parts[f].type == NUM64 && len != sizeof(u64)) tnt_raise(IllegalParams, :"field must be NUM64"); }- if (index->type == TREE && index->key_def->is_unique == false)- /* Don't check non unique indexes */- continue;-- struct box_tuple *tuple = [index findByTuple: txn->tuple]; - if (tuple != NULL && tuple != txn->old_tuple)- tnt_raise(ClientError, :ER_INDEX_VIOLATION);+ /* Check key uniqueness */+ if (index->key_def->is_unique) {+ struct box_tuple *tuple = [index findByTuple: txn->tuple];+ if (tuple != NULL && tuple != txn->old_tuple)+ tnt_raise(ClientError, :ER_INDEX_VIOLATION);+ } } } @@ -489,20 +488,13 @@ process_select(struct box_txn *txn, u32 limit, u32 offset, struct tbuf *data) u32 key_cardinality = read_u32(data); void *key = NULL; - if (key_cardinality != 0)+ if (key_cardinality) { key = read_field(data); - /*- * For TREE indexes, we allow partially specified- * keys. HASH indexes are always unique and can- * not have multiple parts.- */- if (index->type == HASH && key_cardinality != 1)- tnt_raise(IllegalParams, :"key must be single valued");-- /* advance remaining fields of a key */- for (int i = 1; i < key_cardinality; i++)- read_field(data);+ /* advance remaining fields of a key */+ for (int i = 1; i < key_cardinality; i++)+ read_field(data);+ } struct iterator *it = index->position; [index initIterator: it :key :key_cardinality];@@ -1046,7 +1038,7 @@ space_init_field_types(struct space *space) && space->field_types[part->fieldno] != UNKNOWN) { space->field_types[part->fieldno] = UNKNOWN; say_warn("type conflict in space %d for field %d",- space->n, part->fieldno);+ space_n(space), part->fieldno); } } }@@ -1070,7 +1062,6 @@ space_config(void) assert(cfg.memcached_port == 0 || i != cfg.memcached_space); space[i].enabled = true;- space[i].n = i; space[i].cardinality = cfg_space->cardinality; /*@@ -1098,8 +1089,9 @@ space_config(void) for (int j = 0; cfg_space->index[j] != NULL; ++j) { typeof(cfg_space->index[j]) cfg_index = cfg_space->index[j]; enum index_type type = STR2ENUM(index_type, cfg_index->type);- Index *index = [Index alloc: type :&space[i] :j];- [index init: type :&space[i] :j];+ struct key_def *key_def = &space[i].key_defs[j];+ Index *index = [Index alloc: type :key_def :&space[i]];+ [index init: key_def :&space[i]]; space[i].index[j] = index; } say_info("space %i successfully configured", i);diff --git a/mod/box/box_lua.m b/mod/box/box_lua.mindex 02f30c3..0a5087d 100644--- a/mod/box/box_lua.m+++ b/mod/box/box_lua.m@@ -292,7 +292,7 @@ lbox_index_tostring(struct lua_State *L) { Index *index = lua_checkindex(L, 1); lua_pushfstring(L, "index %d in space %d",- index->n, index->space->n);+ index_n(index), space_n(index->space)); return 1; } diff --git a/mod/box/index.h b/mod/box/index.hindex 0ccd99b..2808d69 100644--- a/mod/box/index.h+++ b/mod/box/index.h@@ -86,22 +86,25 @@ struct key_def { struct iterator *position; /* Description of a possibly multipart key. */ struct key_def *key_def;- enum index_type type; bool enabled;- /* Relative offset of the index in its namespace. */- u32 n; }; -+ (Index *) alloc: (enum index_type) type :(struct space *) space- :(u32) n_arg;+/**+ * Allocate index instance.+ *+ * @param type index type+ * @param key_def key part description+ * @param space space the index belongs to+ */++ (Index *) alloc: (enum index_type) type :(struct key_def *) key_def+ :(struct space *) space; /** * Initialize index instance. *+ * @param key_def key part description * @param space space the index belongs to- * @param key key part description */-- (id) init: (enum index_type) type_arg :(struct space *) space_arg- :(u32) n_arg;+- (id) init: (struct key_def *) key_def_arg :(struct space *) space_arg; /** Destroy and free index instance. */ - (void) free; /**diff --git a/mod/box/index.m b/mod/box/index.mindex 112c913..034cf5d 100644--- a/mod/box/index.m+++ b/mod/box/index.m@@ -58,10 +58,10 @@ iterator_first_equal(struct iterator *it) @class HashStrIndex; @class TreeIndex; -+ (Index *) alloc: (enum index_type) type :(struct space *) space- :(u32) n_arg;++ (Index *) alloc: (enum index_type) type+ :(struct key_def *) key_def+ :(struct space *) space {- struct key_def *key_def = &space->key_defs[n_arg]; switch (type) { case HASH: /* Hash index, check key type.@@ -79,20 +79,17 @@ iterator_first_equal(struct iterator *it) } break; case TREE:- return [TreeIndex alloc: space :n_arg];+ return [TreeIndex alloc: key_def :space]; default: break; } panic("unsupported index type"); } -- (id) init: (enum index_type) type_arg :(struct space *) space_arg- :(u32) n_arg;+- (id) init: (struct key_def *) key_def_arg :(struct space *) space_arg { self = [super init];- key_def = &space_arg->key_defs[n_arg];- type = type_arg;- n = n_arg;+ key_def = key_def_arg; space = space_arg; position = [self allocIterator]; [self enable];@@ -364,18 +361,18 @@ hash_iterator_free(struct iterator *iterator) - (void) initIterator: (struct iterator *) iterator :(void *) key :(int) part_count {+ assert(iterator->next = hash_iterator_next); struct hash_iterator *it = hash_iterator(iterator); - (void) part_count;- assert(part_count == 1);- assert(iterator->next = hash_iterator_next);+ if (part_count != 1)+ tnt_raise(IllegalParams, :"key must be single valued"); u32 field_size = load_varint32(&key);- u32 num = *(u32 *)key;- if (field_size != 4) tnt_raise(IllegalParams, :"key is not u32"); + u32 num = *(u32 *)key;+ it->base.next_equal = iterator_first_equal; it->h_pos = mh_i32ptr_get(int_hash, num); it->hash = int_hash;@@ -487,17 +484,17 @@ hash_iterator_free(struct iterator *iterator) :(int) part_count { assert(iterator->next = hash_iterator_next);- assert(part_count == 1);- (void) part_count;- struct hash_iterator *it = hash_iterator(iterator); - u32 field_size = load_varint32(&field);- u64 num = *(u64 *)field;+ if (part_count != 1)+ tnt_raise(IllegalParams, :"key must be single valued"); + u32 field_size = load_varint32(&field); if (field_size != 8) tnt_raise(IllegalParams, :"key is not u64"); + u64 num = *(u64 *)field;+ it->base.next_equal = iterator_first_equal; it->h_pos = mh_i64ptr_get(int64_hash, num); it->hash = (struct mh_i32ptr_t *) int64_hash;@@ -600,11 +597,11 @@ hash_iterator_free(struct iterator *iterator) :(int) part_count { assert(iterator->next = hash_iterator_next);- assert(part_count== 1);- (void) part_count;- struct hash_iterator *it = hash_iterator(iterator); + if (part_count != 1)+ tnt_raise(IllegalParams, :"key must be single valued");+ it->base.next_equal = iterator_first_equal; it->h_pos = mh_lstrptr_get(str_hash, key); it->hash = (struct mh_i32ptr_t *) str_hash;@@ -629,9 +626,9 @@ build_indexes(void) if (index == nil) break; - if (index->type != TREE)- continue;- [(TreeIndex*) index build: pk];+ if ([index isKindOf: [TreeIndex class]]) {+ [(TreeIndex *) index build: pk];+ } } say_info("Space %"PRIu32": done", n); }diff --git a/mod/box/memcached.m b/mod/box/memcached.mindex c79312d..3717294 100644--- a/mod/box/memcached.m+++ b/mod/box/memcached.m@@ -436,7 +436,6 @@ memcached_space_init() struct space *memc_s = &space[cfg.memcached_space]; memc_s->enabled = true; memc_s->cardinality = 4;- memc_s->n = cfg.memcached_space; memc_s->key_count = 1; memc_s->key_defs = malloc(sizeof(struct key_def));@@ -462,8 +461,8 @@ memcached_space_init() key_def->cmp_order[0] = 0; /* Configure memcached index. */- Index *memc_index = memc_s->index[0] = [Index alloc: HASH :memc_s :0];- [memc_index init: HASH :memc_s :0];+ Index *memc_index = memc_s->index[0] = [Index alloc: HASH :key_def :memc_s];+ [memc_index init: key_def :memc_s]; } /** Delete a bunch of expired keys. */diff --git a/mod/box/tree.h b/mod/box/tree.hindex 57b1f98..e51f167 100644--- a/mod/box/tree.h+++ b/mod/box/tree.h@@ -41,7 +41,7 @@ typedef int (*tree_cmp_t)(const void *, const void *, void *); sptree_index tree; }; -+ (Index *) alloc: (struct space *) space :(u32) n_arg;++ (Index *) alloc: (struct key_def *) key_def :(struct space *) space; - (void) build: (Index *) pk; /** To be defined in subclasses. */diff --git a/mod/box/tree.m b/mod/box/tree.mindex 2649bc3..86873ac 100644--- a/mod/box/tree.m+++ b/mod/box/tree.m@@ -695,9 +695,9 @@ tree_iterator_free(struct iterator *iterator) @class Num32TreeIndex; @class FixedTreeIndex; -+ (Index *) alloc: (struct space *) space :(u32) n_arg++ (Index *) alloc: (struct key_def *) key_def :(struct space *) space {- enum tree_type type = find_tree_type(space, &space->key_defs[n_arg]);+ enum tree_type type = find_tree_type(space, key_def); switch (type) { case TREE_SPARSE: return [SparseTreeIndex alloc];@@ -721,7 +721,7 @@ tree_iterator_free(struct iterator *iterator) { enabled = false; memset(&tree, 0, sizeof tree);- if (n == 0) /* pk */ {+ if (index_is_primary(self)) { sptree_index_init(&tree, [self node_size], NULL, 0, 0, [self key_node_cmp], [self node_cmp],@@ -865,7 +865,8 @@ tree_iterator_free(struct iterator *iterator) } if (n_tuples) {- say_info("Sorting %"PRIu32 " keys in index %" PRIu32 "...", n_tuples, self->n);+ say_info("Sorting %"PRIu32 " keys in index %" PRIu32 "...", n_tuples,+ index_n(self)); } /* If n_tuples == 0 then estimated_tuples = 0, elem == NULL, tree is empty */