Example #1
0
/**
 * @brief TEST_CASE - Confirms incorrect inputs are handled gracefully for skiplist_create.
 */
static int abuse_skiplist_create( void )
{
	unsigned int i;
	skiplist_t *skiplist;
	const unsigned int bad_sizes[] = {0, SKIPLIST_MAX_LINKS + 1, UINT_MAX};

	/* Bad property */
	skiplist = skiplist_create( 0xffff, 5, int_compare, int_fprintf, NULL );
	if( skiplist )
		return -1;

	/* Bad size estimates */
	for( i = 0; i < NELEMS( bad_sizes ); ++i )
	{
		skiplist = skiplist_create( SKIPLIST_PROPERTY_NONE, bad_sizes[i],
		                            int_compare, int_fprintf, NULL );
		if( skiplist )
			return -1;
	}

	/* Bad compare */
	skiplist = skiplist_create( SKIPLIST_PROPERTY_NONE, SKIPLIST_MAX_LINKS,
	                            NULL, int_fprintf, NULL );
	if( skiplist )
		return -1;

	/* Bad print */
	skiplist = skiplist_create( SKIPLIST_PROPERTY_NONE, SKIPLIST_MAX_LINKS,
	                            int_compare, NULL, NULL );
	if( skiplist )
		return -1;

	return 0;
}
Example #2
0
/**
 * @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;
}
Example #3
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;
}
Example #4
0
int main() {
    struct skiplist *s;
    struct node *p;
    int i,level;

    s = skiplist_create();
    for(i=0; i<20; i++) {
        skiplist_insert(s,rand()%40);
    }
    print(s);
    return 0;
}
Example #5
0
/**
 * @brief TEST_CASE - Confirms incorrect inputs are handled gracefully for skiplist_fprintf.
 */
static int abuse_skiplist_fprintf( void )
{
	skiplist_t *skiplist;

	skiplist = skiplist_create( SKIPLIST_PROPERTY_NONE, 5, int_compare, int_fprintf, NULL );
	if( !skiplist )
		return -1;

	skiplist_fprintf( NULL, skiplist );
	skiplist_fprintf( stdout, NULL );

	skiplist_destroy( skiplist );
	return 0;
}
Example #6
0
int
main(int argc, char **argv)
{
    ut_init(basename(argv[0]));

    ut_testing("skiplist_create(6, 50, libhl_cmp_keys_int32, free)");
    skiplist_t *skl = skiplist_create(6, 50, libhl_cmp_keys_int32, free);
    if (skl)
        ut_success();
    else
        ut_failure("Can't create a new binomial heap");

    ut_testing("skiplist_insert(0..99)");
    int i;
    for (i = 0; i < 100; i++) { 
        char *val = malloc(4);
        snprintf(val, 4, "%d", i);
        skiplist_insert(skl, &i, sizeof(i), val);
    }
    ut_validate_int(skiplist_count(skl), 100);

    int test_key = 50;
    ut_testing("skiplist_search(50) = \"50\"");
    char *val = skiplist_search(skl, &test_key, sizeof(int));
    ut_validate_string(val, "50");

    
    ut_testing("skiplist_remove(50, &old_value)");
    val = NULL;
    int rc = skiplist_remove(skl, &test_key, sizeof(int), (void **)&val);
    ut_validate_int(rc, 0);

    ut_testing("old_value is \"50\"");
    ut_validate_string(val, "50");
    free(val);

    ut_testing("skiplist_search(50) = NULL");

    val = skiplist_search(skl, &test_key, sizeof(int));
    ut_validate_string(val, NULL);


    skiplist_destroy(skl);

    ut_summary();

    return ut_failed;
}
Example #7
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;
}
Example #8
0
/**
 * @brief TEST_CASE - Confirms incorrect inputs are handled gracefully for skiplist_fprintf_filename.
 */
static int abuse_skiplist_fprintf_filename( void )
{
	skiplist_t *skiplist;

	skiplist = skiplist_create( SKIPLIST_PROPERTY_NONE, 5, int_compare, int_fprintf, NULL );
	if( !skiplist )
		return -1;

	if( !skiplist_fprintf_filename( NULL, skiplist ) )
		return -1;

	if( !skiplist_fprintf_filename( "valid_filname.txt", NULL ) )
		return -1;

	skiplist_destroy( skiplist );
	return 0;
}
Example #9
0
/**
 * @brief TEST_CASE - Measures insertion trade off between number of elements in the list and number of links per node.
 */
