1d722e3fbSopenharmony_ci/* drmsl.c -- Skip list test 2d722e3fbSopenharmony_ci * Created: Mon May 10 09:28:13 1999 by faith@precisioninsight.com 3d722e3fbSopenharmony_ci * 4d722e3fbSopenharmony_ci * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. 5d722e3fbSopenharmony_ci * All Rights Reserved. 6d722e3fbSopenharmony_ci * 7d722e3fbSopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 8d722e3fbSopenharmony_ci * copy of this software and associated documentation files (the "Software"), 9d722e3fbSopenharmony_ci * to deal in the Software without restriction, including without limitation 10d722e3fbSopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11d722e3fbSopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 12d722e3fbSopenharmony_ci * Software is furnished to do so, subject to the following conditions: 13d722e3fbSopenharmony_ci * 14d722e3fbSopenharmony_ci * The above copyright notice and this permission notice (including the next 15d722e3fbSopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 16d722e3fbSopenharmony_ci * Software. 17d722e3fbSopenharmony_ci * 18d722e3fbSopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19d722e3fbSopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20d722e3fbSopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21d722e3fbSopenharmony_ci * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 22d722e3fbSopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 23d722e3fbSopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24d722e3fbSopenharmony_ci * DEALINGS IN THE SOFTWARE. 25d722e3fbSopenharmony_ci * 26d722e3fbSopenharmony_ci * Authors: Rickard E. (Rik) Faith <faith@valinux.com> 27d722e3fbSopenharmony_ci * 28d722e3fbSopenharmony_ci * DESCRIPTION 29d722e3fbSopenharmony_ci * 30d722e3fbSopenharmony_ci * This file contains a straightforward skip list implementation.n 31d722e3fbSopenharmony_ci * 32d722e3fbSopenharmony_ci * FUTURE ENHANCEMENTS 33d722e3fbSopenharmony_ci * 34d722e3fbSopenharmony_ci * REFERENCES 35d722e3fbSopenharmony_ci * 36d722e3fbSopenharmony_ci * [Pugh90] William Pugh. Skip Lists: A Probabilistic Alternative to 37d722e3fbSopenharmony_ci * Balanced Trees. CACM 33(6), June 1990, pp. 668-676. 38d722e3fbSopenharmony_ci * 39d722e3fbSopenharmony_ci */ 40d722e3fbSopenharmony_ci 41d722e3fbSopenharmony_ci#include <stdio.h> 42d722e3fbSopenharmony_ci#include <stdlib.h> 43d722e3fbSopenharmony_ci#include <sys/time.h> 44d722e3fbSopenharmony_ci 45d722e3fbSopenharmony_ci#include "xf86drm.h" 46d722e3fbSopenharmony_ci 47d722e3fbSopenharmony_cistatic void print(void* list) 48d722e3fbSopenharmony_ci{ 49d722e3fbSopenharmony_ci unsigned long key; 50d722e3fbSopenharmony_ci void *value; 51d722e3fbSopenharmony_ci 52d722e3fbSopenharmony_ci if (drmSLFirst(list, &key, &value)) { 53d722e3fbSopenharmony_ci do { 54d722e3fbSopenharmony_ci printf("key = %5lu, value = %p\n", key, value); 55d722e3fbSopenharmony_ci } while (drmSLNext(list, &key, &value)); 56d722e3fbSopenharmony_ci } 57d722e3fbSopenharmony_ci} 58d722e3fbSopenharmony_ci 59d722e3fbSopenharmony_cistatic double do_time(int size, int iter) 60d722e3fbSopenharmony_ci{ 61d722e3fbSopenharmony_ci void *list; 62d722e3fbSopenharmony_ci int i, j; 63d722e3fbSopenharmony_ci unsigned long keys[1000000]; 64d722e3fbSopenharmony_ci unsigned long previous; 65d722e3fbSopenharmony_ci unsigned long key; 66d722e3fbSopenharmony_ci void *value; 67d722e3fbSopenharmony_ci struct timeval start, stop; 68d722e3fbSopenharmony_ci double usec; 69d722e3fbSopenharmony_ci void *ranstate; 70d722e3fbSopenharmony_ci 71d722e3fbSopenharmony_ci list = drmSLCreate(); 72d722e3fbSopenharmony_ci ranstate = drmRandomCreate(12345); 73d722e3fbSopenharmony_ci 74d722e3fbSopenharmony_ci for (i = 0; i < size; i++) { 75d722e3fbSopenharmony_ci keys[i] = drmRandom(ranstate); 76d722e3fbSopenharmony_ci drmSLInsert(list, keys[i], NULL); 77d722e3fbSopenharmony_ci } 78d722e3fbSopenharmony_ci 79d722e3fbSopenharmony_ci previous = 0; 80d722e3fbSopenharmony_ci if (drmSLFirst(list, &key, &value)) { 81d722e3fbSopenharmony_ci do { 82d722e3fbSopenharmony_ci if (key <= previous) { 83d722e3fbSopenharmony_ci printf( "%lu !< %lu\n", previous, key); 84d722e3fbSopenharmony_ci } 85d722e3fbSopenharmony_ci previous = key; 86d722e3fbSopenharmony_ci } while (drmSLNext(list, &key, &value)); 87d722e3fbSopenharmony_ci } 88d722e3fbSopenharmony_ci 89d722e3fbSopenharmony_ci gettimeofday(&start, NULL); 90d722e3fbSopenharmony_ci for (j = 0; j < iter; j++) { 91d722e3fbSopenharmony_ci for (i = 0; i < size; i++) { 92d722e3fbSopenharmony_ci if (drmSLLookup(list, keys[i], &value)) 93d722e3fbSopenharmony_ci printf("Error %lu %d\n", keys[i], i); 94d722e3fbSopenharmony_ci } 95d722e3fbSopenharmony_ci } 96d722e3fbSopenharmony_ci gettimeofday(&stop, NULL); 97d722e3fbSopenharmony_ci 98d722e3fbSopenharmony_ci usec = (double)(stop.tv_sec * 1000000 + stop.tv_usec 99d722e3fbSopenharmony_ci - start.tv_sec * 1000000 - start.tv_usec) / (size * iter); 100d722e3fbSopenharmony_ci 101d722e3fbSopenharmony_ci printf("%0.2f microseconds for list length %d\n", usec, size); 102d722e3fbSopenharmony_ci 103d722e3fbSopenharmony_ci drmRandomDouble(ranstate); 104d722e3fbSopenharmony_ci drmSLDestroy(list); 105d722e3fbSopenharmony_ci 106d722e3fbSopenharmony_ci return usec; 107d722e3fbSopenharmony_ci} 108d722e3fbSopenharmony_ci 109d722e3fbSopenharmony_cistatic void print_neighbors(void *list, unsigned long key, 110d722e3fbSopenharmony_ci unsigned long expected_prev, 111d722e3fbSopenharmony_ci unsigned long expected_next) 112d722e3fbSopenharmony_ci{ 113d722e3fbSopenharmony_ci unsigned long prev_key = 0; 114d722e3fbSopenharmony_ci unsigned long next_key = 0; 115d722e3fbSopenharmony_ci void *prev_value; 116d722e3fbSopenharmony_ci void *next_value; 117d722e3fbSopenharmony_ci int retval; 118d722e3fbSopenharmony_ci 119d722e3fbSopenharmony_ci retval = drmSLLookupNeighbors(list, key, 120d722e3fbSopenharmony_ci &prev_key, &prev_value, 121d722e3fbSopenharmony_ci &next_key, &next_value); 122d722e3fbSopenharmony_ci printf("Neighbors of %5lu: %d %5lu %5lu\n", 123d722e3fbSopenharmony_ci key, retval, prev_key, next_key); 124d722e3fbSopenharmony_ci if (prev_key != expected_prev) { 125d722e3fbSopenharmony_ci fprintf(stderr, "Unexpected neighbor: %5lu. Expected: %5lu\n", 126d722e3fbSopenharmony_ci prev_key, expected_prev); 127d722e3fbSopenharmony_ci exit(1); 128d722e3fbSopenharmony_ci } 129d722e3fbSopenharmony_ci if (next_key != expected_next) { 130d722e3fbSopenharmony_ci fprintf(stderr, "Unexpected neighbor: %5lu. Expected: %5lu\n", 131d722e3fbSopenharmony_ci next_key, expected_next); 132d722e3fbSopenharmony_ci exit(1); 133d722e3fbSopenharmony_ci } 134d722e3fbSopenharmony_ci} 135d722e3fbSopenharmony_ci 136d722e3fbSopenharmony_ciint main(void) 137d722e3fbSopenharmony_ci{ 138d722e3fbSopenharmony_ci void* list; 139d722e3fbSopenharmony_ci double usec, usec2, usec3, usec4; 140d722e3fbSopenharmony_ci 141d722e3fbSopenharmony_ci list = drmSLCreate(); 142d722e3fbSopenharmony_ci printf( "list at %p\n", list); 143d722e3fbSopenharmony_ci 144d722e3fbSopenharmony_ci print(list); 145d722e3fbSopenharmony_ci printf("\n==============================\n\n"); 146d722e3fbSopenharmony_ci 147d722e3fbSopenharmony_ci drmSLInsert(list, 123, NULL); 148d722e3fbSopenharmony_ci drmSLInsert(list, 213, NULL); 149d722e3fbSopenharmony_ci drmSLInsert(list, 50, NULL); 150d722e3fbSopenharmony_ci print(list); 151d722e3fbSopenharmony_ci printf("\n==============================\n\n"); 152d722e3fbSopenharmony_ci 153d722e3fbSopenharmony_ci print_neighbors(list, 0, 0, 50); 154d722e3fbSopenharmony_ci print_neighbors(list, 50, 0, 50); 155d722e3fbSopenharmony_ci print_neighbors(list, 51, 50, 123); 156d722e3fbSopenharmony_ci print_neighbors(list, 123, 50, 123); 157d722e3fbSopenharmony_ci print_neighbors(list, 200, 123, 213); 158d722e3fbSopenharmony_ci print_neighbors(list, 213, 123, 213); 159d722e3fbSopenharmony_ci print_neighbors(list, 256, 213, 256); 160d722e3fbSopenharmony_ci printf("\n==============================\n\n"); 161d722e3fbSopenharmony_ci 162d722e3fbSopenharmony_ci drmSLDelete(list, 50); 163d722e3fbSopenharmony_ci print(list); 164d722e3fbSopenharmony_ci printf("\n==============================\n\n"); 165d722e3fbSopenharmony_ci 166d722e3fbSopenharmony_ci drmSLDump(list); 167d722e3fbSopenharmony_ci drmSLDestroy(list); 168d722e3fbSopenharmony_ci printf("\n==============================\n\n"); 169d722e3fbSopenharmony_ci 170d722e3fbSopenharmony_ci usec = do_time(100, 10000); 171d722e3fbSopenharmony_ci usec2 = do_time(1000, 500); 172d722e3fbSopenharmony_ci printf("Table size increased by %0.2f, search time increased by %0.2f\n", 173d722e3fbSopenharmony_ci 1000.0/100.0, usec2 / usec); 174d722e3fbSopenharmony_ci 175d722e3fbSopenharmony_ci usec3 = do_time(10000, 50); 176d722e3fbSopenharmony_ci printf("Table size increased by %0.2f, search time increased by %0.2f\n", 177d722e3fbSopenharmony_ci 10000.0/100.0, usec3 / usec); 178d722e3fbSopenharmony_ci 179d722e3fbSopenharmony_ci usec4 = do_time(100000, 4); 180d722e3fbSopenharmony_ci printf("Table size increased by %0.2f, search time increased by %0.2f\n", 181d722e3fbSopenharmony_ci 100000.0/100.0, usec4 / usec); 182d722e3fbSopenharmony_ci 183d722e3fbSopenharmony_ci return 0; 184d722e3fbSopenharmony_ci} 185