diff --git a/src/box/memtx_hash.cc b/src/box/memtx_hash.cc index 0b6a90e12bb16ebd1dabee8673caf29ce2a6eabd..4afad8dac1681834a15daa96bbbe37a917eb2e4a 100644 --- a/src/box/memtx_hash.cc +++ b/src/box/memtx_hash.cc @@ -170,13 +170,10 @@ hash_iterator_ge(struct iterator *ptr) assert(ptr->free == hash_iterator_free); struct hash_iterator *it = (struct hash_iterator *) ptr; - if (it->h_pos < it->hash_table->table_size) { - struct tuple *res = light_index_get(it->hash_table, it->h_pos); + while (it->h_pos < it->hash_table->table_size) { + if (light_index_pos_valid(it->hash_table, it->h_pos)) + return light_index_get(it->hash_table, it->h_pos++); it->h_pos++; - while (it->h_pos < it->hash_table->table_size - && !light_index_pos_valid(it->hash_table, it->h_pos)) - it->h_pos++; - return res; } return NULL; } diff --git a/src/lib/salad/light.h b/src/lib/salad/light.h index bd3c139ccfd3f9a09f301ee40bb0f5f3851db723..074f15cafe333e45587b9ab1ecbe20ca6eb00ce3 100644 --- a/src/lib/salad/light.h +++ b/src/lib/salad/light.h @@ -234,6 +234,7 @@ LIGHT(delete)(struct LIGHT(core) *ht, uint32_t slotpos); * @brief Get a value from a desired position * @param ht - pointer to a hash table struct * @param slotpos - ID of an record + * ID must be vaild, check it by light_pos_valid (asserted). */ LIGHT_DATA_TYPE LIGHT(get)(struct LIGHT(core) *ht, uint32_t slotpos); @@ -242,6 +243,7 @@ LIGHT(get)(struct LIGHT(core) *ht, uint32_t slotpos); * @brief Determine if posision holds a value * @param ht - pointer to a hash table struct * @param slotpos - ID of an record + * ID must be in valid range [0, ht->table_size) (asserted). */ bool LIGHT(pos_valid)(struct LIGHT(core) *ht, uint32_t slotpos); @@ -667,8 +669,10 @@ LIGHT(delete_value)(struct LIGHT(core) *ht, uint32_t hash, LIGHT_DATA_TYPE value inline LIGHT_DATA_TYPE LIGHT(get)(struct LIGHT(core) *ht, uint32_t slotpos) { + assert(slotpos < ht->table_size); struct LIGHT(record) *record = (struct LIGHT(record) *) matras_get(&ht->mtable, slotpos); + assert(record->next != slotpos); return record->value; } @@ -680,6 +684,7 @@ LIGHT(get)(struct LIGHT(core) *ht, uint32_t slotpos) inline bool LIGHT(pos_valid)(LIGHT(core) *ht, uint32_t slotpos) { + assert(slotpos < ht->table_size); struct LIGHT(record) *record = (struct LIGHT(record) *) matras_get(&ht->mtable, slotpos); return record->next != slotpos; diff --git a/test/big/hash.result b/test/big/hash.result index da96ab72e56efb776eeb05811ab8299aa3f069e2..f1120fcfae7fba0c2d59523c2c8ca281131485be 100644 --- a/test/big/hash.result +++ b/test/big/hash.result @@ -674,3 +674,23 @@ hash.index['field3']:get{0} hash:drop() --- ... +hash = box.schema.create_space('tweedledum') +--- +... +hi = hash:create_index('primary', { type = 'hash', parts = {1, 'num'}, unique = true }) +--- +... +hash:insert{0} +--- +- [0] +... +hash:insert{16} +--- +- [16] +... +for _, tuple in hi:pairs(nil, {iterator = box.index.ALL}) do hash:delete{tuple[1]} end +--- +... +hash:drop() +--- +... diff --git a/test/big/hash.test.lua b/test/big/hash.test.lua index 7abc2a8436fc5e71c0ae99fad75a84d48b68dc19..a3dbb69b39906c042001980e56f69f6415e5dc1b 100644 --- a/test/big/hash.test.lua +++ b/test/big/hash.test.lua @@ -288,3 +288,10 @@ hash.index['field3']:get{10} hash.index['field3']:get{0} hash:drop() + +hash = box.schema.create_space('tweedledum') +hi = hash:create_index('primary', { type = 'hash', parts = {1, 'num'}, unique = true }) +hash:insert{0} +hash:insert{16} +for _, tuple in hi:pairs(nil, {iterator = box.index.ALL}) do hash:delete{tuple[1]} end +hash:drop()