[tarantool-patches] [PATCH 3/4] sql: remove struct ta_cursor and refactor BtCursor

Nikita Pettik korablev at tarantool.org
Mon Mar 19 21:10:39 MSK 2018


ta_cursor cursor served as a wrapper around Tarantool specific members
which help to iterate through space. As far as now only Tarantool spaces
exist, there is no need in separate cursor. Thus, all such members are
transfered directly to BtCursor. Also, all useless field from BtCursor
are removed.

Part of #3122
---
 src/box/sql.c        | 275 +++++++++++++++++----------------------------------
 src/box/sql/cursor.c |  14 +--
 src/box/sql/cursor.h |  13 +--
 src/box/sql/vdbe.c   |  11 +--
 4 files changed, 101 insertions(+), 212 deletions(-)

diff --git a/src/box/sql.c b/src/box/sql.c
index 4f8b39810..4db253ff4 100644
--- a/src/box/sql.c
+++ b/src/box/sql.c
@@ -152,22 +152,8 @@ sql_get()
  * are accurately positioned, hence both 0 and 1 are fine.
  */
 
-/*
- * Tarantool iterator API was apparently designed by space aliens.
- * This wrapper is necessary for interfacing with the SQLite btree code.
- */
-struct ta_cursor {
-	size_t             size;
-	box_iterator_t    *iter;
-	struct tuple      *tuple_last;
-	enum iterator_type type;
-	/* Used only by ephemeral spaces, for ordinary space == NULL. */
-	struct space      *ephem_space;
-	char               key[1];
-};
-
-static struct ta_cursor *
-cursor_create(struct ta_cursor *c, size_t key_size);
+void
+key_alloc(BtCursor *c, size_t key_size);
 
 static int
 cursor_seek(BtCursor *pCur, int *pRes);
@@ -217,17 +203,10 @@ int tarantoolSqlite3CloseCursor(BtCursor *pCur)
 	assert(pCur->curFlags & BTCF_TaCursor ||
 	       pCur->curFlags & BTCF_TEphemCursor);
 
-	struct ta_cursor *c = pCur->pTaCursor;
-
-	pCur->pTaCursor = NULL;
-
-	if (c) {
-		if (c->iter)
-			box_iterator_free(c->iter);
-		if (c->tuple_last)
-			box_tuple_unref(c->tuple_last);
-		free(c);
-	}
+	if (pCur->iter)
+		box_iterator_free(pCur->iter);
+	if (pCur->last_tuple)
+		box_tuple_unref(pCur->last_tuple);
 	return SQLITE_OK;
 }
 
@@ -235,14 +214,10 @@ const void *tarantoolSqlite3PayloadFetch(BtCursor *pCur, u32 *pAmt)
 {
 	assert(pCur->curFlags & BTCF_TaCursor ||
 	       pCur->curFlags & BTCF_TEphemCursor);
+	assert(pCur->last_tuple != NULL);
 
-	struct ta_cursor *c = pCur->pTaCursor;
-
-	assert(c);
-	assert(c->tuple_last);
-
-	*pAmt = box_tuple_bsize(c->tuple_last);
-	return tuple_data(c->tuple_last);
+	*pAmt = box_tuple_bsize(pCur->last_tuple);
+	return tuple_data(pCur->last_tuple);
 }
 
 const void *
