Added partial implementation of range tracking for pinning arbitrary
regions. Currently, tracks regions, and is O(m log(n)) for each operation, where m is the number of transition points per range, and n is the number of transition points in the system. A transition point is a place in memory where the pincount changes.
This commit is contained in:
parent
f6ccaadc35
commit
c2fa9913b1
4 changed files with 264 additions and 2 deletions
34
lladd/io/rangeTracker.h
Normal file
34
lladd/io/rangeTracker.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
typedef struct range {
|
||||
long start;
|
||||
long end;
|
||||
} range;
|
||||
|
||||
typedef struct transition {
|
||||
long pos;
|
||||
// negative if end of range. Never zero
|
||||
int delta;
|
||||
// >= abs(delta). Number of times the range immediately less than
|
||||
// this point is pinned.
|
||||
int pins;
|
||||
} transition;
|
||||
|
||||
typedef struct rangeTracker rangeTracker;
|
||||
|
||||
rangeTracker * rangeTrackerInit(int quantization);
|
||||
void rangeTrackerDeinit(rangeTracker * rt);
|
||||
|
||||
/**
|
||||
Add a new range
|
||||
@return a null terminated array of newly-pinned, quantized ranges
|
||||
*/
|
||||
range ** rangeTrackerAdd(rangeTracker * rt, const range * r);
|
||||
/**
|
||||
Remove a range
|
||||
@return a null terminated array of newly-unpinned, quantized ranges
|
||||
*/
|
||||
range ** rangeTrackerRemove(rangeTracker * rt, const range * r);
|
||||
|
||||
const transition ** enumTransitions(rangeTracker * rt);
|
||||
char * rangeToString(const range * r);
|
||||
char * transitionToString(const transition * t);
|
||||
|
|
@ -18,7 +18,7 @@ liblladd_a_SOURCES=crc32.c redblack.c lhtable.c common.c stats.c io.c bufferMana
|
|||
operations/linearHashNTA.c operations/linkedListNTA.c \
|
||||
operations/pageOrientedListNTA.c operations/bTree.c \
|
||||
operations/regions.c \
|
||||
io/memory.c io/file.c io/non_blocking.c io/debug.c
|
||||
io/rangeTracker.c io/memory.c io/file.c io/non_blocking.c io/debug.c
|
||||
# page/header.c logger/logMemory.c \ ringbuffer.c \ asdfas
|
||||
#operations/lladdhash.c
|
||||
#AM_CFLAGS= -g -Wall -pedantic -std=gnu99
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
if HAVE_LIBCHECK
|
||||
## Had to disable check_lht because lht needs to be rewritten.
|
||||
TESTS = check_lhtable check_logEntry check_logWriter check_page check_operations check_transactional2 check_recovery check_blobRecovery check_bufferManager check_indirect check_pageOperations check_linearHash check_logicalLinearHash check_header check_linkedListNTA check_linearHashNTA check_pageOrientedList check_lockManager check_compensations check_errorHandling check_ringbuffer check_iterator check_multiplexer check_bTree check_regions check_allocationPolicy check_io
|
||||
TESTS = check_lhtable check_logEntry check_logWriter check_page check_operations check_transactional2 check_recovery check_blobRecovery check_bufferManager check_indirect check_pageOperations check_linearHash check_logicalLinearHash check_header check_linkedListNTA check_linearHashNTA check_pageOrientedList check_lockManager check_compensations check_errorHandling check_ringbuffer check_iterator check_multiplexer check_bTree check_regions check_allocationPolicy check_io check_rangeTracker
|
||||
#check_lladdhash
|
||||
else
|
||||
TESTS =
|
||||
|
|
228
test/lladd/check_rangeTracker.c
Normal file
228
test/lladd/check_rangeTracker.c
Normal file
|
@ -0,0 +1,228 @@
|
|||
#include <check.h>
|
||||
#include <config.h>
|
||||
#include <assert.h>
|
||||
#include "../check_includes.h"
|
||||
#define LOG_NAME "check_rangeTracker.log"
|
||||
#include <lladd/io/rangeTracker.h>
|
||||
|
||||
void printRT(rangeTracker * rt) {
|
||||
const transition ** ts = enumTransitions(rt);
|
||||
ts = enumTransitions(rt);
|
||||
int i = 0;
|
||||
printf("Range tracker:\n");
|
||||
while(ts[i]) {
|
||||
printf("%s\n", transitionToString(ts[i]));
|
||||
i++;
|
||||
}
|
||||
free (ts);
|
||||
}
|
||||
|
||||
START_TEST(rangeTracker_smokeTest) {
|
||||
rangeTracker * rt = rangeTrackerInit(512);
|
||||
|
||||
const transition ** ts = enumTransitions(rt);
|
||||
|
||||
assert(ts[0] == 0);
|
||||
|
||||
free(ts);
|
||||
|
||||
// printRT(rt);
|
||||
|
||||
|
||||
range r;
|
||||
r.start = 10;
|
||||
r.end = 100;
|
||||
|
||||
rangeTrackerAdd(rt, &r);
|
||||
|
||||
// printRT(rt);
|
||||
|
||||
ts = enumTransitions(rt);
|
||||
|
||||
// 10 20 80 90 100
|
||||
// | | | | |
|
||||
// |1111|11111111111111|1111|111|
|
||||
// | | | | |
|
||||
|
||||
assert(ts[0]->pos == 10 && ts[0]->delta == 1 && ts[0]->pins == 0 &&
|
||||
ts[1]->pos == 100&& ts[1]->delta == -1 && ts[1]->pins == 1 && !ts[2]);
|
||||
|
||||
|
||||
r.start = 20;
|
||||
r.end = 80;
|
||||
|
||||
rangeTrackerRemove(rt, &r);
|
||||
|
||||
// printRT(rt);
|
||||
|
||||
ts = enumTransitions(rt);
|
||||
|
||||
// 10 20 80 90 100
|
||||
// | | | | |
|
||||
// |1111| |1111|111|
|
||||
// | | | | |
|
||||
|
||||
assert(ts[0]->pos == 10 && ts[0]->delta == 1 && ts[0]->pins == 0 &&
|
||||
ts[1]->pos == 20 && ts[1]->delta == -1 && ts[1]->pins == 1 &&
|
||||
ts[2]->pos == 80 && ts[2]->delta == 1 && ts[2]->pins == 0 &&
|
||||
ts[3]->pos == 100&& ts[3]->delta == -1 && ts[3]->pins == 1 && !ts[4]);
|
||||
|
||||
|
||||
rangeTrackerAdd(rt, &r);
|
||||
|
||||
// printRT(rt);
|
||||
|
||||
ts = enumTransitions(rt);
|
||||
|
||||
// 10 20 80 90 100
|
||||
// | | | | |
|
||||
// |1111|11111111111111|1111|111|
|
||||
// | | | | |
|
||||
|
||||
|
||||
assert(ts[0]->pos == 10 && ts[0]->delta == 1 && ts[0]->pins == 0 &&
|
||||
ts[1]->pos == 100&& ts[1]->delta == -1 && ts[1]->pins == 1 && !ts[2]);
|
||||
|
||||
rangeTrackerAdd(rt, &r);
|
||||
|
||||
// printRT(rt);
|
||||
|
||||
ts = enumTransitions(rt);
|
||||
|
||||
// 10 20 80 90 100
|
||||
// | | | | |
|
||||
// |1111|22222222222222|1111|111|
|
||||
// | | | | |
|
||||
|
||||
assert(ts[0]->pos == 10 && ts[0]->delta == 1 && ts[0]->pins == 0 &&
|
||||
ts[1]->pos == 20 && ts[1]->delta == 1 && ts[1]->pins == 1 &&
|
||||
ts[2]->pos == 80 && ts[2]->delta == -1 && ts[2]->pins == 2 &&
|
||||
ts[3]->pos == 100&& ts[3]->delta == -1 && ts[3]->pins == 1 && !ts[4]);
|
||||
|
||||
|
||||
rangeTrackerRemove(rt, &r);
|
||||
ts = enumTransitions(rt);
|
||||
|
||||
// 10 20 80 90 100
|
||||
// | | | | |
|
||||
// |1111|11111111111111|1111|111|
|
||||
// | | | | |
|
||||
|
||||
|
||||
assert(ts[0]->pos == 10 && ts[0]->delta == 1 && ts[0]->pins == 0 &&
|
||||
ts[1]->pos == 100&& ts[1]->delta == -1 && ts[1]->pins == 1 && !ts[2]);
|
||||
rangeTrackerRemove(rt, &r);
|
||||
|
||||
// printRT(rt);
|
||||
|
||||
ts = enumTransitions(rt);
|
||||
|
||||
// 10 20 80 90 100
|
||||
// | | | | |
|
||||
// |1111| |1111|111|
|
||||
// | | | | |
|
||||
|
||||
assert(ts[0]->pos == 10 && ts[0]->delta == 1 && ts[0]->pins == 0 &&
|
||||
ts[1]->pos == 20 && ts[1]->delta == -1 && ts[1]->pins == 1 &&
|
||||
ts[2]->pos == 80 && ts[2]->delta == 1 && ts[2]->pins == 0 &&
|
||||
ts[3]->pos == 100&& ts[3]->delta == -1 && ts[3]->pins == 1 && !ts[4]);
|
||||
|
||||
r.start = 80;
|
||||
r.end = 90;
|
||||
|
||||
|
||||
|
||||
rangeTrackerAdd(rt, &r);
|
||||
|
||||
// printRT(rt);
|
||||
|
||||
ts = enumTransitions(rt);
|
||||
|
||||
// 10 20 80 90 100
|
||||
// | | | | |
|
||||
// |1111| |2222|111|
|
||||
// | | | | |
|
||||
|
||||
|
||||
assert(ts[0]->pos == 10 && ts[0]->delta == 1 && ts[0]->pins == 0 &&
|
||||
ts[1]->pos == 20 && ts[1]->delta == -1 && ts[1]->pins == 1 &&
|
||||
ts[2]->pos == 80 && ts[2]->delta == 2 && ts[2]->pins == 0 &&
|
||||
ts[3]->pos == 90 && ts[3]->delta == -1 && ts[3]->pins == 2 &&
|
||||
ts[4]->pos == 100&& ts[4]->delta == -1 && ts[4]->pins == 1 && !ts[5]);
|
||||
|
||||
r.start = 80;
|
||||
r.end = 100;
|
||||
rangeTrackerRemove(rt, &r);
|
||||
|
||||
// printRT(rt);
|
||||
ts = enumTransitions(rt);
|
||||
|
||||
// 10 20 80 90 100
|
||||
// | | | | |
|
||||
// |1111| |1111| |
|
||||
// | | | | |
|
||||
|
||||
|
||||
assert(ts[0]->pos == 10 && ts[0]->delta == 1 && ts[0]->pins == 0 &&
|
||||
ts[1]->pos == 20 && ts[1]->delta == -1 && ts[1]->pins == 1 &&
|
||||
ts[2]->pos == 80 && ts[2]->delta == 1 && ts[2]->pins == 0 &&
|
||||
ts[3]->pos == 90 && ts[3]->delta == -1 && ts[3]->pins == 1 && !ts[4]);
|
||||
|
||||
|
||||
r.start = 10;
|
||||
r.end = 20;
|
||||
rangeTrackerRemove(rt, &r);
|
||||
|
||||
// printRT(rt);
|
||||
ts = enumTransitions(rt);
|
||||
|
||||
// 10 20 80 90 100
|
||||
// | | | | |
|
||||
// | | |1111| |
|
||||
// | | | | |
|
||||
|
||||
|
||||
assert(ts[0]->pos == 80 && ts[0]->delta == 1 && ts[0]->pins == 0 &&
|
||||
ts[1]->pos == 90 && ts[1]->delta == -1 && ts[1]->pins == 1 && !ts[2]);
|
||||
|
||||
|
||||
r.start = 80;
|
||||
r.end = 90;
|
||||
|
||||
rangeTrackerRemove(rt, &r);
|
||||
|
||||
// printRT(rt);
|
||||
ts = enumTransitions(rt);
|
||||
|
||||
// 10 20 80 90 100
|
||||
// | | | | |
|
||||
// | | | | |
|
||||
// | | | | |
|
||||
|
||||
|
||||
assert(!ts[0]);
|
||||
rangeTrackerDeinit(rt);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/**
|
||||
Add suite declarations here
|
||||
*/
|
||||
Suite * check_suite(void) {
|
||||
Suite *s = suite_create("rangeTracker");
|
||||
/* Begin a new test */
|
||||
TCase *tc = tcase_create("rangeTracker");
|
||||
tcase_set_timeout(tc, 600); // ten minute timeout
|
||||
|
||||
/* Sub tests are added, one per line, here */
|
||||
tcase_add_test(tc, rangeTracker_smokeTest);
|
||||
|
||||
/* --------------------------------------------- */
|
||||
tcase_add_checked_fixture(tc, setup, teardown);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
#include "../check_setup.h"
|
Loading…
Reference in a new issue