static int link_trade_off_insert( void )
{
#define MAX_LINKS (SKIPLIST_MAX_LINKS)
#define INSERTIONS_LOG2 (16)

	struct timespec stamps[INSERTIONS_LOG2 + 2];
	FILE *fp;
	unsigned int links;
	unsigned int i;
	const char *seperator;

	fp = fopen( "link_trade_off_insert.gplot", "w" );
	if( !fp ) return -1;
	fprintf(fp, "set term qt\n");
	fprintf(fp, "set key off\n");
	fprintf(fp, "set logscale\n");
	fprintf(fp, "set grid xtics ytics mxtics mytics\n");
	fprintf(fp, "set style textbox opaque noborder\n");
	fprintf(fp, "set title \"Average Insertion Time for Skiplists with Varying Link Counts\"\n");
	fprintf(fp, "set xlabel \"Number of Elements in the Skiplist\"\n");
	fprintf(fp, "set ylabel \"Average Time for One Insertion (ns)\"\n");
	fprintf(fp, "plot " );
	seperator = "";
	for( i = 0; i < MAX_LINKS; ++i )
	{
		fprintf(fp, "%s\"link_trade_off_insert_%u.dat\" using 1:2 with lines lt -1,"
		        "\"\" using 1:2:($0*0+%u) with labels center boxed notitle",
		        seperator, i + 1, i + 1);
		seperator = ",\\\n\t";
	}
	fprintf(fp, "\n");
	fprintf(fp, "pause -1\n");
	fclose( fp );

	for( links = MAX_LINKS; links > 0; --links )
	{
		skiplist_t *skiplist;
		char filename[64];
		unsigned int next;

		sprintf( filename, "link_trade_off_insert_%u.dat", links );
		fp = fopen( filename, "w" );
		if( !fp ) return -1;

		skiplist = skiplist_create( SKIPLIST_PROPERTY_NONE, links, int_compare, int_fprintf, NULL );
		if( !skiplist ) return -1;

		next = 0;
		for( i = 0; i < (1 << INSERTIONS_LOG2); ++i )
		{
			/* Sample at powers of 2. */
			if( (i & (i - 1)) == 0 )
			{
				time_stamp( &stamps[next] );

				/* Stop trying if it's taking too long. */
				if( next && time_diff_ns( &stamps[next - 1], &stamps[next] ) > 300000000LLU )
					break;

				++next;
			}

			if( skiplist_insert( skiplist, rand() ) )
				return -1;
		}
		time_stamp( &stamps[next] );
		++next;

		skiplist_destroy( skiplist );

		for( i = 1; i < next; ++i )
		{
			const unsigned int node_count = 1 << (i - 1);
			fprintf(fp, "%u\t%f\n", node_count,
			        time_diff_ns( &stamps[0], &stamps[i] ) / (double)node_count );
		}

		fclose( fp );
	}

#undef MAX_LINKS
#undef INSERTIONS_LOG2
	return 0;
}
Example #10
0
/**
 * @brief TEST_CASE - Measures lookup trade off between number of elements in the list and number of links per node.
 */