@@ -250,16 +225,14 @@ tarantoolSqlite3TupleColumnFast(BtCursor *pCur, u32 fieldno, u32 *field_size)
 {
 	assert(pCur->curFlags & BTCF_TaCursor ||
 	       pCur->curFlags & BTCF_TEphemCursor);
+	assert(pCur->last_tuple != NULL);
 
-	struct ta_cursor *c = pCur->pTaCursor;
-	assert(c != NULL);
-	assert(c->tuple_last != NULL);
-	struct tuple_format *format = tuple_format(c->tuple_last);
+	struct tuple_format *format = tuple_format(pCur->last_tuple);
 	assert(format->exact_field_count == 0
 	       || fieldno < format->exact_field_count);
 	if (format->fields[fieldno].offset_slot == TUPLE_OFFSET_SLOT_NIL)
 		return NULL;
-	const char *field = tuple_field(c->tuple_last, fieldno);
+	const char *field = tuple_field(pCur->last_tuple, fieldno);
 	const char *end = field;
 	mp_next(&end);
 	*field_size = end - field;
@@ -272,30 +245,26 @@ tarantoolSqlite3TupleColumnFast(BtCursor *pCur, u32 fieldno, u32 *field_size)
  */
 int tarantoolSqlite3First(BtCursor *pCur, int *pRes)
 {
-	struct ta_cursor *c = pCur->pTaCursor;
-	c = cursor_create(c, sizeof(nil_key));
-	if (!c) {
+	key_alloc(pCur, sizeof(nil_key));
+	if (pCur->key == NULL) {
 		*pRes = 1;
 		return SQLITE_NOMEM;
 	}
-	c->key[0] = nil_key[0];
-	c->type = ITER_GE;
-	pCur->pTaCursor = c;
+	pCur->key[0] = nil_key[0];
+	pCur->iter_type = ITER_GE;
 	return cursor_seek(pCur, pRes);
 }
 
 /* Set cursor to the last tuple in given space. */
 int tarantoolSqlite3Last(BtCursor *pCur, int *pRes)
 {
-	struct ta_cursor *c = pCur->pTaCursor;
-	c = cursor_create(c, sizeof(nil_key));
-	if (!c) {
+	key_alloc(pCur, sizeof(nil_key));
+	if (pCur->key == NULL) {
 		*pRes = 1;
 		return SQLITE_NOMEM;
 	}
-	c->key[0] = nil_key[0];
-	c->type = ITER_LE;
-	pCur->pTaCursor = c;
+	pCur->key[0] = nil_key[0];
+	pCur->iter_type = ITER_LE;
 	return cursor_seek(pCur, pRes);
 }
 
@@ -312,9 +281,7 @@ int tarantoolSqlite3Next(BtCursor *pCur, int *pRes)
 		*pRes = 1;
 		return SQLITE_OK;
 	}
-	assert(pCur->pTaCursor);
-	assert(iterator_direction(
-		((struct ta_cursor *)pCur->pTaCursor)->type) > 0);
+	assert(iterator_direction(pCur->iter_type) > 0);
 	return cursor_advance(pCur, pRes);
 }
 
@@ -329,9 +296,7 @@ int tarantoolSqlite3Previous(BtCursor *pCur, int *pRes)
 		*pRes = 1;
 		return SQLITE_OK;
 	}
-	assert(pCur->pTaCursor);
-	assert(iterator_direction(
-		((struct ta_cursor *)pCur->pTaCursor)->type) < 0);
+	assert(iterator_direction(pCur->iter_type) < 0);
 	return cursor_advance(pCur, pRes);
 }
 
