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

Merge branch 'tuple-compare-v2'

parents 9ec48ecb da1a7a22
No related branches found
No related tags found
No related merge requests found
......@@ -307,17 +307,7 @@ HashIndex::max() const
return NULL;
}
struct tuple *
HashIndex::findByTuple(struct tuple *tuple) const
{
assert(key_def->is_unique);
if (tuple->field_count < key_def->max_fieldno)
tnt_raise(IllegalParams, "tuple must have all indexed fields");
/* Hash index currently is always single-part. */
const char *field = tuple_field_old(tuple, key_def->parts[0].fieldno);
return findByKey(field, 1);
}
/* }}} */
......
......@@ -48,7 +48,6 @@ class HashIndex: public Index {
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 *findByTuple(struct tuple *tuple) const;
virtual struct tuple *replace(struct tuple *old_tuple,
struct tuple *new_tuple,
enum dup_replace_mode mode) = 0;
......
......@@ -145,7 +145,7 @@ Index::factory(enum index_type type, struct key_def *key_def, struct space *spac
case HASH:
return HashIndex::factory(key_def, space);
case TREE:
return TreeIndex::factory(key_def, space);
return new TreeIndex(key_def, space);
case BITSET:
return new BitsetIndex(key_def, space);
default:
......@@ -168,4 +168,11 @@ Index::~Index()
m_position->free(m_position);
}
struct tuple *
Index::findByTuple(struct tuple *tuple) const
{
(void) tuple;
tnt_raise(ClientError, ER_UNSUPPORTED, "Index", "findByTuple()");
return NULL;
}
/* }}} */
......@@ -220,7 +220,7 @@ class Index: public Object {
virtual struct tuple *max() const = 0;
virtual struct tuple *random(u32 rnd) const = 0;
virtual struct tuple *findByKey(const char *key, u32 part_count) const = 0;
virtual struct tuple *findByTuple(struct tuple *tuple) const = 0;
virtual struct tuple *findByTuple(struct tuple *tuple) const;
virtual struct tuple *replace(struct tuple *old_tuple,
struct tuple *new_tuple,
enum dup_replace_mode mode) = 0;
......
This diff is collapsed.
......@@ -38,12 +38,10 @@
*/
SPTREE_DEF(index, realloc);
typedef int (*tree_cmp_t)(const void *, const void *, void *);
class TreeIndex: public Index {
public:
static TreeIndex *
factory(struct key_def *key_def, struct space *space);
TreeIndex(struct key_def *key_def, struct space *space);
virtual ~TreeIndex();
virtual void beginBuild();
virtual void buildNext(struct tuple *tuple);
......@@ -54,7 +52,6 @@ class TreeIndex: public Index {
virtual struct tuple *max() const;
virtual struct tuple *random(u32 rnd) const;
virtual struct tuple *findByKey(const char *key, u32 part_count) const;
virtual struct tuple *findByTuple(struct tuple *tuple) const;
virtual struct tuple *replace(struct tuple *old_tuple,
struct tuple *new_tuple,
enum dup_replace_mode mode);
......@@ -65,20 +62,7 @@ class TreeIndex: public Index {
const char *key, u32 part_count) const;
// protected:
/* Needed by iterators */
virtual size_t node_size() const = 0;
virtual tree_cmp_t node_cmp() const = 0;
virtual tree_cmp_t dup_node_cmp() const = 0;
virtual tree_cmp_t key_node_cmp() const= 0;
virtual void fold(void *node, struct tuple *tuple) const = 0;
virtual struct tuple *unfold(const void *node) const = 0;
sptree_index tree;
protected:
TreeIndex(struct key_def *key_def, struct space *space);
virtual ~TreeIndex();
};
#endif /* TARANTOOL_BOX_TREE_INDEX_H_INCLUDED */
......@@ -31,6 +31,7 @@
#include <salloc.h>
#include "tbuf.h"
#include "index.h"
#include "tuple_update.h"
#include <exception.h>
#include <palloc.h>
......@@ -239,3 +240,112 @@ tuple_new(uint32_t field_count, const char **data, const char *end)
memcpy(new_tuple->data, end - tuple_len, tuple_len);
return new_tuple;
}
static inline int
tuple_compare_field(const char *field_a, uint32_t size_a,
const char *field_b, uint32_t size_b,
enum field_data_type type)
{
/*
* field_a is always a tuple field.
* field_b can be either a tuple field or a key part.
* All tuple fields were validated before by space_validate_tuple().
* All key parts were validated before by key_validate().
*/
switch (type) {
case NUM:
{
assert(size_a == sizeof(uint32_t));
assert(size_b == sizeof(uint32_t));
uint32_t a = *(uint32_t *) field_a;
uint32_t b = *(uint32_t *) field_b;
return a < b ? -1 : (a > b);
}
case NUM64:
{
assert(size_a == sizeof(uint64_t));
uint64_t a = *(uint64_t *) field_a;
uint64_t b;
/* Allow search in NUM64 indexes using NUM keys. */
if (size_b == sizeof(uint32_t)) {
b = *(uint32_t *) field_b;
} else {
assert(size_b == sizeof(uint64_t));
b = *(uint64_t *) field_b;
}
return a < b ? -1 : (a > b);
}
case STRING:
{
int cmp = memcmp(field_a, field_b, MIN(size_a, size_b));
if (cmp != 0)
return cmp;
if (size_a > size_b) {
return 1;
} else if (size_a < size_b){
return -1;
} else {
return 0;
}
}
default:
assert(false);
}
}
int
tuple_compare(const struct tuple *tuple_a, const struct tuple *tuple_b,
const struct key_def *key_def)
{
for (uint32_t part = 0; part < key_def->part_count; part++) {
uint32_t field_no = key_def->parts[part].fieldno;
uint32_t size_a, size_b;
const char *field_a = tuple_field(tuple_a, field_no, &size_a);
const char *field_b = tuple_field(tuple_b, field_no, &size_b);
int r = tuple_compare_field(field_a, size_a, field_b, size_b,
key_def->parts[part].type);
if (r != 0) {
return r;
}
}
return 0;
}
int
tuple_compare_dup(const struct tuple *tuple_a, const struct tuple *tuple_b,
const struct key_def *key_def)
{
int r = tuple_compare(tuple_a, tuple_b, key_def);
if (r != 0) {
return r;
}
return tuple_a < tuple_b ? -1 : (tuple_a > tuple_b);
}
int
tuple_compare_with_key(const struct tuple *tuple_a, const char *key,
uint32_t part_count, const struct key_def *key_def)
{
part_count = MIN(part_count, key_def->part_count);
for (uint32_t part = 0; part < part_count; part++) {
uint32_t field_no = key_def->parts[part].fieldno;
uint32_t size_a;
const char *field_a = tuple_field(tuple_a, field_no, &size_a);
uint32_t key_size = load_varint32(&key);
int r = tuple_compare_field(field_a, size_a, key, key_size,
key_def->parts[part].type);
if (r != 0) {
return r;
}
key += key_size;
}
return 0;
}
......@@ -32,6 +32,7 @@
#include <pickle.h>
struct tbuf;
struct key_def;
/**
* An atom of Tarantool/Box storage. Consists of a list of fields.
......@@ -188,5 +189,46 @@ tuple_range_size(const char **begin, const char *end, uint32_t count)
void tuple_free(struct tuple *tuple);
/**
* @brief Compare two tuples using field by field using key definition
* @param tuple_a tuple
* @param tuple_b 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)
*/
int
tuple_compare(const struct tuple *tuple_a, const struct tuple *tuple_b,
const struct key_def *key_def);
/**
* @brief Compare two tuples field by field for duplicate using key definition
* @param tuple_a tuple
* @param tuple_b tuple
* @param key_def key definition
* @retval 0 if key_fields(tuple_a) == key_fields(tuple_b) and
* tuple_a == tuple_b - tuple_a is the same object as tuple_b
* @retval <0 if key_fields(tuple_a) <= key_fields(tuple_b)
* @retval >0 if key_fields(tuple_a > key_fields(tuple_b)
*/
int
tuple_compare_dup(const struct tuple *tuple_a, const struct tuple *tuple_b,
const struct key_def *key_def);
/**
* @brief Compare a tuple with a key field by field using key definition
* @param tuple_a tuple
* @param key BER-encoded key
* @param part_count number of parts in \a key
* @param key_def key definition
* @retval 0 if key_fields(tuple_a) == parts(key)
* @retval <0 if key_fields(tuple_a) < parts(key)
* @retval >0 if key_fields(tuple_a) > parts(key)
*/
int
tuple_compare_with_key(const struct tuple *tuple_a, const char *key,
uint32_t part_count, const struct key_def *key_def);
#endif /* TARANTOOL_BOX_TUPLE_H_INCLUDED */
......@@ -113,6 +113,50 @@ lua num == tonumber64('18446744073709551615')
---
- true
...
lua box.delete(8, 18446744073709551615ULL)
---
- 18446744073709551615: {'magic'}
...
lua box.insert('8', 125ULL, 'magic')
---
- 125: {'magic'}
...
lua tu = box.select('8', '0', 125)
---
...
lua tu2 = box.select('8', '0', 125LL)
---
...
lua num = box.unpack('l', tu[0])
---
...
lua num2 = box.unpack('l', tu2[0])
---
...
lua print(num)
---
125
...
lua print(num2)
---
125
...
lua type(num) == 'cdata'
---
- true
...
lua type(num2) == 'cdata'
---
- true
...
lua num == tonumber64('125')
---
- true
...
lua num2 == tonumber64('125')
---
- true
...
lua box.space[8]:truncate()
---
...
......
......@@ -62,6 +62,18 @@ exec admin "lua type(num) == 'cdata'"
exec admin "lua num == tonumber64('18446744073709551615')"
exec admin "lua num = box.unpack('l', tu[0])"
exec admin "lua num == tonumber64('18446744073709551615')"
exec admin "lua box.delete(8, 18446744073709551615ULL)"
exec admin "lua box.insert('8', 125ULL, 'magic')"
exec admin "lua tu = box.select('8', '0', 125)"
exec admin "lua tu2 = box.select('8', '0', 125LL)"
exec admin "lua num = box.unpack('l', tu[0])"
exec admin "lua num2 = box.unpack('l', tu2[0])"
exec admin "lua print(num)"
exec admin "lua print(num2)"
exec admin "lua type(num) == 'cdata'"
exec admin "lua type(num2) == 'cdata'"
exec admin "lua num == tonumber64('125')"
exec admin "lua num2 == tonumber64('125')"
exec admin "lua box.space[8]:truncate()"
#
......
......@@ -211,10 +211,6 @@ Found 3 tuples:
['21234567', 'part1', 'part2_a']
select * from t5 where k1='part2'
No match
delete from t5 where k0=1
An error occurred: ER_ILLEGAL_PARAMS, 'Illegal parameters, key is not u64'
delete from t5 where k0=2
An error occurred: ER_ILLEGAL_PARAMS, 'Illegal parameters, key is not u64'
delete from t5 where k0='01234567'
Delete OK, 1 row affected
delete from t5 where k0='11234567'
......
......@@ -102,9 +102,6 @@ exec sql "delete from t1 where k0='key2'"
exec sql "delete from t1 where k0='key3'"
exec sql "select * from t5 where k1='part1'"
exec sql "select * from t5 where k1='part2'"
# check incomplete keys
exec sql "delete from t5 where k0=1"
exec sql "delete from t5 where k0=2"
# cleanup
exec sql "delete from t5 where k0='01234567'"
exec sql "delete from t5 where k0='11234567'"
......
......@@ -68,6 +68,44 @@ delete from t6 where k0 = 8
Delete OK, 1 row affected
delete from t6 where k0 = 9
Delete OK, 1 row affected
lua box.insert(6, 6, 6ULL, 400ULL, 'John', 'Smoker', 'Hits', 'A Pipe', 'foo', 2006 )
---
- 6: {6, 400, 1852337994, 'Smoker', 1937008968, 'A Pipe', 'foo', 2006}
...
lua box.insert(6, 7, 7ULL, 400ULL, 'John', 'Smoker', 'Hits', 'A Bong', 'foo', 2007 )
---
- 7: {7, 400, 1852337994, 'Smoker', 1937008968, 'A Bong', 'foo', 2007}
...
lua box.insert(6, 8, 8ULL, 400ULL, 'John', 'Smoker', 'Rolls', 'A Joint', 'foo', 2008 )
---
- 8: {8, 400, 1852337994, 'Smoker', 'Rolls', 'A Joint', 'foo', 2008}
...
lua box.insert(6, 9, 9ULL, 400ULL, 'John', 'Smoker', 'Rolls', 'A Blunt', 'foo', 2009 )
---
- 9: {9, 400, 1852337994, 'Smoker', 'Rolls', 'A Blunt', 'foo', 2009}
...
lua box.select(6, 1, 6ULL)
---
- 6: {6, 400, 1852337994, 'Smoker', 1937008968, 'A Pipe', 'foo', 2006}
...
lua box.select(6, 1, 6)
---
- 6: {6, 400, 1852337994, 'Smoker', 1937008968, 'A Pipe', 'foo', 2006}
...
lua box.select(6, 2, 400ULL)
---
- 6: {6, 400, 1852337994, 'Smoker', 1937008968, 'A Pipe', 'foo', 2006}
- 7: {7, 400, 1852337994, 'Smoker', 1937008968, 'A Bong', 'foo', 2007}
- 8: {8, 400, 1852337994, 'Smoker', 'Rolls', 'A Joint', 'foo', 2008}
- 9: {9, 400, 1852337994, 'Smoker', 'Rolls', 'A Blunt', 'foo', 2009}
...
lua box.select(6, 2, 400)
---
- 6: {6, 400, 1852337994, 'Smoker', 1937008968, 'A Pipe', 'foo', 2006}
- 7: {7, 400, 1852337994, 'Smoker', 1937008968, 'A Bong', 'foo', 2007}
- 8: {8, 400, 1852337994, 'Smoker', 'Rolls', 'A Joint', 'foo', 2008}
- 9: {9, 400, 1852337994, 'Smoker', 'Rolls', 'A Blunt', 'foo', 2009}
...
lua for k,v in box.space[6]:pairs() do print(v) end
---
0: {3472328296227680304, 3472329395739308080, 'Joe', 'Sixpack', 'Drinks', 'Amstel', 'bar', 2000}
......@@ -76,4 +114,8 @@ lua for k,v in box.space[6]:pairs() do print(v) end
3: {3688501078341464112, 3472331594762563632, 'Joe', 'Sixpack', 'Drinks', 'Corona Extra', 'bar', 2003}
4: {3760558672379392048, 3472331594762563632, 'Joe', 'Sixpack', 'Drinks', 'Stella Artois', 'bar', 2004}
5: {3832616266417319984, 3472331594762563632, 'Joe', 'Sixpack', 'Drinks', 'Miller Genuine Draft', 'bar', 2005}
6: {6, 400, 1852337994, 'Smoker', 1937008968, 'A Pipe', 'foo', 2006}
7: {7, 400, 1852337994, 'Smoker', 1937008968, 'A Bong', 'foo', 2007}
8: {8, 400, 1852337994, 'Smoker', 'Rolls', 'A Joint', 'foo', 2008}
9: {9, 400, 1852337994, 'Smoker', 'Rolls', 'A Blunt', 'foo', 2009}
...
......@@ -27,5 +27,14 @@ exec sql "delete from t6 where k0 = 7"
exec sql "delete from t6 where k0 = 8"
exec sql "delete from t6 where k0 = 9"
exec admin "lua for k,v in box.space[6]:pairs() do print(v) end"
exec admin "lua box.insert(6, 6, 6ULL, 400ULL, 'John', 'Smoker', 'Hits', 'A Pipe', 'foo', 2006 )"
exec admin "lua box.insert(6, 7, 7ULL, 400ULL, 'John', 'Smoker', 'Hits', 'A Bong', 'foo', 2007 )"
exec admin "lua box.insert(6, 8, 8ULL, 400ULL, 'John', 'Smoker', 'Rolls', 'A Joint', 'foo', 2008 )"
exec admin "lua box.insert(6, 9, 9ULL, 400ULL, 'John', 'Smoker', 'Rolls', 'A Blunt', 'foo', 2009 )"
exec admin "lua box.select(6, 1, 6ULL)"
exec admin "lua box.select(6, 1, 6)"
exec admin "lua box.select(6, 2, 400ULL)"
exec admin "lua box.select(6, 2, 400)"
exec admin "lua for k,v in box.space[6]:pairs() do print(v) end"
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