rehashing.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. #include "redis.h"
  2. #include "dict.h"
  3. void _redisAssert(char *x, char *y, int l) {
  4. printf("ASSERT: %s %s %d\n",x,y,l);
  5. exit(1);
  6. }
  7. unsigned int dictKeyHash(const void *keyp) {
  8. unsigned long key = (unsigned long)keyp;
  9. key = dictGenHashFunction(&key,sizeof(key));
  10. key += ~(key << 15);
  11. key ^= (key >> 10);
  12. key += (key << 3);
  13. key ^= (key >> 6);
  14. key += ~(key << 11);
  15. key ^= (key >> 16);
  16. return key;
  17. }
  18. int dictKeyCompare(void *privdata, const void *key1, const void *key2) {
  19. unsigned long k1 = (unsigned long)key1;
  20. unsigned long k2 = (unsigned long)key2;
  21. return k1 == k2;
  22. }
  23. dictType dictTypeTest = {
  24. dictKeyHash, /* hash function */
  25. NULL, /* key dup */
  26. NULL, /* val dup */
  27. dictKeyCompare, /* key compare */
  28. NULL, /* key destructor */
  29. NULL /* val destructor */
  30. };
  31. void showBuckets(dictht ht) {
  32. if (ht.table == NULL) {
  33. printf("NULL\n");
  34. } else {
  35. int j;
  36. for (j = 0; j < ht.size; j++) {
  37. printf("%c", ht.table[j] ? '1' : '0');
  38. }
  39. printf("\n");
  40. }
  41. }
  42. void show(dict *d) {
  43. int j;
  44. if (d->rehashidx != -1) {
  45. printf("rhidx: ");
  46. for (j = 0; j < d->rehashidx; j++)
  47. printf(".");
  48. printf("|\n");
  49. }
  50. printf("ht[0]: ");
  51. showBuckets(d->ht[0]);
  52. printf("ht[1]: ");
  53. showBuckets(d->ht[1]);
  54. printf("\n");
  55. }
  56. int sortPointers(const void *a, const void *b) {
  57. unsigned long la, lb;
  58. la = (long) (*((dictEntry**)a));
  59. lb = (long) (*((dictEntry**)b));
  60. return la-lb;
  61. }
  62. void stressGetKeys(dict *d, int times, int *perfect_run, int *approx_run) {
  63. int j;
  64. dictEntry **des = zmalloc(sizeof(dictEntry*)*dictSize(d));
  65. for (j = 0; j < times; j++) {
  66. int requested = rand() % (dictSize(d)+1);
  67. int returned = dictGetSomeKeys(d, des, requested);
  68. int dup = 0;
  69. qsort(des,returned,sizeof(dictEntry*),sortPointers);
  70. if (returned > 1) {
  71. int i;
  72. for (i = 0; i < returned-1; i++) {
  73. if (des[i] == des[i+1]) dup++;
  74. }
  75. }
  76. if (requested == returned && dup == 0) {
  77. (*perfect_run)++;
  78. } else {
  79. (*approx_run)++;
  80. printf("Requested, returned, duplicated: %d %d %d\n",
  81. requested, returned, dup);
  82. }
  83. }
  84. zfree(des);
  85. }
  86. #define MAX1 120
  87. #define MAX2 1000
  88. int main(void) {
  89. dict *d = dictCreate(&dictTypeTest,NULL);
  90. unsigned long i;
  91. srand(time(NULL));
  92. for (i = 0; i < MAX1; i++) {
  93. dictAdd(d,(void*)i,NULL);
  94. show(d);
  95. }
  96. printf("Size: %d\n", (int)dictSize(d));
  97. for (i = 0; i < MAX1; i++) {
  98. dictDelete(d,(void*)i);
  99. dictResize(d);
  100. show(d);
  101. }
  102. dictRelease(d);
  103. d = dictCreate(&dictTypeTest,NULL);
  104. printf("Stress testing dictGetSomeKeys\n");
  105. int perfect_run = 0, approx_run = 0;
  106. for (i = 0; i < MAX2; i++) {
  107. dictAdd(d,(void*)i,NULL);
  108. stressGetKeys(d,100,&perfect_run,&approx_run);
  109. }
  110. for (i = 0; i < MAX2; i++) {
  111. dictDelete(d,(void*)i);
  112. dictResize(d);
  113. stressGetKeys(d,100,&perfect_run,&approx_run);
  114. }
  115. printf("dictGetSomeKey, %d perfect runs, %d approximated runs\n",
  116. perfect_run, approx_run);
  117. dictRelease(d);
  118. printf("TEST PASSED!\n");
  119. return 0;
  120. }