From: Vladimir Davydov <vdavydov.dev@gmail.com>
To: tarantool-patches@freelists.org
Subject: [PATCH 3/7] Make tuple_extract_key support multikey indexes
Date: Wed, 8 May 2019 20:22:35 +0300 [thread overview]
Message-ID: <e175c12d7d86ecc3f22b7897ae8c5890dc6a3658.1557334828.git.vdavydov.dev@gmail.com> (raw)
In-Reply-To: <cover.1557334828.git.vdavydov.dev@gmail.com>
In-Reply-To: <cover.1557334828.git.vdavydov.dev@gmail.com>
Add multikey_idx argument to tuple_extract_key and forward it to
tuple_field_by_part in the method implementation. For unikey indexes
pass -1. We need this to support multikey indexes in Vinyl.
We could of course introduce a separate set of methods for multikey
indexes (something like tuple_extract_key_multikey), but that would
look cumbersome and hardly result in any performance benefits, because
passing -1 to a relatively cold function, such as key extractor, isn't
a big deal. Besides, passing multikey_idx unconditionally is consistent
with tuple_compare.
---
src/box/index.cc | 2 +-
src/box/key_def.h | 18 +++++++++++----
src/box/lua/key_def.c | 2 +-
src/box/memtx_space.c | 2 +-
src/box/request.c | 5 ++--
src/box/space.c | 2 +-
src/box/sql.c | 10 ++++----
| 54 ++++++++++++++++++++++++++++++--------------
src/box/vinyl.c | 12 +++++-----
src/box/vy_run.c | 6 ++---
src/box/vy_stmt.c | 17 +++++++-------
src/box/vy_stmt.h | 6 ++---
12 files changed, 83 insertions(+), 53 deletions(-)
diff --git a/src/box/index.cc b/src/box/index.cc
index 2817d076..39b0ee46 100644
--- a/src/box/index.cc
+++ b/src/box/index.cc
@@ -156,7 +156,7 @@ box_tuple_extract_key(box_tuple_t *tuple, uint32_t space_id, uint32_t index_id,
struct index *index = index_find(space, index_id);
if (index == NULL)
return NULL;
- return tuple_extract_key(tuple, index->def->key_def, key_size);
+ return tuple_extract_key(tuple, index->def->key_def, -1, key_size);
}
static inline int
diff --git a/src/box/key_def.h b/src/box/key_def.h
index 5f65f501..8b94b3b6 100644
--- a/src/box/key_def.h
+++ b/src/box/key_def.h
@@ -145,11 +145,13 @@ typedef int (*tuple_compare_t)(struct tuple *tuple_a,
/** @copydoc tuple_extract_key() */
typedef char *(*tuple_extract_key_t)(struct tuple *tuple,
struct key_def *key_def,
+ int multikey_idx,
uint32_t *key_size);
/** @copydoc tuple_extract_key_raw() */
typedef char *(*tuple_extract_key_raw_t)(const char *data,
const char *data_end,
struct key_def *key_def,
+ int multikey_idx,
uint32_t *key_size);
/** @copydoc tuple_hash() */
typedef uint32_t (*tuple_hash_t)(struct tuple *tuple,
@@ -531,10 +533,12 @@ key_part_cmp(const struct key_part *parts1, uint32_t part_count1,
* Check if a key of @a tuple contains NULL.
* @param tuple Tuple to check.
* @param def Key def to check by.
+ * @param multikey_idx Multikey index hint.
* @retval Does the key contain NULL or not?
*/
bool
-tuple_key_contains_null(struct tuple *tuple, struct key_def *def);
+tuple_key_contains_null(struct tuple *tuple, struct key_def *def,
+ int multikey_idx);
/**
* Check that tuple fields match with given key definition
@@ -554,6 +558,7 @@ tuple_validate_key_parts(struct key_def *key_def, struct tuple *tuple);
* has O(n) complexity, where n is the number of key parts.
* @param tuple - tuple from which need to extract key
* @param key_def - definition of key that need to extract
+ * @param multikey_idx - multikey index hint
* @param key_size - here will be size of extracted key
*
* @retval not NULL Success
@@ -561,9 +566,10 @@ tuple_validate_key_parts(struct key_def *key_def, struct tuple *tuple);
*/
static inline char *
tuple_extract_key(struct tuple *tuple, struct key_def *key_def,
- uint32_t *key_size)
+ int multikey_idx, uint32_t *key_size)
{
- return key_def->tuple_extract_key(tuple, key_def, key_size);
+ return key_def->tuple_extract_key(tuple, key_def, multikey_idx,
+ key_size);
}
/**
@@ -574,6 +580,7 @@ tuple_extract_key(struct tuple *tuple, struct key_def *key_def,
* @param data - msgpuck data from which need to extract key
* @param data_end - pointer at the end of data
* @param key_def - definition of key that need to extract
+ * @param multikey_idx - multikey index hint
* @param key_size - here will be size of extracted key
*
* @retval not NULL Success
@@ -581,10 +588,11 @@ tuple_extract_key(struct tuple *tuple, struct key_def *key_def,
*/
static inline char *
tuple_extract_key_raw(const char *data, const char *data_end,
- struct key_def *key_def, uint32_t *key_size)
+ struct key_def *key_def, int multikey_idx,
+ uint32_t *key_size)
{
return key_def->tuple_extract_key_raw(data, data_end, key_def,
- key_size);
+ multikey_idx, key_size);
}
/**
diff --git a/src/box/lua/key_def.c b/src/box/lua/key_def.c
index 72bb05c4..28d40478 100644
--- a/src/box/lua/key_def.c
+++ b/src/box/lua/key_def.c
@@ -265,7 +265,7 @@ lbox_key_def_extract_key(struct lua_State *L)
struct region *region = &fiber()->gc;
size_t region_svp = region_used(region);
uint32_t key_size;
- char *key = tuple_extract_key(tuple, key_def, &key_size);
+ char *key = tuple_extract_key(tuple, key_def, -1, &key_size);
tuple_unref(tuple);
if (key == NULL)
return luaT_error(L);
diff --git a/src/box/memtx_space.c b/src/box/memtx_space.c
index 4d5e7991..265bf923 100644
--- a/src/box/memtx_space.c
+++ b/src/box/memtx_space.c
@@ -445,7 +445,7 @@ memtx_space_execute_upsert(struct space *space, struct txn *txn,
/* Extract the primary key from tuple. */
const char *key = tuple_extract_key_raw(request->tuple,
request->tuple_end,
- index->def->key_def, NULL);
+ index->def->key_def, -1, NULL);
if (key == NULL)
return -1;
/* Cut array header */
diff --git a/src/box/request.c b/src/box/request.c
index 9c684af7..8b84260a 100644
--- a/src/box/request.c
+++ b/src/box/request.c
@@ -92,7 +92,7 @@ request_create_from_tuple(struct request *request, struct space *space,
uint32_t size, key_size;
const char *data = tuple_data_range(old_tuple, &size);
request->key = tuple_extract_key_raw(data, data + size,
- space->index[0]->def->key_def, &key_size);
+ space->index[0]->def->key_def, -1, &key_size);
if (request->key == NULL)
return -1;
request->key_end = request->key + key_size;
@@ -125,7 +125,8 @@ request_rebind_to_primary_key(struct request *request, struct space *space,
struct index *pk = space_index(space, 0);
assert(pk != NULL);
uint32_t key_len;
- char *key = tuple_extract_key(found_tuple, pk->def->key_def, &key_len);
+ char *key = tuple_extract_key(found_tuple, pk->def->key_def, -1,
+ &key_len);
assert(key != NULL);
request->key = key;
request->key_end = key + key_len;
diff --git a/src/box/space.c b/src/box/space.c
index edfc5d60..9a266604 100644
--- a/src/box/space.c
+++ b/src/box/space.c
@@ -320,7 +320,7 @@ space_before_replace(struct space *space, struct txn *txn,
break;
index = pk;
key = tuple_extract_key_raw(request->tuple, request->tuple_end,
- index->def->key_def, NULL);
+ index->def->key_def, -1, NULL);
if (key == NULL)
return -1;
part_count = mp_decode_array(&key);
diff --git a/src/box/sql.c b/src/box/sql.c
index 7a20d86e..c3f404ee 100644
--- a/src/box/sql.c
+++ b/src/box/sql.c
@@ -480,7 +480,7 @@ int tarantoolsqlEphemeralDelete(BtCursor *pCur)
char *key;
uint32_t key_size;
key = tuple_extract_key(pCur->last_tuple,
- pCur->iter->index->def->key_def,
+ pCur->iter->index->def->key_def, -1,
&key_size);
if (key == NULL)
return SQL_TARANTOOL_DELETE_FAIL;
@@ -506,7 +506,7 @@ int tarantoolsqlDelete(BtCursor *pCur, u8 flags)
int rc;
key = tuple_extract_key(pCur->last_tuple,
- pCur->iter->index->def->key_def,
+ pCur->iter->index->def->key_def, -1,
&key_size);
if (key == NULL)
return SQL_TARANTOOL_DELETE_FAIL;
@@ -561,7 +561,7 @@ int tarantoolsqlEphemeralClearTable(BtCursor *pCur)
uint32_t key_size;
while (iterator_next(it, &tuple) == 0 && tuple != NULL) {
- key = tuple_extract_key(tuple, it->index->def->key_def,
+ key = tuple_extract_key(tuple, it->index->def->key_def, -1,
&key_size);
if (space_ephemeral_delete(pCur->space, key) != 0) {
iterator_delete(it);
@@ -594,7 +594,7 @@ int tarantoolsqlClearTable(struct space *space, uint32_t *tuple_count)
if (iter == NULL)
return SQL_TARANTOOL_ITERATOR_FAIL;
while (iterator_next(iter, &tuple) == 0 && tuple != NULL) {
- request.key = tuple_extract_key(tuple, pk->def->key_def,
+ request.key = tuple_extract_key(tuple, pk->def->key_def, -1,
&key_size);
request.key_end = request.key + key_size;
rc = box_process_rw(&request, space, &unused);
@@ -801,7 +801,7 @@ out:
#ifndef NDEBUG
/* Sanity check. */
original_size = region_used(&fiber()->gc);
- key = tuple_extract_key(tuple, key_def, &key_size);
+ key = tuple_extract_key(tuple, key_def, -1, &key_size);
if (key != NULL) {
int new_rc = sqlVdbeRecordCompareMsgpack(key, unpacked);
region_truncate(&fiber()->gc, original_size);
--git a/src/box/tuple_extract_key.cc b/src/box/tuple_extract_key.cc
index 7868378d..15e43aae 100644
--- a/src/box/tuple_extract_key.cc
+++ b/src/box/tuple_extract_key.cc
@@ -37,8 +37,10 @@ key_def_contains_sequential_parts(const struct key_def *def)
template <bool has_optional_parts>
static char *
tuple_extract_key_sequential_raw(const char *data, const char *data_end,
- struct key_def *key_def, uint32_t *key_size)
+ struct key_def *key_def, int multikey_idx,
+ uint32_t *key_size)
{
+ (void)multikey_idx;
assert(!has_optional_parts || key_def->is_nullable);
assert(key_def_is_sequential(key_def));
assert(has_optional_parts == key_def->has_optional_parts);
@@ -87,7 +89,7 @@ tuple_extract_key_sequential_raw(const char *data, const char *data_end,
template <bool has_optional_parts>
static inline char *
tuple_extract_key_sequential(struct tuple *tuple, struct key_def *key_def,
- uint32_t *key_size)
+ int multikey_idx, uint32_t *key_size)
{
assert(key_def_is_sequential(key_def));
assert(!has_optional_parts || key_def->is_nullable);
@@ -97,6 +99,7 @@ tuple_extract_key_sequential(struct tuple *tuple, struct key_def *key_def,
return tuple_extract_key_sequential_raw<has_optional_parts>(data,
data_end,
key_def,
+ multikey_idx,
key_size);
}
@@ -105,17 +108,18 @@ tuple_extract_key_sequential(struct tuple *tuple, struct key_def *key_def,
* @copydoc tuple_extract_key()
*/
template <bool contains_sequential_parts, bool has_optional_parts,
- bool has_json_paths>
+ bool has_json_paths, bool is_multikey>
static char *
tuple_extract_key_slowpath(struct tuple *tuple, struct key_def *key_def,
- uint32_t *key_size)
+ int multikey_idx, uint32_t *key_size)
{
assert(has_json_paths == key_def->has_json_paths);
assert(!has_optional_parts || key_def->is_nullable);
assert(has_optional_parts == key_def->has_optional_parts);
assert(contains_sequential_parts ==
key_def_contains_sequential_parts(key_def));
- assert(!key_def_is_multikey(key_def));
+ assert(is_multikey == key_def_is_multikey(key_def));
+ assert(!key_def_is_multikey(key_def) || multikey_idx >= 0);
assert(mp_sizeof_nil() == 1);
const char *data = tuple_data(tuple);
uint32_t part_count = key_def->part_count;
@@ -130,9 +134,13 @@ tuple_extract_key_slowpath(struct tuple *tuple, struct key_def *key_def,
if (!has_json_paths) {
field = tuple_field_raw(format, data, field_map,
key_def->parts[i].fieldno);
- } else {
+ } else if (!is_multikey) {
field = tuple_field_raw_by_part(format, data, field_map,
&key_def->parts[i], -1);
+ } else {
+ field = tuple_field_raw_by_part(format, data, field_map,
+ &key_def->parts[i],
+ multikey_idx);
}
if (has_optional_parts && field == NULL) {
bsize += mp_sizeof_nil();
@@ -177,9 +185,13 @@ tuple_extract_key_slowpath(struct tuple *tuple, struct key_def *key_def,
if (!has_json_paths) {
field = tuple_field_raw(format, data, field_map,
key_def->parts[i].fieldno);
- } else {
+ } else if (!is_multikey) {
field = tuple_field_raw_by_part(format, data, field_map,
&key_def->parts[i], -1);
+ } else {
+ field = tuple_field_raw_by_part(format, data, field_map,
+ &key_def->parts[i],
+ multikey_idx);
}
if (has_optional_parts && field == NULL) {
key_buf = mp_encode_nil(key_buf);
@@ -230,12 +242,13 @@ tuple_extract_key_slowpath(struct tuple *tuple, struct key_def *key_def,
template <bool has_optional_parts, bool has_json_paths>
static char *
tuple_extract_key_slowpath_raw(const char *data, const char *data_end,
- struct key_def *key_def, uint32_t *key_size)
+ struct key_def *key_def, int multikey_idx,
+ uint32_t *key_size)
{
assert(has_json_paths == key_def->has_json_paths);
assert(!has_optional_parts || key_def->is_nullable);
assert(has_optional_parts == key_def->has_optional_parts);
- assert(!key_def_is_multikey(key_def));
+ assert(!key_def_is_multikey(key_def) || multikey_idx >= 0);
assert(mp_sizeof_nil() == 1);
/* allocate buffer with maximal possible size */
char *key = (char *) region_alloc(&fiber()->gc, data_end - data);
@@ -311,8 +324,8 @@ tuple_extract_key_slowpath_raw(const char *data, const char *data_end,
const char *src = field;
const char *src_end = field_end;
if (has_json_paths && part->path != NULL) {
- if (tuple_go_to_path(&src, part->path,
- part->path_len, -1) != 0) {
+ if (tuple_go_to_path(&src, part->path, part->path_len,
+ multikey_idx) != 0) {
/*
* The path must be correct as
* it has already been validated
@@ -361,7 +374,7 @@ key_def_set_extract_func_plain(struct key_def *def)
} else {
def->tuple_extract_key = tuple_extract_key_slowpath
<contains_sequential_parts,
- has_optional_parts, false>;
+ has_optional_parts, false, false>;
def->tuple_extract_key_raw = tuple_extract_key_slowpath_raw
<has_optional_parts, false>;
}
@@ -372,9 +385,15 @@ static void
key_def_set_extract_func_json(struct key_def *def)
{
assert(def->has_json_paths);
- def->tuple_extract_key = tuple_extract_key_slowpath
+ if (key_def_is_multikey(def)) {
+ def->tuple_extract_key = tuple_extract_key_slowpath
<contains_sequential_parts,
- has_optional_parts, true>;
+ has_optional_parts, true, true>;
+ } else {
+ def->tuple_extract_key = tuple_extract_key_slowpath
+ <contains_sequential_parts,
+ has_optional_parts, true, false>;
+ }
def->tuple_extract_key_raw = tuple_extract_key_slowpath_raw
<has_optional_parts, true>;
}
@@ -411,16 +430,17 @@ key_def_set_extract_func(struct key_def *key_def)
}
bool
-tuple_key_contains_null(struct tuple *tuple, struct key_def *def)
+tuple_key_contains_null(struct tuple *tuple, struct key_def *def,
+ int multikey_idx)
{
- assert(!key_def_is_multikey(def));
struct tuple_format *format = tuple_format(tuple);
const char *data = tuple_data(tuple);
const uint32_t *field_map = tuple_field_map(tuple);
for (struct key_part *part = def->parts, *end = part + def->part_count;
part < end; ++part) {
const char *field = tuple_field_raw_by_part(format, data,
- field_map, part, -1);
+ field_map, part,
+ multikey_idx);
if (field == NULL || mp_typeof(*field) == MP_NIL)
return true;
}
diff --git a/src/box/vinyl.c b/src/box/vinyl.c
index 6ffbecd9..eddbdbed 100644
--- a/src/box/vinyl.c
+++ b/src/box/vinyl.c
@@ -1344,7 +1344,7 @@ vy_get_by_secondary_tuple(struct vy_lsm *lsm, struct vy_tx *tx,
struct vy_entry key;
if (vy_stmt_is_key(entry.stmt)) {
key.stmt = vy_stmt_extract_key(entry.stmt, lsm->pk_in_cmp_def,
- lsm->env->key_format);
+ lsm->env->key_format, -1);
if (key.stmt == NULL)
return -1;
} else {
@@ -1601,10 +1601,10 @@ vy_check_is_unique_secondary(struct vy_tx *tx, const struct vy_read_view **rv,
if (!lsm->check_is_unique)
return 0;
if (lsm->key_def->is_nullable &&
- tuple_key_contains_null(stmt, lsm->key_def))
+ tuple_key_contains_null(stmt, lsm->key_def, -1))
return 0;
struct tuple *key = vy_stmt_extract_key(stmt, lsm->key_def,
- lsm->env->key_format);
+ lsm->env->key_format, -1);
if (key == NULL)
return -1;
struct tuple *found;
@@ -2149,7 +2149,7 @@ vy_upsert(struct vy_env *env, struct vy_tx *tx, struct txn_stmt *stmt,
*/
/* Find the old tuple using the primary key. */
struct tuple *key = vy_stmt_extract_key_raw(tuple, tuple_end,
- pk->key_def, pk->env->key_format);
+ pk->key_def, pk->env->key_format, -1);
if (key == NULL)
return -1;
int rc = vy_get(pk, tx, vy_tx_read_view(tx), key, &stmt->old_tuple);
@@ -4064,7 +4064,7 @@ vy_build_on_replace(struct trigger *trigger, void *event)
/* Forward the statement to the new LSM tree. */
if (stmt->old_tuple != NULL) {
struct tuple *delete = vy_stmt_extract_key(stmt->old_tuple,
- lsm->cmp_def, lsm->env->key_format);
+ lsm->cmp_def, lsm->env->key_format, -1);
if (delete == NULL)
goto err;
vy_stmt_set_type(delete, IPROTO_DELETE);
@@ -4219,7 +4219,7 @@ vy_build_recover_stmt(struct vy_lsm *lsm, struct vy_lsm *pk,
struct tuple *old_tuple = old.stmt;
if (old_tuple != NULL) {
delete = vy_stmt_extract_key(old_tuple, lsm->cmp_def,
- lsm->env->key_format);
+ lsm->env->key_format, -1);
if (delete == NULL)
return -1;
vy_stmt_set_type(delete, IPROTO_DELETE);
diff --git a/src/box/vy_run.c b/src/box/vy_run.c
index b15a96e9..409c3d96 100644
--- a/src/box/vy_run.c
+++ b/src/box/vy_run.c
@@ -2167,7 +2167,7 @@ vy_run_writer_start_page(struct vy_run_writer *writer,
const char *key = vy_stmt_is_key(first_entry.stmt) ?
tuple_data(first_entry.stmt) :
tuple_extract_key(first_entry.stmt,
- writer->cmp_def, NULL);
+ writer->cmp_def, -1, NULL);
if (key == NULL)
return -1;
if (run->info.page_count == 0) {
@@ -2321,7 +2321,7 @@ vy_run_writer_commit(struct vy_run_writer *writer)
const char *key = vy_stmt_is_key(writer->last.stmt) ?
tuple_data(writer->last.stmt) :
tuple_extract_key(writer->last.stmt,
- writer->cmp_def, NULL);
+ writer->cmp_def, -1, NULL);
if (key == NULL)
goto out;
@@ -2431,7 +2431,7 @@ vy_run_rebuild_index(struct vy_run *run, const char *dir,
goto close_err;
}
key = vy_stmt_is_key(tuple) ? tuple_data(tuple) :
- tuple_extract_key(tuple, cmp_def, NULL);
+ tuple_extract_key(tuple, cmp_def, -1, NULL);
if (prev_tuple != NULL)
tuple_unref(prev_tuple);
prev_tuple = tuple;
diff --git a/src/box/vy_stmt.c b/src/box/vy_stmt.c
index c8088d34..847b6196 100644
--- a/src/box/vy_stmt.c
+++ b/src/box/vy_stmt.c
@@ -489,11 +489,12 @@ out:
struct tuple *
vy_stmt_extract_key(struct tuple *stmt, struct key_def *key_def,
- struct tuple_format *format)
+ struct tuple_format *format, int multikey_idx)
{
struct region *region = &fiber()->gc;
size_t region_svp = region_used(region);
- const char *key_raw = tuple_extract_key(stmt, key_def, NULL);
+ const char *key_raw = tuple_extract_key(stmt, key_def,
+ multikey_idx, NULL);
if (key_raw == NULL)
return NULL;
uint32_t part_count = mp_decode_array(&key_raw);
@@ -506,13 +507,13 @@ vy_stmt_extract_key(struct tuple *stmt, struct key_def *key_def,
struct tuple *
vy_stmt_extract_key_raw(const char *data, const char *data_end,
- struct key_def *key_def,
- struct tuple_format *format)
+ struct key_def *key_def, struct tuple_format *format,
+ int multikey_idx)
{
struct region *region = &fiber()->gc;
size_t region_svp = region_used(region);
- const char *key_raw = tuple_extract_key_raw(data, data_end,
- key_def, NULL);
+ const char *key_raw = tuple_extract_key_raw(data, data_end, key_def,
+ multikey_idx, NULL);
if (key_raw == NULL)
return NULL;
uint32_t part_count = mp_decode_array(&key_raw);
@@ -622,7 +623,7 @@ vy_stmt_encode_primary(struct tuple *value, struct key_def *key_def,
case IPROTO_DELETE:
extracted = vy_stmt_is_key(value) ?
tuple_data_range(value, &size) :
- tuple_extract_key(value, key_def, &size);
+ tuple_extract_key(value, key_def, -1, &size);
if (extracted == NULL)
return -1;
request.key = extracted;
@@ -666,7 +667,7 @@ vy_stmt_encode_secondary(struct tuple *value, struct key_def *cmp_def,
uint32_t size;
const char *extracted = vy_stmt_is_key(value) ?
tuple_data_range(value, &size) :
- tuple_extract_key(value, cmp_def, &size);
+ tuple_extract_key(value, cmp_def, -1, &size);
if (extracted == NULL)
return -1;
if (type == IPROTO_REPLACE || type == IPROTO_INSERT) {
diff --git a/src/box/vy_stmt.h b/src/box/vy_stmt.h
index 49fa1602..929e537a 100644
--- a/src/box/vy_stmt.h
+++ b/src/box/vy_stmt.h
@@ -606,7 +606,7 @@ vy_key_from_msgpack(struct tuple_format *format, const char *key)
*/
struct tuple *
vy_stmt_extract_key(struct tuple *stmt, struct key_def *key_def,
- struct tuple_format *format);
+ struct tuple_format *format, int multikey_idx);
/**
* Extract the key from msgpack by the given key definition
@@ -615,8 +615,8 @@ vy_stmt_extract_key(struct tuple *stmt, struct key_def *key_def,
*/
struct tuple *
vy_stmt_extract_key_raw(const char *data, const char *data_end,
- struct key_def *key_def,
- struct tuple_format *format);
+ struct key_def *key_def, struct tuple_format *format,
+ int multikey_idx);
/**
* Add a statement hash to a bloom filter builder.
--
2.11.0
next prev parent reply other threads:[~2019-05-08 17:22 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-05-08 17:22 [PATCH 0/7] Support multikey indexes in Vinyl Vladimir Davydov
2019-05-08 17:22 ` [PATCH 1/7] Make tuple comparison hints mandatory Vladimir Davydov
2019-05-09 5:58 ` [tarantool-patches] " Konstantin Osipov
2019-05-08 17:22 ` [PATCH 2/7] Get rid of tuple_field_by_part_multikey Vladimir Davydov
2019-05-08 17:22 ` Vladimir Davydov [this message]
2019-05-08 17:22 ` [PATCH 4/7] Make tuple_bloom support multikey indexes Vladimir Davydov
2019-05-08 17:22 ` [PATCH 5/7] vinyl: use field_map_builder for constructing stmt field map Vladimir Davydov
2019-05-08 17:22 ` [PATCH 6/7] vinyl: use multikey hints while writing runs Vladimir Davydov
2019-05-08 17:22 ` [PATCH 7/7] vinyl: implement multikey index support Vladimir Davydov
2019-05-13 16:34 ` [PATCH] Use MULTIKEY_NONE instead of -1 Vladimir Davydov
2019-05-13 19:26 ` [PATCH 0/7] Support multikey indexes in Vinyl Vladimir Davydov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=e175c12d7d86ecc3f22b7897ae8c5890dc6a3658.1557334828.git.vdavydov.dev@gmail.com \
--to=vdavydov.dev@gmail.com \
--cc=tarantool-patches@freelists.org \
--subject='Re: [PATCH 3/7] Make tuple_extract_key support multikey indexes' \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox