drmsl.c 5.2 KB

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