1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
#include "trivia/util.h"
#include "vy_iterators_helper.h"
#include "vy_history.h"
#include "fiber.h"
#include "unit.h"
const struct vy_stmt_template key_template = STMT_TEMPLATE(0, SELECT, vyend);
static void
test_basic()
{
header();
plan(6);
struct vy_cache cache;
uint32_t fields[] = { 0 };
uint32_t types[] = { FIELD_TYPE_UNSIGNED };
struct key_def *key_def;
struct tuple_format *format;
create_test_cache(fields, types, lengthof(fields), &cache, &key_def,
&format);
struct vy_entry select_all = vy_new_simple_stmt(format, key_def,
&key_template);
struct mempool history_node_pool;
mempool_create(&history_node_pool, cord_slab_cache(),
sizeof(struct vy_history_node));
/*
* Fill the cache with 3 chains.
*/
const struct vy_stmt_template chain1[] = {
STMT_TEMPLATE(1, REPLACE, 100),
STMT_TEMPLATE(2, REPLACE, 200),
STMT_TEMPLATE(3, REPLACE, 300),
STMT_TEMPLATE(4, REPLACE, 400),
STMT_TEMPLATE(5, REPLACE, 500),
STMT_TEMPLATE(6, REPLACE, 600),
};
vy_cache_insert_templates_chain(&cache, format, chain1,
lengthof(chain1), &key_template,
ITER_GE);
is(cache.cache_tree.size, 6, "cache is filled with 6 statements");
const struct vy_stmt_template chain2[] = {
STMT_TEMPLATE(10, REPLACE, 1001),
STMT_TEMPLATE(11, REPLACE, 1002),
STMT_TEMPLATE(12, REPLACE, 1003),
STMT_TEMPLATE(13, REPLACE, 1004),
STMT_TEMPLATE(14, REPLACE, 1005),
STMT_TEMPLATE(15, REPLACE, 1006),
};
vy_cache_insert_templates_chain(&cache, format, chain2,
lengthof(chain2), &key_template,
ITER_GE);
is(cache.cache_tree.size, 12, "cache is filled with 12 statements");
const struct vy_stmt_template chain3[] = {
STMT_TEMPLATE(16, REPLACE, 1107),
STMT_TEMPLATE(17, REPLACE, 1108),
STMT_TEMPLATE(18, REPLACE, 1109),
STMT_TEMPLATE(19, REPLACE, 1110),
STMT_TEMPLATE(20, REPLACE, 1111),
STMT_TEMPLATE(21, REPLACE, 1112),
};
vy_cache_insert_templates_chain(&cache, format, chain3,
lengthof(chain3), &key_template,
ITER_GE);
is(cache.cache_tree.size, 18, "cache is filled with 18 statements");
/*
* Try to restore opened and positioned iterator.
* At first, start the iterator and make several iteration
* steps.
* At second, change cache version be insertion a new
* statement.
* At third, restore the opened on the first step
* iterator on the several statements back.
*
* Key1 Key2 NewKey Key3 Key4 Key5
* ^ ^ ^
* restore to new stmt current position
* | |
* +- - - - < - - - - < - - - - -+
*/
struct vy_cache_iterator itr;
struct vy_read_view rv;
rv.vlsn = INT64_MAX;
const struct vy_read_view *rv_p = &rv;
vy_cache_iterator_open(&itr, &cache, ITER_GE, select_all, &rv_p);
/* Start iterator and make several steps. */
struct vy_entry ret;
bool unused;
struct vy_history history;
vy_history_create(&history, &history_node_pool);
for (int i = 0; i < 4; ++i)
vy_cache_iterator_next(&itr, &history, &unused);
ret = vy_history_last_stmt(&history);
ok(vy_stmt_are_same(ret, &chain1[3], format, key_def),
"next_key * 4");
/*
* Emulate new statement insertion: break the first chain
* and insert into the cache the new statement.
*/
const struct vy_stmt_template to_insert =
STMT_TEMPLATE(22, REPLACE, 201);
vy_cache_on_write_template(&cache, format, &to_insert);
vy_cache_insert_templates_chain(&cache, format, &to_insert, 1,
&key_template, ITER_GE);
/*
* Restore after the cache had changed. Restoration
* makes position of the iterator be one statement after
* the last. So restore on chain1[0], but the result
* must be chain1[1].
*/
struct vy_entry last = vy_new_simple_stmt(format, key_def, &chain1[0]);
ok(vy_cache_iterator_restore(&itr, last, &history, &unused) >= 0,
"restore");
ret = vy_history_last_stmt(&history);
ok(vy_stmt_are_same(ret, &chain1[1], format, key_def),
"restore on position after last");
tuple_unref(last.stmt);
vy_history_cleanup(&history);
vy_cache_iterator_close(&itr);
mempool_destroy(&history_node_pool);
tuple_unref(select_all.stmt);
destroy_test_cache(&cache, key_def, format);
check_plan();
footer();
}
int
main()
{
vy_iterator_C_test_init(1LLU * 1024LLU * 1024LLU * 1024LLU);
test_basic();
vy_iterator_C_test_finish();
return 0;
}
|