@@ -340,12 +305,12 @@ int tarantoolSqlite3MovetoUnpacked(BtCursor *pCur, UnpackedRecord *pIdxKey,
 {
 	int rc, res_success;
 	size_t ks;
-	struct ta_cursor *taCur = pCur->pTaCursor;
 
-	ks = sqlite3VdbeMsgpackRecordLen(pIdxKey->aMem,
-					 pIdxKey->nField);
-	taCur = cursor_create(taCur, ks);
-	sqlite3VdbeMsgpackRecordPut((u8 *)taCur->key, pIdxKey->aMem,
+	ks = sqlite3VdbeMsgpackRecordLen(pIdxKey->aMem, pIdxKey->nField);
+	key_alloc(pCur, ks);
+	if (pCur->key == NULL)
+		return SQLITE_NOMEM;
+	sqlite3VdbeMsgpackRecordPut((u8 *)pCur->key, pIdxKey->aMem,
 				    pIdxKey->nField);
 
 	switch (pIdxKey->opcode) {
@@ -355,36 +320,34 @@ int tarantoolSqlite3MovetoUnpacked(BtCursor *pCur, UnpackedRecord *pIdxKey,
 	case 255:
 	/* Restore saved state. Just re-seek cursor.
 	   TODO: replace w/ named constant.  */
-		taCur->type = ((struct ta_cursor *)pCur->pTaCursor)->type;
 		res_success = 0;
 		break;
 	case OP_SeekLT:
-		taCur->type = ITER_LT;
+		pCur->iter_type = ITER_LT;
 		res_success = -1; /* item<key */
 		break;
 	case OP_SeekLE:
-		taCur->type = (pCur->hints & BTREE_SEEK_EQ) ?
-			      ITER_REQ : ITER_LE;
+		pCur->iter_type = (pCur->hints & BTREE_SEEK_EQ) ?
+				  ITER_REQ : ITER_LE;
 		res_success = 0; /* item==key */
 		break;
 	case OP_SeekGE:
-		taCur->type = (pCur->hints & BTREE_SEEK_EQ) ?
-			      ITER_EQ : ITER_GE;
+		pCur->iter_type = (pCur->hints & BTREE_SEEK_EQ) ?
+				  ITER_EQ : ITER_GE;
 		res_success = 0; /* item==key */
 		break;
 	case OP_SeekGT:
-		taCur->type = ITER_GT;
+		pCur->iter_type = ITER_GT;
 		res_success = 1; /* item>key */
 		break;
 	case OP_NoConflict:
 	case OP_NotFound:
 	case OP_Found:
 	case OP_IdxDelete:
-		taCur->type = ITER_EQ;
+		pCur->iter_type = ITER_EQ;
 		res_success = 0;
 		break;
 	}
-	pCur->pTaCursor = taCur;
 	rc = cursor_seek(pCur, pRes);
 	if (*pRes == 0) {
 		*pRes = res_success;
@@ -416,11 +379,7 @@ int tarantoolSqlite3EphemeralCount(struct BtCursor *pCur, i64 *pnEntry)
 {
 	assert(pCur->curFlags & BTCF_TEphemCursor);
 
-	struct ta_cursor *c = pCur->pTaCursor;
-	assert(c);
-	assert(c->ephem_space);
-
-	struct index *primary_index = *c->ephem_space->index;
+	struct index *primary_index = space_index(pCur->space, 0 /* PK */);
 	*pnEntry = index_size(primary_index);
 	return SQLITE_OK;
 }
@@ -486,14 +445,12 @@ int tarantoolSqlite3EphemeralCreate(BtCursor *pCur, uint32_t field_count,
 		diag_log();
 		return SQL_TARANTOOL_ERROR;
 	}
-	struct ta_cursor *c = NULL;
-	c = cursor_create(c, field_count /* key size */);
-	if (!c) {
+	key_alloc(pCur, field_count /* key size */);
+	if (pCur->key == NULL) {
 		space_delete(ephemer_new_space);
 		return SQLITE_NOMEM;
 	}
-	c->ephem_space = ephemer_new_space;
-	pCur->pTaCursor = c;
+	pCur->space = ephemer_new_space;
 
 	int unused;
 	return tarantoolSqlite3First(pCur, &unused);
@@ -513,14 +470,10 @@ int tarantoolSqlite3EphemeralInsert(BtCursor *pCur)
 {
 	assert(pCur);
 	assert(pCur->curFlags & BTCF_TEphemCursor);
-	struct ta_cursor *c = pCur->pTaCursor;
-	assert(c);
-	assert(c->ephem_space);
-	mp_tuple_assert(pCur->pKey, pCur->pKey + pCur->nKey);
-
-	struct space *space = c->ephem_space;
-	if (space_ephemeral_replace(space, pCur->pKey,
-				    pCur->pKey + pCur->nKey) != 0) {
+	mp_tuple_assert(pCur->key, pCur->key + pCur->nKey);
+
+	if (space_ephemeral_replace(pCur->space, pCur->key,
+				    pCur->key + pCur->nKey) != 0) {
 		diag_log();
 		return SQL_TARANTOOL_INSERT_FAIL;
 	}
@@ -532,11 +485,7 @@ int tarantoolSqlite3EphemeralDrop(BtCursor *pCur)
 {
 	assert(pCur);
 	assert(pCur->curFlags & BTCF_TEphemCursor);
-
-	struct ta_cursor *c = pCur->pTaCursor;
-	assert(c->ephem_space);
-	space_delete_ephemeral(c->ephem_space);
-
+	space_delete_ephemeral(pCur->space);
 	return SQLITE_OK;
 }
 
@@ -549,12 +498,12 @@ static int insertOrReplace(BtCursor *pCur, int operationType)
 	int space_id = SQLITE_PAGENO_TO_SPACEID(pCur->pgnoRoot);
 	int rc;
 	if (operationType == TARANTOOL_INDEX_INSERT) {
-		rc = box_insert(space_id, pCur->pKey,
-				(const char *)pCur->pKey + pCur->nKey,
+		rc = box_insert(space_id, pCur->key,
+				(const char *)pCur->key + pCur->nKey,
 				NULL /* result */);
 	} else {
-		rc = box_replace(space_id, pCur->pKey,
-				 (const char *)pCur->pKey + pCur->nKey,
+		rc = box_replace(space_id, pCur->key,
+				 (const char *)pCur->key + pCur->nKey,
 				 NULL /* result */);
 	}
 
@@ -582,23 +531,18 @@ int tarantoolSqlite3Replace(BtCursor *pCur)
 int tarantoolSqlite3EphemeralDelete(BtCursor *pCur)
 {
 	assert(pCur->curFlags & BTCF_TEphemCursor);
-	assert(pCur->pTaCursor);
-	struct ta_cursor *c = pCur->pTaCursor;
-	struct space *ephem_space = c->ephem_space;
-	assert(ephem_space);
+	assert(pCur->iter != NULL);
+	assert(pCur->last_tuple != NULL);
 
 	char *key;
 	uint32_t key_size;
-	assert(c->iter);
-	assert(c->tuple_last);
-
-	key = tuple_extract_key(c->tuple_last,
-				box_iterator_key_def(c->iter),
+	key = tuple_extract_key(pCur->last_tuple,
+				box_iterator_key_def(pCur->iter),
 				&key_size);
 	if (key == NULL)
 		return SQL_TARANTOOL_DELETE_FAIL;
 
-	int rc = space_ephemeral_delete(ephem_space, key);
+	int rc = space_ephemeral_delete(pCur->space, key);
 	if (rc != 0) {
 		diag_log();
 		return SQL_TARANTOOL_DELETE_FAIL;
@@ -611,21 +555,18 @@ int tarantoolSqlite3Delete(BtCursor *pCur, u8 flags)
 	(void)flags;
 
 	assert(pCur->curFlags & BTCF_TaCursor);
+	assert(pCur->iter != NULL);
+	assert(pCur->last_tuple != NULL);
 
-	struct ta_cursor *c = pCur->pTaCursor;
 	uint32_t space_id, index_id;
 	char *key;
 	uint32_t key_size;
 	int rc;
 
-	assert(c);
-	assert(c->iter);
-	assert(c->tuple_last);
-
 	space_id = SQLITE_PAGENO_TO_SPACEID(pCur->pgnoRoot);
 	index_id = SQLITE_PAGENO_TO_INDEXID(pCur->pgnoRoot);
-	key = tuple_extract_key(c->tuple_last,
-				box_iterator_key_def(c->iter),
+	key = tuple_extract_key(pCur->last_tuple,
+				box_iterator_key_def(pCur->iter),
 				&key_size);
 	if (key == NULL)
 		return SQL_TARANTOOL_DELETE_FAIL;
@@ -648,11 +589,8 @@ int tarantoolSqlite3EphemeralClearTable(BtCursor *pCur)
 {
 	assert(pCur);
 	assert(pCur->curFlags & BTCF_TEphemCursor);
-	struct ta_cursor *c = pCur->pTaCursor;
-	assert(c->ephem_space);
 
-	struct space *ephem_space = c->ephem_space;
-	struct iterator *it = index_create_iterator(*ephem_space->index,
+	struct iterator *it = index_create_iterator(*pCur->space->index,
 						    ITER_ALL, nil_key,
 						    0 /* part_count */);
 	if (it == NULL) {
@@ -667,7 +605,7 @@ int tarantoolSqlite3EphemeralClearTable(BtCursor *pCur)
 	while (iterator_next(it, &tuple) == 0 && tuple != NULL) {
 		key = tuple_extract_key(tuple, box_iterator_key_def(it),
 					&key_size);
-		if (space_ephemeral_delete(ephem_space, key) != 0) {
+		if (space_ephemeral_delete(pCur->space, key) != 0) {
 			iterator_delete(it);
 			return SQL_TARANTOOL_DELETE_FAIL;
 		}
@@ -1025,8 +963,9 @@ int tarantoolSqlite3IdxKeyCompare(BtCursor *pCur, UnpackedRecord *pUnpacked,
 				  int *res)
 {
 	assert(pCur->curFlags & BTCF_TaCursor);
+	assert(pCur->iter != NULL);
+	assert(pCur->last_tuple != NULL);
 
-	struct ta_cursor *c = pCur->pTaCursor;
 	const box_key_def_t *key_def;
 	const struct tuple *tuple;
 	const char *base;
@@ -1042,13 +981,9 @@ int tarantoolSqlite3IdxKeyCompare(BtCursor *pCur, UnpackedRecord *pUnpacked,
 	uint32_t key_size;
 #endif
 
-	assert(c);
-	assert(c->iter);
-	assert(c->tuple_last);
-
-	key_def = box_iterator_key_def(c->iter);
+	key_def = box_iterator_key_def(pCur->iter);
 	n = MIN(pUnpacked->nField, key_def->part_count);
-	tuple = c->tuple_last;
+	tuple = pCur->last_tuple;
 	base = tuple_data(tuple);
 	format = tuple_format(tuple);
 	field_map = tuple_field_map(tuple);
@@ -1118,6 +1053,7 @@ out:
  */
 int tarantoolSqlite3IncrementMaxid(BtCursor *pCur)
 {
+	assert(pCur->curFlags & BTCF_TaCursor);
 	/* ["max_id"] */
 	static const char key[] = {
 		(char)0x91, /* MsgPack array(1) */
@@ -1134,9 +1070,6 @@ int tarantoolSqlite3IncrementMaxid(BtCursor *pCur)
 		1           /* MsgPack int(1) */
 	};
 
-	assert(pCur->curFlags & BTCF_TaCursor);
-
-	struct ta_cursor *c = pCur->pTaCursor;
 	uint32_t space_id = SQLITE_PAGENO_TO_SPACEID(pCur->pgnoRoot);
 	uint32_t index_id = SQLITE_PAGENO_TO_INDEXID(pCur->pgnoRoot);
 	box_tuple_t *res;
@@ -1150,54 +1083,30 @@ int tarantoolSqlite3IncrementMaxid(BtCursor *pCur)
 	if (rc != 0 || res == NULL) {
 		return SQL_TARANTOOL_ERROR;
 	}
-	if (!c) {
-		c = cursor_create(NULL, 0);
-		if (!c) return SQLITE_NOMEM;
-		pCur->pTaCursor = c;
-		c->type = ITER_EQ; /* store some meaningfull value */
-	} else if (c->tuple_last) {
-		box_tuple_unref(c->tuple_last);
+	if (pCur->last_tuple != NULL) {
+		box_tuple_unref(pCur->last_tuple);
 	}
 	box_tuple_ref(res);
-	c->tuple_last = res;
+	pCur->last_tuple = res;
 	pCur->eState = CURSOR_VALID;
 	return SQLITE_OK;
 }
 
 /*
- * Allocate or grow cursor.
+ * Allocate or grow memory for cursor's key.
  * Result->type value is unspecified.
  */
-static struct ta_cursor *
-cursor_create(struct ta_cursor *c, size_t key_size)
+void
+key_alloc(BtCursor *cur, size_t key_size)
 {
-	size_t             size;
-	struct ta_cursor  *res;
-	struct space *ephem_space;
-
-	if (c) {
-		size = c->size;
-		ephem_space = c->ephem_space;
-		if (size - offsetof(struct ta_cursor, key) >= key_size)
-			return c;
+	if (cur->key == NULL) {
+		cur->key = malloc(key_size);
+		cur->iter = NULL;
+		cur->last_tuple = NULL;
 	} else {
-		size = sizeof(*c);
-		ephem_space = NULL;
+		cur->key = realloc(cur->key, key_size);
 	}
-
-	while (size - offsetof(struct ta_cursor, key) < key_size)
-		size *= 2;
-
-	res = realloc(c, size);
-	if (res) {
-		res->size = size;
-		res->ephem_space = ephem_space;
-		if (!c) {
-			res->iter = NULL;
-			res->tuple_last = NULL;
-		}
-	}
-	return res;
+	cur->nKey = key_size;
 }
 
 /*
@@ -1215,13 +1124,10 @@ cursor_create(struct ta_cursor *c, size_t key_size)
 static int
 cursor_seek(BtCursor *pCur, int *pRes)
 {
-	struct ta_cursor *c = pCur->pTaCursor;
-	assert(c != NULL);
-
 	/* Close existing iterator, if any */
-	if (c->iter) {
-		box_iterator_free(c->iter);
-		c->iter = NULL;
+	if (pCur->iter) {
+		box_iterator_free(pCur->iter);
+		pCur->iter = NULL;
 	}
 
 	struct space *space;
@@ -1234,24 +1140,24 @@ cursor_seek(BtCursor *pCur, int *pRes)
 		uint32_t index_id = SQLITE_PAGENO_TO_INDEXID(pCur->pgnoRoot);
 		index = index_find(space, index_id);
 	} else {
-		space = c->ephem_space;
+		space = pCur->space;
 		index = *space->index;
 	}
 
-	const char *key = (const char *)c->key;
+	const char *key = (const char *)pCur->key;
 	uint32_t part_count = mp_decode_array(&key);
-	if (key_validate(index->def, c->type, key, part_count)) {
+	if (key_validate(index->def, pCur->iter_type, key, part_count)) {
 		diag_log();
 		return SQL_TARANTOOL_ITERATOR_FAIL;
 	}
 
-	struct iterator *it = index_create_iterator(index, c->type, key,
+	struct iterator *it = index_create_iterator(index, pCur->iter_type, key,
 						    part_count);
 	if (it == NULL) {
 		pCur->eState = CURSOR_INVALID;
 		return SQL_TARANTOOL_ITERATOR_FAIL;
 	}
-	c->iter = it;
+	pCur->iter = it;
 	pCur->eState = CURSOR_VALID;
 
 	return cursor_advance(pCur, pRes);
@@ -1270,16 +1176,15 @@ cursor_seek(BtCursor *pCur, int *pRes)
 static int
 cursor_advance(BtCursor *pCur, int *pRes)
 {
-	struct ta_cursor *c = pCur->pTaCursor;
-	assert(c);
-	assert(c->iter);
+	assert(pCur->iter != NULL);
 
 	struct tuple *tuple;
-	if (iterator_next(c->iter, &tuple) != 0)
+	if (iterator_next(pCur->iter, &tuple) != 0)
 		return SQL_TARANTOOL_ITERATOR_FAIL;
 	if (tuple != NULL && tuple_bless(tuple) == NULL)
 		return SQL_TARANTOOL_ITERATOR_FAIL;
-	if (c->tuple_last) box_tuple_unref(c->tuple_last);
+	if (pCur->last_tuple)
+		box_tuple_unref(pCur->last_tuple);
 	if (tuple) {
 		box_tuple_ref(tuple);
 		*pRes = 0;
@@ -1287,7 +1192,7 @@ cursor_advance(BtCursor *pCur, int *pRes)
 		pCur->eState = CURSOR_INVALID;
 		*pRes = 1;
 	}
-	c->tuple_last = tuple;
+	pCur->last_tuple = tuple;
 	return SQLITE_OK;
 }
 
@@ -1749,9 +1654,7 @@ sql_debug_info(struct info_handler *h)
 int tarantoolSqlite3EphemeralGetMaxId(BtCursor *pCur, uint32_t fieldno,
 				       uint64_t *max_id)
 {
-	assert(pCur->pTaCursor);
-	struct ta_cursor *c = pCur->pTaCursor;
-	struct space *ephem_space = c->ephem_space;
+	struct space *ephem_space = pCur->space;
 	assert(ephem_space);
 	struct index *primary_index = *ephem_space->index;
 
diff --git a/src/box/sql/cursor.c b/src/box/sql/cursor.c
index 8e6d5c82b..02add5f11 100644
--- a/src/box/sql/cursor.c
+++ b/src/box/sql/cursor.c
@@ -38,8 +38,10 @@
 void
 sqlite3ClearCursor(BtCursor * pCur)
 {
-	sqlite3_free(pCur->pKey);
-	pCur->pKey = 0;
+	sqlite3_free(pCur->key);
+	pCur->key = 0;
+	pCur->iter = NULL;
+	pCur->last_tuple = NULL;
 	pCur->eState = CURSOR_INVALID;
 }
 
@@ -55,16 +57,11 @@ sqlite3CursorHintFlags(BtCursor * pCur, unsigned x)
 
 /*
  * Initialize memory that will be converted into a BtCursor object.
- *
- * The simple approach here would be to memset() the entire object
- * to zero.  But it turns out that the apPage[] and aiIdx[] arrays
- * do not need to be zeroed and they are large, so we can save a lot
- * of run-time by skipping the initialization of those elements.
  */
 void
 sqlite3CursorZero(BtCursor * p)
 {
-	memset(p, 0, offsetof(BtCursor, hints));
+	memset(p, 0, sizeof(*p));
 }
 
 /*
@@ -165,7 +162,6 @@ sqlite3CursorMovetoUnpacked(BtCursor * pCur,	/* The cursor to be moved */
 {
 	assert(pRes);
 	assert(pIdxKey);
-	assert(pCur->pKeyInfo);
 	assert((pCur->curFlags & BTCF_TaCursor) ||
 	       (pCur->curFlags & BTCF_TEphemCursor));
 
diff --git a/src/box/sql/cursor.h b/src/box/sql/cursor.h
index 646d9913d..6b23ebf4a 100644
--- a/src/box/sql/cursor.h
+++ b/src/box/sql/cursor.h
@@ -58,19 +58,16 @@ typedef struct BtCursor BtCursor;
  * for ordinary space, or to TEphemCursor for ephemeral space.
  */
 struct BtCursor {
-	BtCursor *pNext;	/* Forms a linked list of all cursors */
 	i64 nKey;		/* Size of pKey, or last integer key */
-	void *pKey;		/* Saved key that was cursor last known position */
 	Pgno pgnoRoot;		/* Contains both space_id and index_id */
 	u8 curFlags;		/* zero or more BTCF_* flags defined below */
 	u8 eState;		/* One of the CURSOR_XXX constants (see below) */
 	u8 hints;		/* As configured by CursorSetHints() */
-	/* All fields above are zeroed when the cursor is allocated.  See
-	 * sqlite3CursorZero().  Fields that follow must be manually
-	 * initialized.
-	 */
-	struct KeyInfo *pKeyInfo;	/* Argument passed to comparison function */
-	void *pTaCursor;	/* Tarantool cursor */
+	struct space *space;
+	struct iterator *iter;
+	enum iterator_type iter_type;
+	struct tuple *last_tuple;
+	char *key;		/* Saved key that was cursor last known position */
 };
 
 void sqlite3CursorZero(BtCursor *);
diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
index 7de9b67c1..cd3321c4f 100644
--- a/src/box/sql/vdbe.c
+++ b/src/box/sql/vdbe.c
@@ -3214,10 +3214,8 @@ case OP_OpenWrite:
 	assert(p2 >= 1);
 	pBtCur = pCur->uc.pCursor;
 	pBtCur->pgnoRoot = p2;
-	pBtCur->pKeyInfo = pKeyInfo;
 	pBtCur->eState = CURSOR_INVALID;
 	pBtCur->curFlags |= BTCF_TaCursor;
-	pBtCur->pTaCursor = 0;
 	pCur->pKeyInfo = pKeyInfo;
 
 	open_cursor_set_hints:
@@ -3254,10 +3252,8 @@ case OP_OpenTEphemeral: {
 	pBtCur = pCx->uc.pCursor;
 	/* Ephemeral spaces don't have space_id */
 	pBtCur->pgnoRoot = 0;
-	pBtCur->pKeyInfo = pCx->pKeyInfo;
 	pBtCur->eState = CURSOR_INVALID;
 	pBtCur->curFlags = BTCF_TEphemCursor;
-	pBtCur->pTaCursor = 0;
 
 	rc = tarantoolSqlite3EphemeralCreate(pCx->uc.pCursor, pOp->p2,
 					     pOp->p4.pKeyInfo->aColl[0]);
@@ -4406,11 +4402,8 @@ case OP_IdxInsert: {        /* in2 */
 		rc = sqlite3VdbeSorterWrite(pC, pIn2);
 	} else {
 		BtCursor *pBtCur = pC->uc.pCursor;
-		assert((pIn2->z == 0) == (pBtCur->pKeyInfo == 0));
-
 		pBtCur->nKey = pIn2->n;
-		pBtCur->pKey = pIn2->z;
-
+		pBtCur->key = pIn2->z;
 		if (pBtCur->curFlags & BTCF_TaCursor) {
 			/* Make sure that memory has been allocated on region. */
 			assert(aMem[pOp->p2].flags & MEM_Ephem);
@@ -4435,7 +4428,7 @@ case OP_IdxInsert: {        /* in2 */
 		 * nullified.
 		 */
 		pBtCur->nKey = 0;
-		pBtCur->pKey = NULL;
+		pBtCur->key = NULL;
 	}
 
 	if (pOp->p5 & OPFLAG_OE_IGNORE) {
-- 
2.15.1





More information about the Tarantool-patches mailing list