/** * creates cache with special size */ Cache cacheCreate( int size, FreeCacheElement free_element, CopyCacheElement copy_element, CompareCacheElements compare_elements, ComputeCacheKey compute_key) { if (size <= 0 || !free_element || !copy_element || !compare_elements || !compute_key) { return NULL; } //memory allocation Cache cache; CACHE_ALLOCATE(cache_t, cache, NULL); //initialization cache->computeKey = compute_key; cache->cache_size = size; cache->iteratorIndex = CACHE_INVALID_ITERATOR_INDEX; cache->container = (Set*)malloc(sizeof(*cache->container) * size); if (cache->container == NULL) { cacheDestroy(cache); return NULL; } CACHE_CONTAINER_FOREACH(i, cache) { cache->container[i] = setCreate(copy_element, free_element, compare_elements); if (cache->container[i] == NULL) { cacheDestroy(cache); return NULL; } }
bool testCacheExample() { char* empty_string = ""; char* hello = "Hello world!"; char* helloAgain = "Hello world!"; char* goodbye = "Goodbye!"; char* goodDay = "Good day!"; Cache cache = cacheCreate(256, freeString, copyString, compareStrings, getFirstLetter); ASSERT_TEST(cache != NULL); ASSERT_TEST(cacheIsIn(cache, hello) == false); ASSERT_TEST(cachePush(cache, hello) == CACHE_SUCCESS); ASSERT_TEST(cacheIsIn(cache, helloAgain) == true); ASSERT_TEST(cachePush(cache, hello) == CACHE_ITEM_ALREADY_EXISTS); ASSERT_TEST(cachePush(cache, goodbye) == CACHE_SUCCESS); ASSERT_TEST(cachePush(cache, goodDay) == CACHE_SUCCESS); ASSERT_TEST(cachePush(cache, empty_string) == CACHE_SUCCESS); ASSERT_TEST(cacheIsIn(cache, empty_string) == true); ASSERT_TEST(cacheIsIn(cache, goodbye) == true); char* temp_ptr; temp_ptr = cacheExtractElementByKey(cache, 0); ASSERT_TEST(strcmp(temp_ptr, "") == 0); ASSERT_TEST(cacheIsIn(cache, empty_string) == false); ASSERT_TEST(cacheFreeElement(cache, goodbye) == CACHE_SUCCESS); ASSERT_TEST(cacheIsIn(cache, goodbye) == false); ASSERT_TEST(cacheClear(cache) == CACHE_SUCCESS); ASSERT_TEST(setGetFirst(cacheGetFirst(cache)) == NULL); free(temp_ptr); cacheDestroy(cache); return true; }
static bool testCacheFreeElement(void) { Cache cache = cacheCreate(255, freeString, copyString, compareStrings, getFirstLetter); char outOfRange[2] = { (char)255, '\0' }; char *notInCache = "Rock"; char *doubled = "Louna"; char * elements[] = { "Ramones", "Lumen", "Louna", "Arch Enemy" "Linkin park", }; const int ELEMENTS_SIZE = sizeof(elements) / sizeof(*elements); for (int i = 0; i < ELEMENTS_SIZE; ++i) { ASSERT_TEST(cachePush(cache, elements[i]) == CACHE_SUCCESS); } ASSERT_TEST(cachePush(cache, outOfRange) == CACHE_OUT_OF_RANGE); ASSERT_TEST(cachePush(cache, doubled) == CACHE_ITEM_ALREADY_EXISTS); ASSERT_TEST(cacheFreeElement(cache, outOfRange) == CACHE_ITEM_DOES_NOT_EXIST); ASSERT_TEST(cacheFreeElement(cache, notInCache) == CACHE_ITEM_DOES_NOT_EXIST); for (int i = ELEMENTS_SIZE-1; i >= 0; --i) { ASSERT_TEST(cacheFreeElement(cache, elements[i]) == CACHE_SUCCESS); } ASSERT_TEST(cacheFreeElement(cache, doubled) == CACHE_ITEM_DOES_NOT_EXIST); ASSERT_TEST(cacheFreeElement(NULL, doubled) == CACHE_NULL_ARGUMENT); ASSERT_TEST(cacheFreeElement(NULL, NULL) == CACHE_NULL_ARGUMENT); cacheDestroy(cache); return true; }
static bool testCacheCreate(void) { ASSERT_TEST(!cacheCreate(0, freeString, copyString, compareStrings, getFirstLetter)); ASSERT_TEST(!cacheCreate(256, NULL, copyString, compareStrings, getFirstLetter)); ASSERT_TEST(!cacheCreate(256, freeString, NULL, compareStrings, getFirstLetter)); ASSERT_TEST(!cacheCreate(256, freeString, copyString, NULL, getFirstLetter)); ASSERT_TEST(!cacheCreate(256, freeString, copyString, compareStrings, NULL)); Cache cache = cacheCreate(1, freeString, copyString, compareStrings, getFirstLetter); ASSERT_TEST(cache != NULL); cacheDestroy(cache); return true; }
static bool testCachePush() { //strings char * toFirstCell = ""; char * ramones = "Ramones"; char toLastCell[] = {(char)254, '\0'}; char outOfRange[] = {(char)255, '\0'}; Cache cache = cacheCreate(255, freeString, copyString, compareStrings, getFirstLetter); ASSERT_TEST(cache != NULL); ASSERT_TEST(cachePush(NULL, toFirstCell) == CACHE_NULL_ARGUMENT); ASSERT_TEST(cachePush(cache, NULL) == CACHE_NULL_ARGUMENT); ASSERT_TEST(cachePush(cache, toFirstCell) == CACHE_SUCCESS); ASSERT_TEST(cacheIsIn(cache, toFirstCell)); ASSERT_TEST(cacheIsIn(cache, toFirstCell)); ASSERT_TEST(cachePush(cache, ramones) == CACHE_SUCCESS); ASSERT_TEST(cacheIsIn(cache, ramones)); ASSERT_TEST(cachePush(cache, toLastCell) == CACHE_SUCCESS); ASSERT_TEST(cacheIsIn(cache, toLastCell)); ASSERT_TEST(cachePush(cache, outOfRange) == CACHE_OUT_OF_RANGE); ASSERT_TEST(!cacheIsIn(cache, outOfRange)); ASSERT_TEST(cachePush(cache, ramones) == CACHE_ITEM_ALREADY_EXISTS); ASSERT_TEST(cachePush(cache, toFirstCell) == CACHE_ITEM_ALREADY_EXISTS); ASSERT_TEST(cachePush(cache, toLastCell) == CACHE_ITEM_ALREADY_EXISTS); ASSERT_TEST(cachePush(cache, outOfRange) == CACHE_OUT_OF_RANGE); char * toFirstCellCopy = cacheExtractElementByKey(cache, getFirstLetter(toFirstCell)); char * ramonesCopy = cacheExtractElementByKey(cache, getFirstLetter(ramones)); char * toLastCellCopy = cacheExtractElementByKey(cache, getFirstLetter(toLastCell)); char * outOfRangeCopy = cacheExtractElementByKey(cache, getFirstLetter(outOfRange)); ASSERT_TEST(!strcmp(toFirstCell, toFirstCellCopy)); ASSERT_TEST(!strcmp(ramones, ramonesCopy)); ASSERT_TEST(!strcmp(toLastCell, toLastCellCopy)); ASSERT_TEST(outOfRangeCopy == NULL); ASSERT_TEST(cacheExtractElementByKey(cache, getFirstLetter(toFirstCell)) == NULL); ASSERT_TEST(cacheExtractElementByKey(cache, getFirstLetter(ramones)) == NULL); ASSERT_TEST(cacheExtractElementByKey(cache, getFirstLetter(toLastCell)) == NULL); freeString(toFirstCellCopy); freeString(ramonesCopy); freeString(toLastCellCopy); cacheDestroy(cache); return true; }
int main(int argc, char *argv[]) { FileIterator **fis = NULL; const int fi_count = argc - 1; int active_fi_count = 0; time_t ready_time; Cache *them, *us; int i; if (argc < 3) return usage(argv[0]); them = cacheCreate("them"); us = cacheCreate("us"); them->peer = us; us->peer = them; fis = xcalloc(fi_count, sizeof(FileIterator *)); /* init iterators with files */ fis[0] = fileIteratorCreate(argv[1], accessLogReader); for (i = 2; i < argc; ++i) fis[i - 1] = fileIteratorCreate(argv[i], swapStateReader); /* check that all files were found */ for (i = 0; i < fi_count; ++i) if (!fis[i]) return -2; /* read prefix to get start-up contents of the peer cache */ ready_time = -1; for (i = 1; i < fi_count; ++i) { FileIterator *fi = fis[i]; while (fi->inner_time > 0) { if (((storeSwapLogData *) fi->entry)->op == SWAP_LOG_DEL) { cachePurge(them, fi->entry, 0); if (ready_time < 0) ready_time = fi->inner_time; } else { if (ready_time > 0 && fi->inner_time > ready_time) break; cacheStore(them, fi->entry, 0); } fileIteratorAdvance(fi); } } /* digest peer cache content */ cacheResetDigest(them); us->digest = cacheDigestClone(them->digest); /* @netw@ */ /* shift the time in access log to match ready_time */ fileIteratorSetCurTime(fis[0], ready_time); /* iterate, use the iterator with the smallest positive inner_time */ cur_time = -1; do { int next_i = -1; time_t next_time = -1; active_fi_count = 0; for (i = 0; i < fi_count; ++i) { if (fis[i]->inner_time >= 0) { if (!active_fi_count || fis[i]->inner_time < next_time) { next_i = i; next_time = fis[i]->inner_time; } active_fi_count++; } } if (next_i >= 0) { cur_time = next_time; /*fprintf(stderr, "%2d time: %d %s", next_i, (int)cur_time, ctime(&cur_time)); */ if (next_i == 0) cacheFetch(us, fis[next_i]->entry); else cacheUpdateStore(them, fis[next_i]->entry, 1); fileIteratorAdvance(fis[next_i]); } } while (active_fi_count); /* report */ cacheReport(them); cacheReport(us); cacheQueryReport(us, &us->qstats); /* clean */ for (i = 0; i < argc - 1; ++i) { fileIteratorDestroy(fis[i]); } xfree(fis); cacheDestroy(them); cacheDestroy(us); return 0; }