Return a random entry from the hash table. Useful to * implement randomized algorithms */
| 635 | /* Return a random entry from the hash table. Useful to |
| 636 | * implement randomized algorithms */ |
| 637 | dictEntry *dictGetRandomKey(dict *d) |
| 638 | { |
| 639 | dictEntry *he, *orighe; |
| 640 | unsigned long h; |
| 641 | int listlen, listele; |
| 642 | |
| 643 | if (dictSize(d) == 0) return NULL; |
| 644 | if (dictIsRehashing(d)) _dictRehashStep(d); |
| 645 | if (dictIsRehashing(d)) { |
| 646 | do { |
| 647 | /* We are sure there are no elements in indexes from 0 |
| 648 | * to rehashidx-1 */ |
| 649 | h = d->rehashidx + (randomULong() % (dictSlots(d) - d->rehashidx)); |
| 650 | he = (h >= d->ht[0].size) ? d->ht[1].table[h - d->ht[0].size] : |
| 651 | d->ht[0].table[h]; |
| 652 | } while(he == NULL); |
| 653 | } else { |
| 654 | do { |
| 655 | h = randomULong() & d->ht[0].sizemask; |
| 656 | he = d->ht[0].table[h]; |
| 657 | } while(he == NULL); |
| 658 | } |
| 659 | |
| 660 | /* Now we found a non empty bucket, but it is a linked |
| 661 | * list and we need to get a random element from the list. |
| 662 | * The only sane way to do so is counting the elements and |
| 663 | * select a random index. */ |
| 664 | listlen = 0; |
| 665 | orighe = he; |
| 666 | while(he) { |
| 667 | he = he->next; |
| 668 | listlen++; |
| 669 | } |
| 670 | listele = random() % listlen; |
| 671 | he = orighe; |
| 672 | while(listele--) he = he->next; |
| 673 | return he; |
| 674 | } |
| 675 | |
| 676 | /* This function samples the dictionary to return a few keys from random |
| 677 | * locations. |
no test coverage detected