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 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
|
#include "memory.h"
#include "fiber.h"
#include "tuple.h"
#include "unit.h"
#include <stdio.h>
enum {
BIGREF_DIFF = 10,
BIGREF_COUNT = 70003,
BIGREF_CAPACITY = 107,
};
static char tuple_buf[64];
static char *tuple_end = tuple_buf;
/**
* This function creates new tuple with refs == 1.
*/
static inline struct tuple *
create_tuple()
{
struct tuple *ret =
tuple_new(box_tuple_format_default(), tuple_buf, tuple_end);
tuple_ref(ret);
return ret;
}
/**
* This test performs overall check of bigrefs.
* What it checks:
* 1) Till refs <= TUPLE_REF_MAX it shows number of refs
* of tuple and it isn't a bigref.
* 2) When refs > TUPLE_REF_MAX first 15 bits of it becomes
* index of bigref and the last bit becomes true which
* shows that it is bigref.
* 3) Each of tuple has its own number of refs, but all
* these numbers more than it is needed for getting a bigref.
* 4) Indexes of bigrefs are given sequentially.
* 5) After some tuples are sequentially deleted all of
* others bigrefs are fine. In this test BIGREF_CAPACITY
* tuples created and each of their ref counter increased
* to (BIGREF_COUNT - index of tuple). Tuples are created
* consistently.
*/
static void
test_bigrefs_overall()
{
header();
plan(3);
uint16_t counter = 0;
struct tuple **tuples = (struct tuple **) malloc(BIGREF_CAPACITY *
sizeof(*tuples));
for(int i = 0; i < BIGREF_CAPACITY; ++i)
tuples[i] = create_tuple();
for(int i = 0; i < BIGREF_CAPACITY; ++i)
counter += tuples[i]->refs == 1;
is(counter, BIGREF_CAPACITY, "All tuples have refs == 1.");
for(int i = 0; i < BIGREF_CAPACITY; ++i) {
for(int j = 1; j < TUPLE_REF_MAX; ++j)
tuple_ref(tuples[i]);
tuple_ref(tuples[i]);
for(int j = TUPLE_REF_MAX + 1; j < BIGREF_COUNT - i; ++j)
tuple_ref(tuples[i]);
}
counter = 0;
for(int i = 0; i < BIGREF_CAPACITY; ++i)
counter += tuples[i]->is_bigref == true;
is(counter, BIGREF_CAPACITY, "All tuples have bigrefs.");
counter = 0;
for(int i = 0; i < BIGREF_CAPACITY; ++i) {
for(int j = 1; j < BIGREF_COUNT - i; ++j)
tuple_unref(tuples[i]);
counter += tuples[i]->refs == 1;
tuple_unref(tuples[i]);
}
is(counter, BIGREF_CAPACITY, "All tuples were deleted.");
free(tuples);
footer();
check_plan();
}
/**
* This test checks that indexes are given as
* intended.
*/
static void
test_bigrefs_non_consistent()
{
header();
plan(3);
uint16_t counter = 0;
uint16_t max_index = BIGREF_CAPACITY / BIGREF_DIFF;
struct tuple **tuples = (struct tuple **) malloc(BIGREF_CAPACITY *
sizeof(*tuples));
uint16_t *indexes = (uint16_t *) malloc(sizeof(*indexes) *
(max_index + 1));
for(int i = 0; i < BIGREF_CAPACITY; ++i)
tuples[i] = create_tuple();
for(int i = 0; i < BIGREF_CAPACITY; ++i) {
for(int j = 1; j < BIGREF_COUNT; ++j)
tuple_ref(tuples[i]);
counter += tuples[i]->is_bigref == true;
}
is(counter, BIGREF_CAPACITY, "All tuples have bigrefs.");
counter = 0;
uint16_t index = 0;
for(int i = 0; i < BIGREF_CAPACITY; i += BIGREF_DIFF) {
indexes[index] = tuples[i]->ref_index;
for(int j = 1; j < BIGREF_COUNT; ++j)
tuple_unref(tuples[i]);
index++;
counter += tuples[i]->is_bigref == false;
}
is(counter, max_index + 1, "%d tuples don't have bigrefs "\
"and all other tuples have", max_index + 1);
counter = 0;
index = 0;
for(int i = 0; i < BIGREF_CAPACITY; i += BIGREF_DIFF) {
bool check_refs = tuples[i]->refs == 1;
for(int j = 1; j < BIGREF_COUNT; ++j)
tuple_ref(tuples[i]);
counter += check_refs && tuples[i]->is_bigref &&
tuples[i]->ref_index == indexes[max_index - index];
index++;
}
is(counter, max_index + 1, "All tuples have bigrefs and "\
"their indexes are in right order.");
for (int i = 0; i < BIGREF_CAPACITY; ++i) {
for (int j = 0; j < BIGREF_COUNT; ++j)
tuple_unref(tuples[i]);
}
free(indexes);
free(tuples);
footer();
check_plan();
}
int
main()
{
header();
plan(2);
memory_init();
fiber_init(fiber_c_invoke);
tuple_init(NULL);
tuple_end = mp_encode_array(tuple_end, 1);
tuple_end = mp_encode_uint(tuple_end, 2);
test_bigrefs_overall();
test_bigrefs_non_consistent();
tuple_free();
fiber_free();
memory_free();
footer();
check_plan();
}
|