static int link_trade_off_lookup( void )
{
#define MAX_LINKS (SKIPLIST_MAX_LINKS)
#define INSERTIONS_LOG2 (16)
	unsigned int i;
	FILE *fp;
	const char *seperator;

	fp = fopen( "link_trade_off_lookup.gplot", "w" );
	if( !fp ) return -1;
	fprintf(fp, "set term qt\n");
	fprintf(fp, "set key off\n");
	fprintf(fp, "set logscale\n");
	fprintf(fp, "set grid xtics ytics mxtics mytics\n");
	fprintf(fp, "set style textbox opaque noborder\n");
	fprintf(fp, "set title \"Average Lookup Time for Skiplists with Varying Link Counts\"\n");
	fprintf(fp, "set xlabel \"Number of Elements in the Skiplist\"\n");
	fprintf(fp, "set ylabel \"Average Time for One Lookup (ns)\"\n");
	fprintf(fp, "plot " );

	seperator = "";
	for( i = 0; i < MAX_LINKS; ++i )
	{
		fprintf(fp, "%s\"link_trade_off_lookup.dat\" using 1:%u with lines lt -1,"
		        "\"\" using 1:%u:($0*0+%u) with labels center boxed notitle",
		        seperator, i + 2, i + 2, i + 1);
		seperator = ",\\\n\t";
	}
	fprintf(fp, "\n");
	fprintf(fp, "pause -1\n");
	fclose( fp );

	fp = fopen( "link_trade_off_lookup.dat", "w" );
	if( !fp ) return -1;

	for( i = 1; i < (1 << INSERTIONS_LOG2); i <<= 1 )
	{
		unsigned int links;
		fprintf( fp, "%u", i );
		for( links = 1; links <= MAX_LINKS; ++links )
		{
			unsigned int j;
			skiplist_t *skiplist;
			struct timespec start, end;

			skiplist = skiplist_create( SKIPLIST_PROPERTY_NONE, links, int_compare, int_fprintf, NULL );
			if( !skiplist ) return -1;

			for( j = 0; j < i; ++j )
				if( skiplist_insert( skiplist, j ) )
					return -1;

			time_stamp( &start );
			for( j = 0; j < i; ++j )
				if( !skiplist_contains( skiplist, j, NULL ) )
					return -1;
			time_stamp( &end );
			fprintf( fp, "\t%f", time_diff_ns( &start, &end ) / (double)i );
			skiplist_destroy( skiplist );
		}
		fprintf( fp, "\n" );
	}

	fclose( fp );

#undef MAX_LINKS
#undef INSERTIONS_LOG2
	return 0;
}
Example #11
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 __init skiplist_init(void)
{
	int i;
	struct timeval start, end;
	struct skiplist *list;
	struct skipnode *node;
	int res = 0;

	int *key = kmalloc(N * sizeof(int), GFP_KERNEL);
	if (key == NULL) {
		printk("-ENOMEM\n");
		return -1;
	}

	printk("Starting initialization...\n");
	list = skiplist_create();
        if (list == NULL) {
		printk("-ENOMEM\n");
		return -1;
        }

	printk("Started initialization...\n");
        printk("Test start!\n");

	/* Test 01 */ 
	printk("Test 01: adding and search %d nodes testing!\n", N);
        printk("Add %d nodes...\n", N);

        do_gettimeofday(&start);
        for (i = 0; i < N; i++) {
                int value = key[i] = i;
               	skiplist_insert(list, key[i], value);
        }
        do_gettimeofday(&end);
        printk("time span:% ldms\n", (end.tv_sec - start.tv_sec)*1000 + (end.tv_usec - start.tv_usec)/1000);
#ifdef SKIPLIST_DEBUG
        skiplist_dump(list);
#endif

        /* Search test */
        printk("Now search %d node...\n", N);
        do_gettimeofday(&start);

        for (i = 0; i < N; i++) {
                struct skipnode *node = skiplist_search(list, key[i]);

                if (node != NULL) {
#ifdef SKIPLIST_DEBUG
                        printk("key:%d value:%d\n", node->key, node->value);
#endif
                } else {
                        printk("Not found:%d\n", key[i]);
			res = 1;
			break;
                }
        }
        do_gettimeofday(&end);
        printk("time span:% ldms\n", (end.tv_sec - start.tv_sec)*1000 + (end.tv_usec - start.tv_usec)/1000);
	if (res) {
		printk("Test 01: failed!\n");
		goto out_clean;
	} else {
		printk("Test 01: success!\n");
	}

	/* Test 02 */

	printk("Test 02: search single node (%d/2) testing!\n", N);
	node = skiplist_search(list, N/2);
	if (node && node->value == N/2) {
		printk("Test 02: Success!\n");
	} else {
		printk("Test 02: Failed!\n");
		res = 1;
		goto out_clean;
	}

	/* Test 03 */

	printk("Test 03: remove single node (%d/2) testing!\n", N);
	skiplist_remove(list, N/2);
	node = skiplist_search(list, N/2);
	if (!node) {
		printk("Test 03: Success!\n");
	} else {
		printk("Test 03: Failed (key:%d)!\n", node->key);
		res = 1;
		goto out_clean;
	}

	/* Test 04 */

	printk("Test 04: search single node equal or great than (%d/2) testing!\n", N);
	printk("Test 04: case 1: no equal node (%d/2) \n", N);
	node = skiplist_search_first_eq_big(list, N/2);
	if (!node || node->value != (N/2 + 1)) {
		printk("Test 04: Failed!\n");
		res = 1;
		goto out_clean;
	}

	printk("Test 04: case 2: has equal node (%d/2 + 1) \n", N);
	node = skiplist_search_first_eq_big(list, N/2 + 1);
	if (node && node->value == (N/2 + 1)) {
		printk("Test 04: Success!\n");
	} else {
		printk("Test 04: Failed!\n");
		res = 1;
		goto out_clean;
	}

	/* Test 05 */
	res = 0;
	printk("Test 05: remove all nodes\n");
        for (i = 0; i < N; i++) {
                skiplist_remove(list, key[i]);
        }

        for (i = 0; i < N; i++) {
		node = skiplist_search(list, key[i]);
		if (node) {
			res = 1;
			break;
		}
	}

	if (res)
		printk("Test 05: Failed!\n");
	else
		printk("Test 05: Success!\n");

#ifdef SKIPLIST_DEBUG
        skiplist_dump(list);
#endif

        printk("End of Test.\n");
out_clean:	

        skiplist_destroy(list);

        return 0;
}