END_TEST START_TEST(updateLogEntryAllocNoExtras) { Tinit(); recordid rid = { 3 , 4, sizeof(int)*3 }; stasis_log_t *l = (stasis_log_t *)stasis_log(); LogEntry * log = allocUpdateLogEntry(l, 200, 1, OPERATION_SET, rid.page, 0); assert(log->prevLSN == 200); assert(log->xid == 1); assert(log->type == UPDATELOG); assert(log->update.funcID == OPERATION_SET); assert(log->update.page == 3); assert(log->update.arg_size == 0); assert(stasis_log_entry_update_args_ptr(log) == NULL); assert(sizeofLogEntry(0, log) == (sizeof(struct __raw_log_entry) + sizeof(UpdateLogEntry) + 0 * (sizeof(int)+sizeof(char)))); l->write_entry(l, log); l->write_entry_done(l, log); Tdeinit(); }
int main(int argc, char * argv[]) { if(argc != 3) { printf(usage, argv[0]); abort(); } char * endptr; numthreads = strtoul(argv[1], &endptr, 10); if(*endptr != 0) { printf(usage, argv[0]); abort(); } numops= strtoul(argv[2], &endptr, 10) / numthreads; if(*endptr != 0) { printf(usage, argv[0]); abort(); } pthread_t workers[numthreads]; Page * p; Tinit(); dpt = stasis_runtime_dirty_page_table(); p = loadPage(-1,0); for(int i = 0; i < numthreads; i++) { pthread_create(&workers[i], 0, worker, p); } for(int i = 0; i < numthreads; i++) { pthread_join(workers[i], 0); } releasePage(p); Tdeinit(); }
int main(int argc, char** argv) { assert(argc == 3); int xact_count = atoi(argv[1]); int count = atoi(argv[2]); /* unlink("storefile.txt"); unlink("logfile.txt"); unlink("blob0_file.txt"); unlink("blob1_file.txt");*/ Tinit(); int xid = Tbegin(); recordid hash = TnaiveHashCreate(xid, sizeof(int), sizeof(int)); Tcommit(xid); int i = 0; int k; for(k = 0; k < xact_count; k++) { xid = Tbegin(); for(; i < (count*(k+1)) ; i++) { TnaiveHashInsert(xid, hash, &i, sizeof(int), &i, sizeof(int)); } Tcommit(xid); } Tdeinit(); }
JNIEXPORT void JNICALL Java_stasis_jni_Stasis_deinit (JNIEnv *e, jclass c) { initted--; if(!initted) { Tdeinit(); } }
}END_TEST /** @test More complicated case of log w/ hard bound; many xacts at a time. */ START_TEST(boundedLogConcurrentTest) { stasis_log_type = LOG_TO_MEMORY; stasis_log_in_memory_max_entries = 1000; stasis_log_softcommit = 1; Tinit(); int xid = Tbegin(); pageid_t region_start = TregionAlloc(xid, NUM_XACTS, 0); Tcommit(xid); for(int64_t i = 0; i < NUM_XACTS; i++) { int xids[NUM_CONCURRENT_XACTS]; for(int j = 0; j < NUM_CONCURRENT_XACTS; j++) { xids[j] = Tbegin(); } for(int j = 0; j < NUM_CONCURRENT_XACTS; j++) { TinitializeFixedPage(xids[j], region_start + i, sizeof(uint64_t)); recordid rid = {region_start + i, 0, sizeof(uint64_t)}; Tset(xids[j], rid, &i); i++; } for(int j = 0; j < NUM_CONCURRENT_XACTS; j++) { Tcommit(xids[j]); } } Tdeinit(); }END_TEST
} END_TEST START_TEST(regions_lockSmokeTest) { Tinit(); int xid = Tbegin(); pageid_t pageid = TregionAlloc(xid, 100,0); fsckRegions(xid); Tcommit(xid); xid = Tbegin(); int xid2 = Tbegin(); TregionDealloc(xid, pageid); for(int i = 0; i < 50; i++) { TregionAlloc(xid2, 1, 0); } fsckRegions(xid); Tabort(xid); fsckRegions(xid2); Tcommit(xid2); Tdeinit(); } END_TEST
int main(int argc, char * argv[]) { Tinit(); ReferentialAlgebra_init(); recordid rootEntry; recordid hash; int xid = Tbegin(); if(TrecordType(xid, ROOT_RECORD) == INVALID_SLOT) { printf("Creating new store\n"); rootEntry = Talloc(xid, sizeof(recordid)); assert(rootEntry.page == ROOT_RECORD.page); assert(rootEntry.slot == ROOT_RECORD.slot); hash = ReferentialAlgebra_allocContext(xid); Tset(xid, rootEntry, &hash); } else { printf("Opened existing store\n"); rootEntry.page = ROOT_RECORD.page; rootEntry.slot = ROOT_RECORD.slot; rootEntry.size = sizeof(recordid); Tread(xid, rootEntry, &hash); } context = ReferentialAlgebra_openContext(xid,hash); Tcommit(xid); FILE * in; if(argc == 3) { // listen on socket if(strcmp("--socket", argv[1])) { printf("usage:\n\n%s\n%s <filename>\n%s --socket addr:port\n", argv[0],argv[0],argv[0]); } else { startServer(argv[2], hash); } printf("Shutting down...\n"); } else { if(argc == 2) { in = fopen(argv[1], "r"); if(!in) { printf("Couldn't open input file.\n"); return 1; } } else { in = stdin; } openInterpreter(in, stdout, hash); } Tdeinit(); }
} END_TEST START_TEST(regions_recoveryTest) { Tinit(); pageid_t pages[50]; int xid1 = Tbegin(); int xid2 = Tbegin(); for(int i = 0; i < 50; i+=2) { pages[i] = TregionAlloc(xid1, stasis_util_random64(4)+1, 0); pages[i+1] = TregionAlloc(xid2, stasis_util_random64(2)+1, 0); } fsckRegions(xid1); Tcommit(xid1); Tdeinit(); if(TdurabilityLevel() == VOLATILE) { return; } Tinit(); int xid = Tbegin(); fsckRegions(xid); for(int i = 0; i < 50; i+=2) { TregionDealloc(xid, pages[i]); } fsckRegions(xid); Tabort(xid); fsckRegions(Tbegin()); Tdeinit(); Tinit(); fsckRegions(Tbegin()); Tdeinit(); } END_TEST
int main(int argc, char** argv) { assert(argc == 3 || argc == 4); int thread_count = atoi(argv[1]); count = atoi(argv[2]); alwaysCommit = (argc==4); unlink("storefile.txt"); unlink("logfile.txt"); unlink("blob0_file.txt"); unlink("blob1_file.txt"); pthread_t * workers = stasis_malloc(thread_count, pthread_t); Tinit(); int xid = Tbegin(); // hash = ThashCreate(xid, sizeof(int), sizeof(int)); hash = ThashCreate(xid, VARIABLE_LENGTH, VARIABLE_LENGTH); Tcommit(xid); int k; /* threads have static thread sizes. Ughh. */ pthread_attr_t attr; pthread_attr_init(&attr); pthread_mutex_init(&mutex, NULL); pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN); // pthread_attr_setschedpolicy(&attr, SCHED_FIFO); pthread_mutex_lock(&mutex); for(k = 0; k < thread_count; k++) { int * k_copy = stasis_alloc(int); *k_copy = k ; pthread_create(&workers[k], &attr, go, k_copy); } pthread_mutex_unlock(&mutex); for(k = 0; k < thread_count; k++) { pthread_join(workers[k],NULL); } Tdeinit(); printf("Committed %d times, put %d times.\n", commitCount, putCount); }
void insertProbeIter(lsmkey_t NUM_ENTRIES) { int intcmp = 0; lsmTreeRegisterComparator(intcmp,cmp); TlsmRegionAllocConf_t alloc_conf = LSM_REGION_ALLOC_STATIC_INITIALIZER; stasis_page_impl_register(lsmRootImpl()); Tinit(); int xid = Tbegin(); recordid tree = TlsmCreate(xid, intcmp, TlsmRegionAlloc, &alloc_conf, sizeof(lsmkey_t)); long oldpagenum = -1; for(lsmkey_t i = 0; i < NUM_ENTRIES; i++) { long pagenum = TlsmFindPage(xid, tree, (byte*)&i); assert(pagenum == -1 || pagenum == oldpagenum || oldpagenum == -1); DEBUG("TlsmAppendPage %d\n",i); TlsmAppendPage(xid, tree, (const byte*)&i, TlsmRegionAlloc, &alloc_conf, i + OFFSET); pagenum = TlsmFindPage(xid, tree, (byte*)&i); oldpagenum = pagenum; assert(pagenum == i + OFFSET); } for(lsmkey_t i = 0; i < NUM_ENTRIES; i++) { long pagenum = TlsmFindPage(xid, tree, (byte*)&i); assert(pagenum == i + OFFSET); } int64_t count = 0; lladdIterator_t * it = lsmTreeIterator_open(xid, tree); while(lsmTreeIterator_next(xid, it)) { lsmkey_t * key; lsmkey_t **key_ptr = &key; int size = lsmTreeIterator_key(xid, it, (byte**)key_ptr); assert(size == sizeof(lsmkey_t)); long *value; long **value_ptr = &value; size = lsmTreeIterator_value(xid, it, (byte**)value_ptr); assert(size == sizeof(pageid_t)); assert(*key + OFFSET == *value); assert(*key == count); count++; } assert(count == NUM_ENTRIES); lsmTreeIterator_close(xid, it); Tcommit(xid); Tdeinit(); }
END_TEST /** @test Quick test of allocUpdateLogEntry @todo It would be nice if this test used actual operatations table instead of making up values.*/ START_TEST(updateLogEntryAlloc) { char args[] = {'a', 'b', 'c'}; recordid rid = { 3 , 4, sizeof(int)*3 }; LogEntry * log; Tinit(); /* Needed because it sets up the operations table. */ stasis_log_t *l = (stasis_log_t *)stasis_log(); log = allocUpdateLogEntry(l, 200, 1, OPERATION_SET, rid.page, 3*sizeof(char)); memcpy(stasis_log_entry_update_args_ptr(log), args, 3*sizeof(char)); assert(log->prevLSN == 200); assert(log->xid == 1); assert(log->type == UPDATELOG); assert(log->update.funcID == OPERATION_SET); assert(log->update.page == 3); assert(log->update.arg_size == 3*sizeof(char)); assert(stasis_log_entry_update_args_ptr(log) != NULL); assert(args[0] == ((char*)stasis_log_entry_update_args_ptr(log))[0]); assert(args[1] == ((char*)stasis_log_entry_update_args_ptr(log))[1]); assert(args[2] == ((char*)stasis_log_entry_update_args_ptr(log))[2]); // printf("sizes %d %d\n",sizeofLogEntry(log),(sizeof(struct __raw_log_entry) + sizeof(UpdateLogEntry) + (sizeof(char)))); assert(sizeofLogEntry(0, log) == (sizeof(struct __raw_log_entry) + sizeof(UpdateLogEntry) + 3 * (sizeof(char)))); l->write_entry(l, log); l->write_entry_done(l, log); Tdeinit(); }
int main(int argc, char * argv[]) { if(argc != 3) { printf(usage, argv[0]); abort(); } char * endptr; unsigned long numthreads = strtoul(argv[1], &endptr, 10); if(*endptr != 0) { printf(usage, argv[0]); abort(); } unsigned long numops= strtoul(argv[2], &endptr, 10) / numthreads; if(*endptr != 0) { printf(usage, argv[0]); abort(); } pthread_t workers[numthreads]; Tinit(); for(int i = 0; i < numthreads; i++) { pthread_create(&workers[i], 0, noopWorker, &numops); } for(int i = 0; i < numthreads; i++) { pthread_join(workers[i], 0); } Tdeinit(); }
int runSubject(void) { pthread_t* threads; pthread_attr_t attr; intptr_t k; int xid, fd; /* Need the following sleep call for debugging. */ //sleep(45); printf("\tRunning Subject Process\n"); fflush(stdout); readGlobalsFromSharedBuffer(); initHashTable = 1; Tinit(); if (iteration == 0) { /* Create the transactional hash table data structure. */ xid = Tbegin(); hashTable = ThashCreate(xid, sizeof(int), sizeof(int)); Tcommit(xid); /* Write the hash table recordid to a file, so it can be * reloaded during subsequent iterations. */ fd = open("recordid.txt", O_CREAT | O_WRONLY | O_SYNC, 0777); write(fd, (char*) &hashTable, sizeof(recordid)); close(fd); } else { /* Otherwise, read in the hash table from disk. */ fd = open("recordid.txt", O_RDONLY, 0777); read(fd, (char*) &hashTable, sizeof(recordid)); close(fd); } initHashTable = 0; /* Open the insert and commit log files. The insert-log keeps track of all insertions * that were made to the hash-table, not all of which may have been committed. The * commit-log keeps track of all insertions that were definitely committed. */ insertLog = open("inserts.txt", O_CREAT | O_RDWR | O_APPEND, 0777); commitLog = open("commits.txt", O_CREAT | O_RDWR | O_APPEND, 0777); /* Allocate the worker threads. */ threads = stasis_malloc(numThreads, pthread_t); pthread_attr_init(&attr); pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN); pthread_mutex_init(&hashTableMutex, NULL); for (k = 0; k < numThreads; k++) { pthread_create(&threads[k], &attr, threadFunc, (void*) k); } for (k = 0; k < numThreads; k++) { pthread_join(threads[k], NULL); } /* Close the insert and commit log files. */ close(insertLog); close(commitLog); Tdeinit(); printf("\t\tSubject Process Exiting Normally\n"); fflush(stdout); return 0; }
} END_TEST START_TEST(regions_lockRandomizedTest) { Tinit(); const int NUM_XACTS = 100; const int NUM_OPS = 10000; const int FUDGE = 10; int xids[NUM_XACTS]; pageid_t * xidRegions[NUM_XACTS + FUDGE]; int xidRegionCounts[NUM_XACTS + FUDGE]; int longXid = Tbegin(); time_t seed = time(0); printf("\nSeed = %ld\n", seed); srandom(seed); for(int i = 0; i < NUM_XACTS; i++) { xids[i] = Tbegin(); assert(xids[i] < NUM_XACTS + FUDGE); xidRegions[xids[i]] = stasis_malloc(NUM_OPS, pageid_t); xidRegionCounts[xids[i]] = 0; } int activeXacts = NUM_XACTS; for(int i = 0; i < NUM_OPS; i++) { pageid_t j; if(!(i % (NUM_OPS/NUM_XACTS))) { // abort or commit one transaction randomly. activeXacts --; j = stasis_util_random64(activeXacts); if(stasis_util_random64(2)) { Tcommit(xids[j]); } else { Tabort(xids[j]); } if(activeXacts == 0) { break; } for(; j < activeXacts; j++) { xids[j] = xids[j+1]; } fsckRegions(longXid); } j = stasis_util_random64(activeXacts); if(stasis_util_random64(2)) { // alloc xidRegions[xids[j]][xidRegionCounts[xids[j]]] = TregionAlloc(xids[j], stasis_util_random64(100), 0); xidRegionCounts[xids[j]]++; } else { // free if(xidRegionCounts[xids[j]]) { pageid_t k = stasis_util_random64(xidRegionCounts[xids[j]]); TregionDealloc(xids[j], xidRegions[xids[j]][k]); xidRegionCounts[xids[j]]--; for(; k < xidRegionCounts[xids[j]]; k++) { xidRegions[xids[j]][k] = xidRegions[xids[j]][k+1]; } } } } for(int i = 0; i < activeXacts; i++) { Tabort(i); fsckRegions(longXid); } Tcommit(longXid); Tdeinit(); } END_TEST
END_TEST START_TEST(regions_randomizedTest) { Tinit(); time_t seed = time(0); printf("Seed = %ld: ", seed); srandom(seed); int xid = Tbegin(); pageid_t pagesAlloced = 0; pageid_t regionsAlloced = 0; double max_blowup = 0; pageid_t max_region_count = 0; pageid_t max_waste = 0; pageid_t max_size = 0; pageid_t max_ideal_size = 0; for(int i = 0; i < 10000; i++) { if(!(i % 100)) { Tcommit(xid); xid = Tbegin(); } if(!(i % 100)) { fsckRegions(xid); } if(stasis_util_random64(2)) { unsigned int size = stasis_util_random64(100); TregionAlloc(xid, size, 0); pagesAlloced += size; regionsAlloced ++; } else { if(regionsAlloced) { pageid_t victim = stasis_util_random64(regionsAlloced); pageid_t victimSize; pageid_t victimPage; TregionFindNthActive(xid, victim, &victimPage, &victimSize); TregionDealloc(xid, victimPage); pagesAlloced -= victimSize; regionsAlloced --; } else { i--; } } if(regionsAlloced) { pageid_t lastRegionStart; pageid_t lastRegionSize; TregionFindNthActive(xid, regionsAlloced-1, &lastRegionStart, &lastRegionSize); pageid_t length = lastRegionStart + lastRegionSize+1; pageid_t ideal = pagesAlloced + regionsAlloced + 1; double blowup = (double)length/(double)ideal; unsigned long long bytes_wasted = length - ideal; // printf("Region count = %d, blowup = %d / %d = %5.2f\n", regionsAlloced, length, ideal, blowup); if(max_blowup < blowup) { max_blowup = blowup; } if(max_waste < bytes_wasted) { max_waste = bytes_wasted; } if(max_size < length) { max_size = length; } if(max_ideal_size < ideal) { max_ideal_size = ideal; } if(max_region_count < regionsAlloced) { max_region_count = regionsAlloced; } } } fsckRegions(xid); Tcommit(xid); Tdeinit(); printf("Max # of regions = %lld, page file size = %5.2fM, ideal page file size = %5.2fM, (blowup = %5.2f)\n", //peak bytes wasted = %5.2fM, blowup = %3.2f\n", max_region_count, ((double)max_size * PAGE_SIZE)/(1024.0*1024.0), ((double)max_ideal_size * PAGE_SIZE)/(1024.0*1024.0), (double)max_size/(double)max_ideal_size); // ((double)max_waste * PAGE_SIZE)/(1024.0*1024.0), // max_blowup); if((double)max_size/(double)max_ideal_size > 5) { // max_blowup isn't what we want here; it measures the peak // percentage of the file that is unused. Instead, we want to // measure the actual and ideal page file sizes for this run. printf("ERROR: Excessive blowup (max allowable is 5)\n"); abort(); } } END_TEST
void bLSM::deinit_stasis() { Tdeinit(); }
} END_TEST START_TEST(pagedListCheck) { Tinit(); int xid = Tbegin(); recordid list = TpagedListAlloc(xid); int a; recordid b; int i; printf("\n"); for(i = 0; i < NUM_ENTRIES; i++) { if(!(i % (NUM_ENTRIES/10))) { printf("."); fflush(stdout); } a = i; b.page = i+1; b.slot = i+2; b.size = i+3; int ret; { byte * t; ret = TpagedListFind(xid, list, (byte*)&a, sizeof(int), &t); assert(-1 == ret); } ret = TpagedListInsert(xid, list, (byte*)&a, sizeof(int), (byte*)&b, sizeof(recordid)); assert(!ret); recordid * bb; recordid ** bbb = &bb; ret = TpagedListFind(xid, list, (byte*)&a, sizeof(int), (byte**)bbb); assert(ret == sizeof(recordid)); assert(!memcmp(bb, &b, sizeof(recordid))); } Tcommit(xid); printf("\n"); xid = Tbegin(); for(i = 0; i < NUM_ENTRIES; i++ ) { if(!(i % (NUM_ENTRIES/10))) { printf("."); fflush(stdout); } a = i; b.page = i+1; b.slot = i+2; b.size = i+3; recordid * bb; recordid ** bbb = &bb; int ret = TpagedListFind(xid, list, (byte*)&a, sizeof(int), (byte**)bbb); assert(ret == sizeof(recordid)); assert(!memcmp(bb, &b, sizeof(recordid))); if(!(i % 10)) { ret = TpagedListRemove(xid, list, (byte*)&a, sizeof(int)); assert(ret); free(bb); bb = 0; ret = TpagedListFind(xid, list, (byte*)&a, sizeof(int), (byte**)bbb); assert(-1==ret); assert(!bb); } } Tabort(xid); xid = Tbegin(); printf("\n"); for(i = 0; i < NUM_ENTRIES; i++) { if(!(i % (NUM_ENTRIES/10))) { printf("."); fflush(stdout); } a = i; b.page = i+1; b.slot = i+2; b.size = i+3; recordid * bb; recordid ** bbb = &bb; int ret = TpagedListFind(xid, list, (byte*)&a, sizeof(int), (byte**)bbb); assert(ret == sizeof(recordid)); assert(!memcmp(bb, &b, sizeof(recordid))); } byte * seen = stasis_calloc(NUM_ENTRIES, byte); lladd_pagedList_iterator * it = TpagedListIterator(xid, list); int keySize; int valueSize; int * key = 0; int ** bkey = &key; recordid * value = 0; recordid ** bvalue = &value; while(TpagedListNext(xid, it, (byte**)bkey, &keySize, (byte**)bvalue, &valueSize)) { assert(!seen[*key]); seen[*key] = 1; assert(value->page == *key+1); assert(value->slot == *key+2); assert(value->size == *key+3); free(key); free(value); key = 0; value = 0; } for(i = 0; i < NUM_ENTRIES; i++) { assert(seen[i] == 1); } Tcommit(xid); Tdeinit(); } END_TEST
int main(int argc, char** argv) { assert(argc == 4); int thread_count = atoi(argv[1]) ; // count = atoi(argv[2]); thread_requests_per_sec = (double)(atoi(argv[2])); count = 10.0 * thread_requests_per_sec; alwaysCommit = atoi(argv[3]); printf("%d %f\n", thread_count, thread_requests_per_sec); /* unlink("storefile.txt"); unlink("logfile.txt"); unlink("blob0_file.txt"); unlink("blob1_file.txt"); */ int l; for(l = 0; l < COUNTER_RESOLUTION; l++) { buckets[l] = 0; } pthread_t * workers = stasis_malloc(thread_count, pthread_t); Tinit(); int xid = Tbegin(); hash = ThashCreate(xid, sizeof(int), sizeof(int)); Tcommit(xid); int k; /* threads have static thread sizes. Ughh. */ pthread_attr_t attr; pthread_attr_init(&attr); pthread_mutex_init(&mutex, NULL); pthread_cond_init(&never, NULL); pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN); // pthread_attr_setschedpolicy(&attr, SCHED_FIFO); pthread_mutex_lock(&mutex); for(k = 0; k < thread_count; k++) { int * k_copy = stasis_alloc(int); *k_copy = k ; pthread_create(&workers[k], &attr, go, k_copy); } pthread_mutex_unlock(&mutex); for(k = 0; k < thread_count; k++) { pthread_join(workers[k],NULL); } double log_multiplier = (COUNTER_RESOLUTION / log(MAX_SECONDS * 1000000000.0)); int total = 0; for(k = 0; k < COUNTER_RESOLUTION; k++) { printf("%3.4f\t%d\n", exp(((double)k)/log_multiplier)/1000000000.0, buckets[k]); total += buckets[k]; } printf("Total requests %d\n", total); /* printf("mean: (max, avg) %f, %f\n", max_mean, avg_mean / (double)thread_count); printf("variance: (max, avg) %f, %f\n", max_var, avg_var / (double)thread_count); */ Tdeinit(); }