Skip to content
Snippets Groups Projects
Commit e9b4c19a authored by Konstantin Osipov's avatar Konstantin Osipov
Browse files

Merge branch 'tuple-compare-hash'

parents a6161fa8 b3ae55dc
No related branches found
No related tags found
No related merge requests found
......@@ -170,6 +170,32 @@ _mh(next_slot)(mh_int_t slot, mh_int_t inc, mh_int_t size)
return slot >= size ? slot - size : slot;
}
#if defined(mh_hash_key) && defined(mh_eq_key)
/**
* If it is necessary to search by something different
* than a hash node, define mh_hash_key and mh_eq_key
* and use mh_find().
*/
static inline mh_int_t
_mh(find)(struct _mh(t) *h, mh_key_t key, mh_arg_t arg)
{
(void) arg;
mh_int_t k = mh_hash_key(key, arg);
mh_int_t i = k % h->n_buckets;
mh_int_t inc = 1 + k % (h->n_buckets - 1);
for (;;) {
if ((mh_exist(h, i) && mh_eq_key(key, mh_node(h, i), arg)))
return i;
if (!mh_dirty(h, i))
return h->n_buckets;
i = _mh(next_slot)(i, inc, h->n_buckets);
}
}
#endif
static inline mh_int_t
_mh(get)(struct _mh(t) *h, const mh_node_t *node,
mh_arg_t arg)
......@@ -504,9 +530,12 @@ _mh(dump)(struct _mh(t) *h)
#undef mh_int_t
#undef mh_node_t
#undef mh_arg_t
#undef mh_key_t
#undef mh_name
#undef mh_hash
#undef mh_hash_key
#undef mh_eq
#undef mh_eq_key
#undef mh_node
#undef mh_dirty
#undef mh_place
......
This diff is collapsed.
......@@ -31,33 +31,35 @@
#include "index.h"
struct mh_index_t;
class HashIndex: public Index {
public:
static HashIndex *
factory(struct key_def *key_def, struct space *space);
HashIndex(struct key_def *key_def, struct space *space);
~HashIndex();
virtual void beginBuild();
virtual void buildNext(struct tuple *tuple);
virtual void endBuild();
virtual void build(Index *pk);
virtual size_t size() const = 0;
virtual size_t size() const;
virtual struct tuple *min() const;
virtual struct tuple *max() const;
virtual struct tuple *random(u32 rnd) const = 0;
virtual struct tuple *findByKey(const char *key, u32 part_count) const = 0;
virtual struct tuple *random(u32 rnd) const;
virtual struct tuple *findByKey(const char *key, u32 part_count) const;
virtual struct tuple *replace(struct tuple *old_tuple,
struct tuple *new_tuple,
enum dup_replace_mode mode) = 0;
enum dup_replace_mode mode);
virtual struct iterator *allocIterator() const = 0;
virtual struct iterator *allocIterator() const;
virtual void initIterator(struct iterator *iterator,
enum iterator_type type,
const char *key, u32 part_count) const = 0;
const char *key, u32 part_count) const;
virtual void reserve(u32 n_tuples);
virtual void reserve(u32 n_tuples) = 0;
protected:
struct mh_index_t *hash;
};
#endif /* TARANTOOL_BOX_HASH_INDEX_H_INCLUDED */
......@@ -143,7 +143,7 @@ Index::factory(enum index_type type, struct key_def *key_def, struct space *spac
{
switch (type) {
case HASH:
return HashIndex::factory(key_def, space);
return new HashIndex(key_def, space);
case TREE:
return new TreeIndex(key_def, space);
case BITSET:
......
......@@ -586,12 +586,6 @@ check_spaces(struct tarantool_cfg *conf)
switch (index_type) {
case HASH:
/* check hash index */
/* hash index must has single-field key */
if (key_part_count != 1) {
out_warning(CNF_OK, "(space = %zu index = %zu) "
"hash index must has a single-field key", i, j);
return -1;
}
/* hash index must be unique */
if (!index->unique) {
out_warning(CNF_OK, "(space = %zu index = %zu) "
......
......@@ -156,25 +156,41 @@ error: 'Invalid key part count in an exact match (expected 1, got 2)'
# Insert valid fieds
lua box.space[11]:insert('00000000', 'value1 v1.0', 'value2 v1.0')
lua box.space[11]:insert(0ULL, 'value1 v1.0', 'value2 v1.0')
---
- 3472328296227680304: {'value1 v1.0', 'value2 v1.0'}
- 0: {'value1 v1.0', 'value2 v1.0'}
...
lua box.space[11]:insert('00000001', 'value1 v1.0', 'value2 v1.0')
lua box.space[11]:insert(1ULL, 'value1 v1.0', 'value2 v1.0')
---
- 3544385890265608240: {'value1 v1.0', 'value2 v1.0'}
- 1: {'value1 v1.0', 'value2 v1.0'}
...
lua box.space[11]:insert('00000002', 'value1 v1.0', 'value2 v1.0')
lua box.space[11]:insert(2ULL, 'value1 v1.0', 'value2 v1.0')
---
- 3616443484303536176: {'value1 v1.0', 'value2 v1.0'}
- 2: {'value1 v1.0', 'value2 v1.0'}
...
lua box.space[11]:insert('00000003', 'value1 v1.0', 'value2 v1.0')
lua box.space[11]:insert(3ULL, 'value1 v1.0', 'value2 v1.0')
---
- 3688501078341464112: {'value1 v1.0', 'value2 v1.0'}
- 3: {'value1 v1.0', 'value2 v1.0'}
...
# Insert invalid fields
lua box.space[11]:insert(100, 'value1 v1.0', 'value2 v1.0')
---
error: 'Supplied key field type does not match index type: expected u64'
...
lua box.space[11]:insert(101, 'value1 v1.0', 'value2 v1.0')
---
error: 'Supplied key field type does not match index type: expected u64'
...
lua box.space[11]:insert(102, 'value1 v1.0', 'value2 v1.0')
---
error: 'Supplied key field type does not match index type: expected u64'
...
lua box.space[11]:insert(103, 'value1 v1.0', 'value2 v1.0')
---
error: 'Supplied key field type does not match index type: expected u64'
...
lua box.space[11]:insert('invalid key', 'value1 v1.0', 'value2 v1.0')
---
error: 'Supplied key field type does not match index type: expected u64'
......@@ -187,24 +203,36 @@ error: 'Supplied key field type does not match index type: expected u64'
# Replace valid fieds
lua box.space[11]:replace('00000003', 'value1 v1.31', 'value2 1.12')
lua box.space[11]:replace(3ULL, 'value1 v1.31', 'value2 1.12')
---
- 3688501078341464112: {'value1 v1.31', 'value2 1.12'}
- 3: {'value1 v1.31', 'value2 1.12'}
...
lua box.space[11]:replace('00000001', 'value1 v1.32', 'value2 1.72')
lua box.space[11]:replace(1ULL, 'value1 v1.32', 'value2 1.72')
---
- 3544385890265608240: {'value1 v1.32', 'value2 1.72'}
- 1: {'value1 v1.32', 'value2 1.72'}
...
lua box.space[11]:replace('00000002', 'value1 v1.43', 'value2 1.92')
lua box.space[11]:replace(2ULL, 'value1 v1.43', 'value2 1.92')
---
- 3616443484303536176: {'value1 v1.43', 'value2 1.92'}
- 2: {'value1 v1.43', 'value2 1.92'}
...
# Replace invalid fields
lua box.space[10]:replace('invalid key', 'value1 v1.0', 'value2 v1.0')
lua box.space[11]:replace(3, 'value1 v1.31', 'value2 1.12')
---
error: 'Supplied key field type does not match index type: expected u32'
error: 'Supplied key field type does not match index type: expected u64'
...
lua box.space[11]:replace(1, 'value1 v1.32', 'value2 1.72')
---
error: 'Supplied key field type does not match index type: expected u64'
...
lua box.space[11]:replace(2, 'value1 v1.43', 'value2 1.92')
---
error: 'Supplied key field type does not match index type: expected u64'
...
lua box.space[11]:replace('invalid key', 'value1 v1.0', 'value2 v1.0')
---
error: 'Supplied key field type does not match index type: expected u64'
...
#-----------------------------------------------------------------------------#
......@@ -214,26 +242,51 @@ error: 'Supplied key field type does not match index type: expected u32'
# select by valid keys
lua box.space[11]:select(0, '00000000')
lua box.space[11]:select(0, 0ULL)
---
- 3472328296227680304: {'value1 v1.0', 'value2 v1.0'}
- 0: {'value1 v1.0', 'value2 v1.0'}
...
lua box.space[11]:select(0, '00000001')
lua box.space[11]:select(0, 1ULL)
---
- 3544385890265608240: {'value1 v1.32', 'value2 1.72'}
- 1: {'value1 v1.32', 'value2 1.72'}
...
lua box.space[11]:select(0, '00000002')
lua box.space[11]:select(0, 2ULL)
---
- 3616443484303536176: {'value1 v1.43', 'value2 1.92'}
- 2: {'value1 v1.43', 'value2 1.92'}
...
lua box.space[11]:select(0, '00000003')
lua box.space[11]:select(0, 3ULL)
---
- 3688501078341464112: {'value1 v1.31', 'value2 1.12'}
- 3: {'value1 v1.31', 'value2 1.12'}
...
lua box.space[11]:select(0, '00000004')
lua box.space[11]:select(0, 4ULL)
---
...
lua box.space[11]:select(0, '00000005')
lua box.space[11]:select(0, 5ULL)
---
...
# select by valid NUM keys
lua box.space[11]:select(0, 0)
---
- 0: {'value1 v1.0', 'value2 v1.0'}
...
lua box.space[11]:select(0, 1)
---
- 1: {'value1 v1.32', 'value2 1.72'}
...
lua box.space[11]:select(0, 2)
---
- 2: {'value1 v1.43', 'value2 1.92'}
...
lua box.space[11]:select(0, 3)
---
- 3: {'value1 v1.31', 'value2 1.12'}
...
lua box.space[11]:select(0, 4)
---
...
lua box.space[11]:select(0, 5)
---
...
......@@ -255,26 +308,67 @@ error: 'Invalid key part count (expected [0..1], got 2)'
# delete by valid keys
lua box.space[11]:delete('00000000')
lua box.space[11]:delete(0ULL)
---
- 0: {'value1 v1.0', 'value2 v1.0'}
...
lua box.space[11]:delete(1ULL)
---
- 1: {'value1 v1.32', 'value2 1.72'}
...
lua box.space[11]:delete(2ULL)
---
- 3472328296227680304: {'value1 v1.0', 'value2 v1.0'}
- 2: {'value1 v1.43', 'value2 1.92'}
...
lua box.space[11]:delete('00000001')
lua box.space[11]:delete(3ULL)
---
- 3544385890265608240: {'value1 v1.32', 'value2 1.72'}
- 3: {'value1 v1.31', 'value2 1.12'}
...
lua box.space[11]:delete('00000002')
lua box.space[11]:delete(4ULL)
---
- 3616443484303536176: {'value1 v1.43', 'value2 1.92'}
...
lua box.space[11]:delete('00000003')
lua box.space[11]:delete(5ULL)
---
...
lua box.space[11]:insert(0ULL, 'value1 v1.0', 'value2 v1.0')
---
- 0: {'value1 v1.0', 'value2 v1.0'}
...
lua box.space[11]:insert(1ULL, 'value1 v1.0', 'value2 v1.0')
---
- 3688501078341464112: {'value1 v1.31', 'value2 1.12'}
- 1: {'value1 v1.0', 'value2 v1.0'}
...
lua box.space[11]:insert(2ULL, 'value1 v1.0', 'value2 v1.0')
---
- 2: {'value1 v1.0', 'value2 v1.0'}
...
lua box.space[11]:insert(3ULL, 'value1 v1.0', 'value2 v1.0')
---
- 3: {'value1 v1.0', 'value2 v1.0'}
...
# delete by valid NUM keys
lua box.space[11]:delete(0)
---
- 0: {'value1 v1.0', 'value2 v1.0'}
...
lua box.space[11]:delete(1)
---
- 1: {'value1 v1.0', 'value2 v1.0'}
...
lua box.space[11]:delete(2)
---
- 2: {'value1 v1.0', 'value2 v1.0'}
...
lua box.space[11]:delete(3)
---
- 3: {'value1 v1.0', 'value2 v1.0'}
...
lua box.space[11]:delete('00000004')
lua box.space[11]:delete(4)
---
...
lua box.space[11]:delete('00000005')
lua box.space[11]:delete(5)
---
...
......
......@@ -107,17 +107,20 @@ print """
print """
# Insert valid fieds
"""
exec admin "lua box.space[11]:insert('00000000', 'value1 v1.0', 'value2 v1.0')"
exec admin "lua box.space[11]:insert('00000001', 'value1 v1.0', 'value2 v1.0')"
exec admin "lua box.space[11]:insert('00000002', 'value1 v1.0', 'value2 v1.0')"
exec admin "lua box.space[11]:insert('00000003', 'value1 v1.0', 'value2 v1.0')"
exec admin "lua box.space[11]:insert(0ULL, 'value1 v1.0', 'value2 v1.0')"
exec admin "lua box.space[11]:insert(1ULL, 'value1 v1.0', 'value2 v1.0')"
exec admin "lua box.space[11]:insert(2ULL, 'value1 v1.0', 'value2 v1.0')"
exec admin "lua box.space[11]:insert(3ULL, 'value1 v1.0', 'value2 v1.0')"
print """
# Insert invalid fields
"""
exec admin "lua box.space[11]:insert(100, 'value1 v1.0', 'value2 v1.0')"
exec admin "lua box.space[11]:insert(101, 'value1 v1.0', 'value2 v1.0')"
exec admin "lua box.space[11]:insert(102, 'value1 v1.0', 'value2 v1.0')"
exec admin "lua box.space[11]:insert(103, 'value1 v1.0', 'value2 v1.0')"
exec admin "lua box.space[11]:insert('invalid key', 'value1 v1.0', 'value2 v1.0')"
print """
#-----------------------------------------------------------------------------#
# 64-bit hash replace fields tests
......@@ -127,15 +130,17 @@ print """
print """
# Replace valid fieds
"""
exec admin "lua box.space[11]:replace('00000003', 'value1 v1.31', 'value2 1.12')"
exec admin "lua box.space[11]:replace('00000001', 'value1 v1.32', 'value2 1.72')"
exec admin "lua box.space[11]:replace('00000002', 'value1 v1.43', 'value2 1.92')"
exec admin "lua box.space[11]:replace(3ULL, 'value1 v1.31', 'value2 1.12')"
exec admin "lua box.space[11]:replace(1ULL, 'value1 v1.32', 'value2 1.72')"
exec admin "lua box.space[11]:replace(2ULL, 'value1 v1.43', 'value2 1.92')"
print """
# Replace invalid fields
"""
exec admin "lua box.space[10]:replace('invalid key', 'value1 v1.0', 'value2 v1.0')"
exec admin "lua box.space[11]:replace(3, 'value1 v1.31', 'value2 1.12')"
exec admin "lua box.space[11]:replace(1, 'value1 v1.32', 'value2 1.72')"
exec admin "lua box.space[11]:replace(2, 'value1 v1.43', 'value2 1.92')"
exec admin "lua box.space[11]:replace('invalid key', 'value1 v1.0', 'value2 v1.0')"
print """
#-----------------------------------------------------------------------------#
......@@ -146,12 +151,22 @@ print """
print """
# select by valid keys
"""
exec admin "lua box.space[11]:select(0, '00000000')"
exec admin "lua box.space[11]:select(0, '00000001')"
exec admin "lua box.space[11]:select(0, '00000002')"
exec admin "lua box.space[11]:select(0, '00000003')"
exec admin "lua box.space[11]:select(0, '00000004')"
exec admin "lua box.space[11]:select(0, '00000005')"
exec admin "lua box.space[11]:select(0, 0ULL)"
exec admin "lua box.space[11]:select(0, 1ULL)"
exec admin "lua box.space[11]:select(0, 2ULL)"
exec admin "lua box.space[11]:select(0, 3ULL)"
exec admin "lua box.space[11]:select(0, 4ULL)"
exec admin "lua box.space[11]:select(0, 5ULL)"
print """
# select by valid NUM keys
"""
exec admin "lua box.space[11]:select(0, 0)"
exec admin "lua box.space[11]:select(0, 1)"
exec admin "lua box.space[11]:select(0, 2)"
exec admin "lua box.space[11]:select(0, 3)"
exec admin "lua box.space[11]:select(0, 4)"
exec admin "lua box.space[11]:select(0, 5)"
print """
# select by invalid keys
......@@ -159,7 +174,6 @@ print """
exec admin "lua box.space[11]:select(0, 'invalid key')"
exec admin "lua box.space[11]:select(0, '00000001', '00000002')"
print """
#-----------------------------------------------------------------------------#
# 64-bit hash delete fields test
......@@ -169,12 +183,27 @@ print """
print """
# delete by valid keys
"""
exec admin "lua box.space[11]:delete('00000000')"
exec admin "lua box.space[11]:delete('00000001')"
exec admin "lua box.space[11]:delete('00000002')"
exec admin "lua box.space[11]:delete('00000003')"
exec admin "lua box.space[11]:delete('00000004')"
exec admin "lua box.space[11]:delete('00000005')"
exec admin "lua box.space[11]:delete(0ULL)"
exec admin "lua box.space[11]:delete(1ULL)"
exec admin "lua box.space[11]:delete(2ULL)"
exec admin "lua box.space[11]:delete(3ULL)"
exec admin "lua box.space[11]:delete(4ULL)"
exec admin "lua box.space[11]:delete(5ULL)"
exec admin "lua box.space[11]:insert(0ULL, 'value1 v1.0', 'value2 v1.0')"
exec admin "lua box.space[11]:insert(1ULL, 'value1 v1.0', 'value2 v1.0')"
exec admin "lua box.space[11]:insert(2ULL, 'value1 v1.0', 'value2 v1.0')"
exec admin "lua box.space[11]:insert(3ULL, 'value1 v1.0', 'value2 v1.0')"
print """
# delete by valid NUM keys
"""
exec admin "lua box.space[11]:delete(0)"
exec admin "lua box.space[11]:delete(1)"
exec admin "lua box.space[11]:delete(2)"
exec admin "lua box.space[11]:delete(3)"
exec admin "lua box.space[11]:delete(4)"
exec admin "lua box.space[11]:delete(5)"
print """
# delete by invalid keys
......
......@@ -768,7 +768,7 @@ error: 'utils.lua:27: Key part count 4 is greater than index part count 2'
...
#-----------------------------------------------------------------------------#
# Iterator: hash multi-part non-unique
# Iterator: hash single-part unique
#-----------------------------------------------------------------------------#
lua iterate(20, 4, 0, 1)
......@@ -840,6 +840,68 @@ lua iterate(20, 4, 0, 1, box.index.GE, 'pid_999')
sorted output
...
#-----------------------------------------------------------------------------#
# Iterator: hash multi-part unique
#-----------------------------------------------------------------------------#
lua iterate(20, 5, 1, 3, box.index.ALL)
---
sorted output
$sid_001$tid_997$
$sid_001$tid_998$
$sid_002$tid_996$
$sid_002$tid_997$
$sid_003$tid_996$
$sid_004$tid_996$
$sid_005$tid_994$
$sid_005$tid_995$
$sid_005$tid_996$
$sid_006$tid_996$
...
lua iterate(20, 5, 1, 3, box.index.EQ)
---
error: 'Invalid key part count in an exact match (expected 2, got 0)'
...
lua iterate(20, 5, 1, 3, box.index.EQ, 'sid_005')
---
error: 'Invalid key part count in an exact match (expected 2, got 1)'
...
lua iterate(20, 5, 1, 3, box.index.GE)
---
sorted output
$sid_001$tid_997$
$sid_001$tid_998$
$sid_002$tid_996$
$sid_002$tid_997$
$sid_003$tid_996$
$sid_004$tid_996$
$sid_005$tid_994$
$sid_005$tid_995$
$sid_005$tid_996$
$sid_006$tid_996$
...
lua iterate(20, 2, 1, 3, box.index.EQ, 'sid_005', 'tid_995')
---
$sid_005$tid_995$
...
lua iterate(20, 2, 1, 3, box.index.EQ, 'sid_005', 'tid_999')
---
...
lua iterate(20, 2, 1, 3, box.index.EQ, 'sid_005', 'tid_995', 'a')
---
error: 'utils.lua:27: Key part count 3 is greater than index part count 2'
...
lua iterate(20, 2, 1, 3, box.index.GE, 'sid_005', 'tid_995')
---
$sid_005$tid_995$
$sid_005$tid_996$
$sid_006$tid_996$
...
lua iterate(20, 2, 1, 3, box.index.GE, 'sid_005', 'tid_999')
---
$sid_006$tid_996$
...
#-----------------------------------------------------------------------------#
# Iterator: various
#-----------------------------------------------------------------------------#
......
......@@ -135,7 +135,7 @@ exec admin "lua iterate(20, 3, 2, 4, box.index.LT, 'tid_996', 'to', 'many', 'key
print """
#-----------------------------------------------------------------------------#
# Iterator: hash multi-part non-unique
# Iterator: hash single-part unique
#-----------------------------------------------------------------------------#
"""
......@@ -148,6 +148,21 @@ exec admin "lua iterate(20, 4, 0, 1, box.index.EQ, 'pid_666')"
exec admin "lua iterate(20, 4, 0, 1, box.index.GE, 'pid_001')"
exec admin "lua iterate(20, 4, 0, 1, box.index.GE, 'pid_999')"
print """
#-----------------------------------------------------------------------------#
# Iterator: hash multi-part unique
#-----------------------------------------------------------------------------#
"""
exec admin "lua iterate(20, 5, 1, 3, box.index.ALL)"
exec admin "lua iterate(20, 5, 1, 3, box.index.EQ)"
exec admin "lua iterate(20, 5, 1, 3, box.index.EQ, 'sid_005')"
exec admin "lua iterate(20, 5, 1, 3, box.index.GE)"
exec admin "lua iterate(20, 2, 1, 3, box.index.EQ, 'sid_005', 'tid_995')"
exec admin "lua iterate(20, 2, 1, 3, box.index.EQ, 'sid_005', 'tid_999')"
exec admin "lua iterate(20, 2, 1, 3, box.index.EQ, 'sid_005', 'tid_995', 'a')"
exec admin "lua iterate(20, 2, 1, 3, box.index.GE, 'sid_005', 'tid_995')"
exec admin "lua iterate(20, 2, 1, 3, box.index.GE, 'sid_005', 'tid_999')"
print """
#-----------------------------------------------------------------------------#
# Iterator: various
......
......@@ -283,6 +283,14 @@ space[20].index[4].unique = 1
space[20].index[4].key_field[0].fieldno = 0
space[20].index[4].key_field[0].type = "STR"
# Hash multi-part unique
space[20].index[5].type = "HASH"
space[20].index[5].unique = 1
space[20].index[5].key_field[0].fieldno = 1
space[20].index[5].key_field[0].type = "STR"
space[20].index[5].key_field[1].fieldno = 2
space[20].index[5].key_field[1].type = "STR"
# hash::replace
space[21].enabled = true
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment