[PATCH 08/13] memtx: allow snapshot iterator to fail
Vladimir Davydov
vdavydov.dev at gmail.com
Sat Aug 10 13:03:35 MSK 2019
Memtx iterators never fail, that's why the snapshot iterator interface
doesn't support failures. However, once we introduce snapshot iterator
support for vinyl, we will need a way to handle errors in the API.
---
src/box/index.h | 3 ++-
src/box/memtx_engine.c | 22 ++++++++++++----------
src/box/memtx_hash.c | 14 +++++++++-----
src/box/memtx_tree.c | 14 +++++++++-----
src/box/sequence.c | 24 ++++++++++++++----------
5 files changed, 46 insertions(+), 31 deletions(-)
diff --git a/src/box/index.h b/src/box/index.h
index 89b5e134..86148023 100644
--- a/src/box/index.h
+++ b/src/box/index.h
@@ -293,7 +293,8 @@ struct snapshot_iterator {
* Returns a pointer to the tuple data and its
* size or NULL if EOF.
*/
- const char *(*next)(struct snapshot_iterator *, uint32_t *size);
+ int (*next)(struct snapshot_iterator *,
+ const char **data, uint32_t *size);
/**
* Destroy the iterator.
*/
diff --git a/src/box/memtx_engine.c b/src/box/memtx_engine.c
index ec667e7a..87806775 100644
--- a/src/box/memtx_engine.c
+++ b/src/box/memtx_engine.c
@@ -575,25 +575,27 @@ checkpoint_f(va_list ap)
ERROR_INJECT_SLEEP(ERRINJ_SNAP_WRITE_DELAY);
struct checkpoint_entry *entry;
rlist_foreach_entry(entry, &ckpt->entries, link) {
+ int rc;
uint32_t size;
const char *data;
struct snapshot_iterator *it = entry->iterator;
- for (data = it->next(it, &size); data != NULL;
- data = it->next(it, &size)) {
+ while ((rc = it->next(it, &data, &size)) == 0 && data != NULL) {
if (checkpoint_write_tuple(&snap, entry->space_id,
- entry->group_id, data, size) != 0) {
- xlog_close(&snap, false);
- return -1;
- }
+ entry->group_id, data, size) != 0)
+ goto fail;
}
+ if (rc != 0)
+ goto fail;
}
- if (xlog_flush(&snap) < 0) {
- xlog_close(&snap, false);
- return -1;
- }
+ if (xlog_flush(&snap) < 0)
+ goto fail;
+
xlog_close(&snap, false);
say_info("done");
return 0;
+fail:
+ xlog_close(&snap, false);
+ return -1;
}
static int
diff --git a/src/box/memtx_hash.c b/src/box/memtx_hash.c
index 2762d973..920f1032 100644
--- a/src/box/memtx_hash.c
+++ b/src/box/memtx_hash.c
@@ -424,8 +424,9 @@ hash_snapshot_iterator_free(struct snapshot_iterator *iterator)
* Virtual method of snapshot iterator.
* @sa index_vtab::create_snapshot_iterator.
*/
-static const char *
-hash_snapshot_iterator_next(struct snapshot_iterator *iterator, uint32_t *size)
+static int
+hash_snapshot_iterator_next(struct snapshot_iterator *iterator,
+ const char **data, uint32_t *size)
{
assert(iterator->free == hash_snapshot_iterator_free);
struct hash_snapshot_iterator *it =
@@ -433,9 +434,12 @@ hash_snapshot_iterator_next(struct snapshot_iterator *iterator, uint32_t *size)
struct light_index_core *hash_table = &it->index->hash_table;
struct tuple **res = light_index_iterator_get_and_next(hash_table,
&it->iterator);
- if (res == NULL)
- return NULL;
- return tuple_data_range(*res, size);
+ if (res == NULL) {
+ *data = NULL;
+ return 0;
+ }
+ *data = tuple_data_range(*res, size);
+ return 0;
}
/**
diff --git a/src/box/memtx_tree.c b/src/box/memtx_tree.c
index 77223a6d..831a2715 100644
--- a/src/box/memtx_tree.c
+++ b/src/box/memtx_tree.c
@@ -1220,8 +1220,9 @@ tree_snapshot_iterator_free(struct snapshot_iterator *iterator)
free(iterator);
}
-static const char *
-tree_snapshot_iterator_next(struct snapshot_iterator *iterator, uint32_t *size)
+static int
+tree_snapshot_iterator_next(struct snapshot_iterator *iterator,
+ const char **data, uint32_t *size)
{
assert(iterator->free == tree_snapshot_iterator_free);
struct tree_snapshot_iterator *it =
@@ -1229,10 +1230,13 @@ tree_snapshot_iterator_next(struct snapshot_iterator *iterator, uint32_t *size)
struct memtx_tree *tree = &it->index->tree;
struct memtx_tree_data *res = memtx_tree_iterator_get_elem(tree,
&it->tree_iterator);
- if (res == NULL)
- return NULL;
+ if (res == NULL) {
+ *data = NULL;
+ return 0;
+ }
memtx_tree_iterator_next(tree, &it->tree_iterator);
- return tuple_data_range(res->tuple, size);
+ *data = tuple_data_range(res->tuple, size);
+ return 0;
}
/**
diff --git a/src/box/sequence.c b/src/box/sequence.c
index 1aacc505..5ebfa274 100644
--- a/src/box/sequence.c
+++ b/src/box/sequence.c
@@ -311,27 +311,31 @@ struct sequence_data_iterator {
#define SEQUENCE_TUPLE_BUF_SIZE (mp_sizeof_array(2) + \
2 * mp_sizeof_uint(UINT64_MAX))
-static const char *
-sequence_data_iterator_next(struct snapshot_iterator *base, uint32_t *size)
+static int
+sequence_data_iterator_next(struct snapshot_iterator *base,
+ const char **data, uint32_t *size)
{
struct sequence_data_iterator *iter =
(struct sequence_data_iterator *)base;
- struct sequence_data *data =
+ struct sequence_data *sd =
light_sequence_iterator_get_and_next(&sequence_data_index,
&iter->iter);
- if (data == NULL)
- return NULL;
+ if (sd == NULL) {
+ *data = NULL;
+ return 0;
+ }
char *buf_end = iter->tuple;
buf_end = mp_encode_array(buf_end, 2);
- buf_end = mp_encode_uint(buf_end, data->id);
- buf_end = (data->value >= 0 ?
- mp_encode_uint(buf_end, data->value) :
- mp_encode_int(buf_end, data->value));
+ buf_end = mp_encode_uint(buf_end, sd->id);
+ buf_end = (sd->value >= 0 ?
+ mp_encode_uint(buf_end, sd->value) :
+ mp_encode_int(buf_end, sd->value));
assert(buf_end <= iter->tuple + SEQUENCE_TUPLE_BUF_SIZE);
+ *data = iter->tuple;
*size = buf_end - iter->tuple;
- return iter->tuple;
+ return 0;
}
static void
--
2.20.1
More information about the Tarantool-patches
mailing list