/** * @brief TEST_CASE - Confirms that duplicate entries are disallowed when the skiplist is a set. */ static int duplicate_entries_disallowed( void ) { unsigned int i; skiplist_node_t *iter; skiplist_t *skiplist; skiplist = skiplist_create( SKIPLIST_PROPERTY_UNIQUE, 5, int_compare, int_fprintf, NULL ); if( !skiplist ) return -1; for( i = 0; i < 2; ++i ) { unsigned int j; for( j = 0; j < 5; ++j ) { if( skiplist_insert( skiplist, j ) ) return -1; if( skiplist_size( skiplist, NULL ) != (i ? 5 : j+1) ) return -1; } } for( i = 0; i < 5; ++i ) if( !skiplist_contains( skiplist, i, NULL ) ) return -1; for( i = 0, iter = skiplist_begin( skiplist ); iter != skiplist_end(); iter = skiplist_next( iter ), ++i ) if( skiplist_node_value( iter, NULL ) != i ) return -1; if( skiplist_fprintf_filename( "duplicate_entries_disallowed.dot", skiplist ) ) return -1; return 0; }
static void test_delete() { int i; int64_t start_time; int64_t end_time; void *value; start_time = get_current_time_ms(); for (i=0; i<COUNT; i++) { assert(skiplist_delete(&sl, numbers + i) == 0); } assert(instance_count == 0); end_time = get_current_time_ms(); printf("delete time used: %"PRId64" ms\n", end_time - start_time); start_time = get_current_time_ms(); for (i=0; i<COUNT; i++) { value = skiplist_find(&sl, numbers + i); assert(value == NULL); } end_time = get_current_time_ms(); printf("find after delete time used: %"PRId64" ms\n", end_time - start_time); i = 0; skiplist_iterator(&sl, &iterator); while ((value=skiplist_next(&iterator)) != NULL) { i++; } assert(i==0); }
/** * @brief TEST_CASE - Sanity test of some key skiplist APIs using integers. */ static int simple( void ) { unsigned int i; skiplist_node_t *iter; skiplist_t *skiplist; skiplist = skiplist_create( SKIPLIST_PROPERTY_NONE, 5, int_compare, int_fprintf, NULL ); if( !skiplist ) return -1; if( skiplist_contains( skiplist, 10, NULL ) ) return -1; if( !skiplist_remove( skiplist, 10 ) ) return -1; for( i = 0; i < 10; ++i ) { if( skiplist_insert( skiplist, i ) ) return -1; if( !skiplist_contains( skiplist, i, NULL ) ) return -1; } for( i = 0; i < 100; ++i ) { unsigned int value = rand(); if( skiplist_insert( skiplist, value ) ) return -1; if( !skiplist_contains( skiplist, value, NULL ) ) return -1; } for( i = 5; i < 10; ++i ) if( skiplist_remove( skiplist, i ) ) return -1; for( iter = skiplist_begin( skiplist ); iter != skiplist_end(); iter = skiplist_next( iter ) ) { uintptr_t value = skiplist_node_value( iter, NULL ); if( value >= 5 && value < 10 ) return -1; } for( i = 0; i < skiplist_size( skiplist, NULL ); ++i ) skiplist_at_index( skiplist, i, NULL ); if( skiplist_fprintf_filename( "simple.dot", skiplist ) ) return -1; skiplist_destroy( skiplist ); return 0; }
/** * @brief TEST_CASE - Confirms incorrect inputs are handled gracefully for skiplist_next. */ static int abuse_skiplist_next( void ) { skiplist_t *skiplist; skiplist = skiplist_create( SKIPLIST_PROPERTY_NONE, 5, int_compare, int_fprintf, NULL ); if( !skiplist ) return -1; if( skiplist_insert( skiplist, 1 ) ) return -1; if( skiplist_next( NULL ) ) return -1; skiplist_destroy( skiplist ); return 0; }
static int test_insert() { int i; int result; int64_t start_time; int64_t end_time; void *value; instance_count = 0; start_time = get_current_time_ms(); for (i=0; i<COUNT; i++) { if ((result=skiplist_insert(&sl, numbers + i)) != 0) { return result; } instance_count++; } assert(instance_count == COUNT); end_time = get_current_time_ms(); printf("insert time used: %"PRId64" ms\n", end_time - start_time); start_time = get_current_time_ms(); for (i=0; i<COUNT; i++) { value = skiplist_find(&sl, numbers + i); assert(value != NULL && *((int *)value) == numbers[i]); } end_time = get_current_time_ms(); printf("find time used: %"PRId64" ms\n", end_time - start_time); start_time = get_current_time_ms(); i = 0; skiplist_iterator(&sl, &iterator); while ((value=skiplist_next(&iterator)) != NULL) { i++; assert(i == *((int *)value)); } assert(i==COUNT); end_time = get_current_time_ms(); printf("iterator time used: %"PRId64" ms\n", end_time - start_time); return 0; }
/** * @brief TEST_CASE - Sanity test of some key skiplist APIs using a pointer to data items. */ static int pointers( void ) { skiplist_t *skiplist; const coord_t coords[] = { /* Simple in order insertion. */ {5,5}, {7,5}, /* Duplicate x with increasing y. */ {5,6}, {5,8}, /* Duplicate x with decreasing y. */ {7,4}, {7,0}, /* Decreasing x. */ {4,5}, {3,5}, /* Increasing x. */ {9,0}, {10,0}, /* Duplicate values. */ {9,0}, {5,5}, /* Zero. */ {0,0}, /* Huge. */ {UINT_MAX,UINT_MAX} }; unsigned int i; skiplist_node_t *iter; coord_t tmp; skiplist = skiplist_create( SKIPLIST_PROPERTY_NONE, 8, coord_compare, coord_fprintf, NULL ); if( !skiplist ) return -1; for( i = 0; i < sizeof(coords) / sizeof(coords[0]); ++i ) if( skiplist_insert( skiplist, (uintptr_t) &coords[i] ) ) return -1; /* Output skiplist for debugging purposes. */ if( skiplist_fprintf_filename( "pointers.dot", skiplist ) ) return -1; /* Confirm skiplist is in the correct order. */ tmp.x = 0; tmp.y = 0; for( iter = skiplist_begin( skiplist ); iter != skiplist_end(); iter = skiplist_next( iter ) ) { coord_t *cur = (coord_t *)skiplist_node_value( iter, NULL ); if( cur->x < tmp.x ) return -1; if( cur->x == tmp.x && cur->y < tmp.y ) return -1; tmp = *cur; } /* Confirm the skiplist contains what we expect. */ for( i = 0; i < sizeof(coords) / sizeof(coords[0]); ++i ) if( !skiplist_contains( skiplist, (uintptr_t) &coords[i], NULL ) ) return -1; /* If we use a different pointer to point to the same values the skiplist should skill contain it. */ tmp = coords[0]; if( !skiplist_contains( skiplist, (uintptr_t) &tmp, NULL ) ) return -1; /* Free resources. */ skiplist_destroy( skiplist ); return 0; }
static int test_stable_sort() { #define RECORDS 32 int i; int result; int index1; int index2; int delete_count; int total_delete_count; Skiplist sl; SkiplistIterator iterator; Record records[RECORDS]; Record *record; Record target; void *value; instance_count = 0; result = skiplist_init_ex(&sl, 12, compare_record, free_test_func, 128, skiplist_type); if (result != 0) { return result; } for (i=0; i<RECORDS; i++) { records[i].line = i + 1; records[i].key = i + 1; } for (i=0; i<RECORDS/4; i++) { index1 = (RECORDS - 1) * (int64_t)rand() / (int64_t)RAND_MAX; index2 = RECORDS - 1 - index1; if (index1 != index2) { records[index1].key = records[index2].key; } } for (i=0; i<RECORDS; i++) { if ((result=skiplist_insert(&sl, records + i)) != 0) { return result; } instance_count++; } assert(instance_count == RECORDS); for (i=0; i<RECORDS; i++) { value = skiplist_find(&sl, records + i); assert(value != NULL && ((Record *)value)->key == records[i].key); } i = 0; skiplist_iterator(&sl, &iterator); while ((value=skiplist_next(&iterator)) != NULL) { i++; record = (Record *)value; printf("%d => #%d\n", record->key, record->line); } assert(i==RECORDS); target.key = 10; target.line = 0; if (skiplist_find_all(&sl, &target, &iterator) == 0) { printf("found key: %d\n", target.key); } i = 0; while ((value=skiplist_next(&iterator)) != NULL) { i++; record = (Record *)value; printf("%d => #%d\n", record->key, record->line); } printf("found record count: %d\n", i); total_delete_count = 0; for (i=0; i<RECORDS; i++) { if ((result=skiplist_delete_all(&sl, records + i, &delete_count)) == 0) { total_delete_count += delete_count; } assert((result == 0 && delete_count > 0) || (result != 0 && delete_count == 0)); } assert(total_delete_count == RECORDS); assert(instance_count == 0); i = 0; skiplist_iterator(&sl, &iterator); while ((value=skiplist_next(&iterator)) != NULL) { i++; } assert(i == 0); skiplist_destroy(&sl); assert(instance_count == 0); return 0; }