/* drmsl.c -- Skip list test
 * Created: Mon May 10 09:28:13 1999 by faith@precisioninsight.com
 *
 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
 * All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 * Authors: Rickard E. (Rik) Faith <faith@valinux.com>
 *
 * DESCRIPTION
 *
 * This file contains a straightforward skip list implementation.n
 *
 * FUTURE ENHANCEMENTS
 *
 * REFERENCES
 *
 * [Pugh90] William Pugh.  Skip Lists: A Probabilistic Alternative to
 * Balanced Trees. CACM 33(6), June 1990, pp. 668-676.
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>

#include "xf86drm.h"

static void print(void* list)
{
    unsigned long key;
    void          *value;

    if (drmSLFirst(list, &key, &value)) {
	do {
	    printf("key = %5lu, value = %p\n", key, value);
	} while (drmSLNext(list, &key, &value));
    }
}

static double do_time(int size, int iter)
{
    void           *list;
    int            i, j;
    unsigned long  keys[1000000];
    unsigned long  previous;
    unsigned long  key;
    void           *value;
    struct timeval start, stop;
    double         usec;
    void           *ranstate;

    list = drmSLCreate();
    ranstate = drmRandomCreate(12345);

    for (i = 0; i < size; i++) {
	keys[i] = drmRandom(ranstate);
	drmSLInsert(list, keys[i], NULL);
    }

    previous = 0;
    if (drmSLFirst(list, &key, &value)) {
	do {
	    if (key <= previous) {
		printf( "%lu !< %lu\n", previous, key);
	    }
	    previous = key;
	} while (drmSLNext(list, &key, &value));
    }

    gettimeofday(&start, NULL);
    for (j = 0; j < iter; j++) {
	for (i = 0; i < size; i++) {
	    if (drmSLLookup(list, keys[i], &value))
		printf("Error %lu %d\n", keys[i], i);
	}
    }
    gettimeofday(&stop, NULL);

    usec = (double)(stop.tv_sec * 1000000 + stop.tv_usec
		    - start.tv_sec * 1000000 - start.tv_usec) / (size * iter);

    printf("%0.2f microseconds for list length %d\n", usec, size);

    drmRandomDouble(ranstate);
    drmSLDestroy(list);

    return usec;
}

static void print_neighbors(void *list, unsigned long key)
{
    unsigned long prev_key = 0;
    unsigned long next_key = 0;
    void          *prev_value;
    void          *next_value;
    int           retval;

    retval = drmSLLookupNeighbors(list, key,
				  &prev_key, &prev_value,
				  &next_key, &next_value);
    printf("Neighbors of %5lu: %d %5lu %5lu\n",
	   key, retval, prev_key, next_key);
}

int main(void)
{
    void*    list;
    double   usec, usec2, usec3, usec4;

    list = drmSLCreate();
    printf( "list at %p\n", list);

    print(list);
    printf("\n==============================\n\n");

    drmSLInsert(list, 123, NULL);
    drmSLInsert(list, 213, NULL);
    drmSLInsert(list, 50, NULL);
    print(list);
    printf("\n==============================\n\n");

    print_neighbors(list, 0);
    print_neighbors(list, 50);
    print_neighbors(list, 51);
    print_neighbors(list, 123);
    print_neighbors(list, 200);
    print_neighbors(list, 213);
    print_neighbors(list, 256);
    printf("\n==============================\n\n");

    drmSLDelete(list, 50);
    print(list);
    printf("\n==============================\n\n");

    drmSLDump(list);
    drmSLDestroy(list);
    printf("\n==============================\n\n");

    usec  = do_time(100, 10000);
    usec2 = do_time(1000, 500);
    printf("Table size increased by %0.2f, search time increased by %0.2f\n",
	   1000.0/100.0, usec2 / usec);

    usec3 = do_time(10000, 50);
    printf("Table size increased by %0.2f, search time increased by %0.2f\n",
	   10000.0/100.0, usec3 / usec);

    usec4 = do_time(100000, 4);
    printf("Table size increased by %0.2f, search time increased by %0.2f\n",
	   100000.0/100.0, usec4 / usec);

    return 0;
}
