diff --git a/src/box/vinyl.c b/src/box/vinyl.c index f498410c967e640d99ed493a8ebe60b1b89484fa..478dd815926c73dd7ec52fe8655549ec3e98ab2c 100644 --- a/src/box/vinyl.c +++ b/src/box/vinyl.c @@ -1374,7 +1374,7 @@ vy_get(struct vy_lsm *lsm, struct vy_tx *tx, int rc; struct tuple *tuple; - if (tuple_field_count(key) >= lsm->cmp_def->part_count) { + if (vy_stmt_is_full_key(key, lsm->cmp_def)) { /* * Use point lookup for a full key. */ diff --git a/src/box/vy_cache.c b/src/box/vy_cache.c index ead56e95898c9d8087ce9711247dcdc3cbb50ecc..320ea04d88bfa84ee435d1ee8a21854ddd295680 100644 --- a/src/box/vy_cache.c +++ b/src/box/vy_cache.c @@ -270,13 +270,15 @@ vy_cache_add(struct vy_cache *cache, struct tuple *stmt, * Regardless of order, the statement is the first in * sequence of statements that is equal to the key. */ - boundary_level = tuple_field_count(key); + boundary_level = vy_stmt_key_part_count(key, + cache->cmp_def); } } else { assert(prev_stmt != NULL); if (order == ITER_EQ || order == ITER_REQ) { /* that is the last statement that is equal to key */ - boundary_level = tuple_field_count(key); + boundary_level = vy_stmt_key_part_count(key, + cache->cmp_def); } else { /* that is the last statement */ boundary_level = 0; @@ -527,7 +529,8 @@ static inline bool vy_cache_iterator_is_stop(struct vy_cache_iterator *itr, struct vy_cache_entry *entry) { - uint8_t key_level = tuple_field_count(itr->key); + uint8_t key_level = vy_stmt_key_part_count(itr->key, + itr->cache->cmp_def); /* select{} is actually an EQ iterator with part_count == 0 */ bool iter_is_eq = itr->iterator_type == ITER_EQ || key_level == 0; if (iterator_direction(itr->iterator_type) > 0) { @@ -556,7 +559,8 @@ static inline bool vy_cache_iterator_is_end_stop(struct vy_cache_iterator *itr, struct vy_cache_entry *last_entry) { - uint8_t key_level = tuple_field_count(itr->key); + uint8_t key_level = vy_stmt_key_part_count(itr->key, + itr->cache->cmp_def); /* select{} is actually an EQ iterator with part_count == 0 */ bool iter_is_eq = itr->iterator_type == ITER_EQ || key_level == 0; if (iterator_direction(itr->iterator_type) > 0) { @@ -644,7 +648,7 @@ vy_cache_iterator_seek(struct vy_cache_iterator *itr, *entry = NULL; itr->cache->stat.lookup++; - if (tuple_field_count(key) > 0) { + if (!vy_stmt_is_empty_key(key)) { bool exact; itr->curr_pos = iterator_type == ITER_EQ || iterator_type == ITER_GE || diff --git a/src/box/vy_mem.c b/src/box/vy_mem.c index 9c4448eb4fd119bb8617c7451ed13d620b7abc1f..6bc3859cfde47bbdd7a39983acfafde376e0995f 100644 --- a/src/box/vy_mem.c +++ b/src/box/vy_mem.c @@ -401,7 +401,7 @@ vy_mem_iterator_seek(struct vy_mem_iterator *itr, const struct tuple *last_key) tree_key.stmt = key; /* (lsn == INT64_MAX - 1) means that lsn is ignored in comparison */ tree_key.lsn = INT64_MAX - 1; - if (tuple_field_count(key) > 0) { + if (!vy_stmt_is_empty_key(key)) { if (iterator_type == ITER_LE || iterator_type == ITER_GT) { itr->curr_pos = vy_mem_tree_upper_bound(&itr->mem->tree, diff --git a/src/box/vy_point_lookup.c b/src/box/vy_point_lookup.c index 6b8bbd231e241afe0409fa215d4ae38693b6732f..18d5622b7e16f504e73045a0ad6214d06dfe90eb 100644 --- a/src/box/vy_point_lookup.c +++ b/src/box/vy_point_lookup.c @@ -197,8 +197,7 @@ vy_point_lookup(struct vy_lsm *lsm, struct vy_tx *tx, struct tuple *key, struct tuple **ret) { /* All key parts must be set for a point lookup. */ - assert(vy_stmt_type(key) != IPROTO_SELECT || - tuple_field_count(key) >= lsm->cmp_def->part_count); + assert(vy_stmt_is_full_key(key, lsm->cmp_def)); *ret = NULL; double start_time = ev_monotonic_now(loop()); @@ -301,7 +300,7 @@ int vy_point_lookup_mem(struct vy_lsm *lsm, const struct vy_read_view **rv, struct tuple *key, struct tuple **ret) { - assert(tuple_field_count(key) >= lsm->cmp_def->part_count); + assert(vy_stmt_is_full_key(key, lsm->cmp_def)); int rc; struct vy_history history; diff --git a/src/box/vy_range.c b/src/box/vy_range.c index 3491784a469c32abf4efeb667e6fa9f2c2be3200..2a2d2d006cb54d89bff7b72b5cdfe1aa2a8032ed 100644 --- a/src/box/vy_range.c +++ b/src/box/vy_range.c @@ -81,8 +81,7 @@ vy_range_tree_find_by_key(vy_range_tree_t *tree, enum iterator_type iterator_type, const struct tuple *key) { - uint32_t key_field_count = tuple_field_count(key); - if (key_field_count == 0) { + if (vy_stmt_is_empty_key(key)) { switch (iterator_type) { case ITER_LT: case ITER_LE: @@ -125,7 +124,7 @@ vy_range_tree_find_by_key(vy_range_tree_t *tree, range = vy_range_tree_psearch(tree, key); /* switch to previous for case (4) */ if (range != NULL && range->begin != NULL && - key_field_count < range->cmp_def->part_count && + !vy_stmt_is_full_key(key, range->cmp_def) && vy_stmt_compare_with_key(key, range->begin, range->cmp_def) == 0) range = vy_range_tree_prev(tree, range); diff --git a/src/box/vy_read_iterator.c b/src/box/vy_read_iterator.c index 2984174ac86471d71b070a7b7877072587fba0b1..740ee940b77c16dc31f30b32cddec4bd89e748fe 100644 --- a/src/box/vy_read_iterator.c +++ b/src/box/vy_read_iterator.c @@ -208,7 +208,7 @@ vy_read_iterator_is_exact_match(struct vy_read_iterator *itr, return itr->last_stmt == NULL && stmt != NULL && (type == ITER_EQ || type == ITER_REQ || type == ITER_GE || type == ITER_LE) && - tuple_field_count(key) >= cmp_def->part_count && + vy_stmt_is_full_key(key, cmp_def) && vy_stmt_compare(stmt, key, cmp_def) == 0; } @@ -445,7 +445,7 @@ vy_read_iterator_advance(struct vy_read_iterator *itr) { if (itr->last_stmt != NULL && (itr->iterator_type == ITER_EQ || itr->iterator_type == ITER_REQ) && - tuple_field_count(itr->key) >= itr->lsm->cmp_def->part_count) { + vy_stmt_is_full_key(itr->key, itr->lsm->cmp_def)) { /* * There may be one statement at max satisfying * EQ with a full key. @@ -678,7 +678,7 @@ vy_read_iterator_open(struct vy_read_iterator *itr, struct vy_lsm *lsm, itr->key = key; itr->read_view = rv; - if (tuple_field_count(key) == 0) { + if (vy_stmt_is_empty_key(key)) { /* * Strictly speaking, a GT/LT iterator should return * nothing if the key is empty, because every key is diff --git a/src/box/vy_read_set.c b/src/box/vy_read_set.c index 0f3fab6147ff1e51e98ae2cb6d8b6fc02f2a781f..b95d2e4e2bc1ef1925b65424ac5f50161161bb3a 100644 --- a/src/box/vy_read_set.c +++ b/src/box/vy_read_set.c @@ -53,10 +53,8 @@ vy_read_interval_cmpl(const struct vy_read_interval *a, return -1; if (!a->left_belongs && b->left_belongs) return 1; - uint32_t a_parts = tuple_field_count(a->left); - uint32_t b_parts = tuple_field_count(b->left); - a_parts = MIN(a_parts, cmp_def->part_count); - b_parts = MIN(b_parts, cmp_def->part_count); + uint32_t a_parts = vy_stmt_key_part_count(a->left, cmp_def); + uint32_t b_parts = vy_stmt_key_part_count(b->left, cmp_def); if (a->left_belongs) return a_parts < b_parts ? -1 : a_parts > b_parts; else @@ -76,10 +74,8 @@ vy_read_interval_cmpr(const struct vy_read_interval *a, return 1; if (!a->right_belongs && b->right_belongs) return -1; - uint32_t a_parts = tuple_field_count(a->right); - uint32_t b_parts = tuple_field_count(b->right); - a_parts = MIN(a_parts, cmp_def->part_count); - b_parts = MIN(b_parts, cmp_def->part_count); + uint32_t a_parts = vy_stmt_key_part_count(a->right, cmp_def); + uint32_t b_parts = vy_stmt_key_part_count(b->right, cmp_def); if (a->right_belongs) return a_parts > b_parts ? -1 : a_parts < b_parts; else @@ -102,10 +98,8 @@ vy_read_interval_should_merge(const struct vy_read_interval *l, return true; if (!l->right_belongs && !r->left_belongs) return false; - uint32_t l_parts = tuple_field_count(l->right); - uint32_t r_parts = tuple_field_count(r->left); - l_parts = MIN(l_parts, cmp_def->part_count); - r_parts = MIN(r_parts, cmp_def->part_count); + uint32_t l_parts = vy_stmt_key_part_count(l->right, cmp_def); + uint32_t r_parts = vy_stmt_key_part_count(r->left, cmp_def); if (l->right_belongs) return l_parts <= r_parts; else diff --git a/src/box/vy_run.c b/src/box/vy_run.c index 38ca686f23307c29cae0c65e951ed3064ea051ae..ff39c133daecd0ad8158fc99f24839a5483b9a0d 100644 --- a/src/box/vy_run.c +++ b/src/box/vy_run.c @@ -1273,7 +1273,7 @@ vy_run_iterator_do_seek(struct vy_run_iterator *itr, struct vy_run_iterator_pos end_pos = {run->info.page_count, 0}; bool equal_found = false; int rc; - if (tuple_field_count(key) > 0) { + if (!vy_stmt_is_empty_key(key)) { rc = vy_run_iterator_search(itr, iterator_type, key, &itr->curr_pos, &equal_found); if (rc != 0 || itr->search_ended) diff --git a/src/box/vy_stmt.h b/src/box/vy_stmt.h index 3efad12cc054de33e0a2f9a952a33f115eaeeb64..1dfbe1f7b71c6d12bb234ab298ee83d82e0ce96f 100644 --- a/src/box/vy_stmt.h +++ b/src/box/vy_stmt.h @@ -219,6 +219,44 @@ vy_stmt_set_n_upserts(struct tuple *stmt, uint8_t n) *((uint8_t *)stmt - 1) = n; } +/** + * Return the number of key parts defined in the given vinyl + * statement. + * + * If the statement represents a tuple, we assume that it has + * all key parts defined. + */ +static inline uint32_t +vy_stmt_key_part_count(const struct tuple *stmt, struct key_def *key_def) +{ + if (vy_stmt_type(stmt) == IPROTO_SELECT) { + uint32_t part_count = tuple_field_count(stmt); + assert(part_count <= key_def->part_count); + return part_count; + } + return key_def->part_count; +} + +/** + * Return true if the given vinyl statement contains all + * key parts, i.e. can be used for an exact match lookup. + */ +static inline bool +vy_stmt_is_full_key(const struct tuple *stmt, struct key_def *key_def) +{ + return vy_stmt_key_part_count(stmt, key_def) == key_def->part_count; +} + +/** + * Return true if the given vinyl statement stores an empty + * (match all) key. + */ +static inline bool +vy_stmt_is_empty_key(const struct tuple *stmt) +{ + return tuple_field_count(stmt) == 0; +} + /** * Duplicate the statememnt. * diff --git a/src/box/vy_tx.c b/src/box/vy_tx.c index b1fcfabb300daff60579667cc7356539564f1de0..ac02ee4d4af075cd732540676873de1397772d8a 100644 --- a/src/box/vy_tx.c +++ b/src/box/vy_tx.c @@ -943,7 +943,7 @@ vy_tx_track(struct vy_tx *tx, struct vy_lsm *lsm, int vy_tx_track_point(struct vy_tx *tx, struct vy_lsm *lsm, struct tuple *stmt) { - assert(tuple_field_count(stmt) >= lsm->cmp_def->part_count); + assert(vy_stmt_is_full_key(stmt, lsm->cmp_def)); if (vy_tx_is_in_read_view(tx)) { /* No point in tracking reads. */ @@ -1102,7 +1102,7 @@ vy_txw_iterator_seek(struct vy_txw_iterator *itr, struct vy_lsm *lsm = itr->lsm; struct write_set_key k = { lsm, key }; struct txv *txv; - if (tuple_field_count(key) > 0) { + if (!vy_stmt_is_empty_key(key)) { if (iterator_type == ITER_EQ) txv = write_set_search(&itr->tx->write_set, &k); else if (iterator_type == ITER_GE || iterator_type == ITER_GT)