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:
Sears Russell 2007-01-24 01:03:52 +00:00
parent f6ccaadc35
commit c2fa9913b1
4 changed files with 264 additions and 2 deletions

34
lladd/io/rangeTracker.h Normal file
View 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);

View file

@ -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

View file

@ -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 =

View 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"