@@ -148,8 +148,6 @@ void hashtableSetResizePolicy(hashtableResizePolicy policy) {
148148#define ENTRIES_PER_BUCKET 7
149149#define BUCKET_BITS_TYPE uint8_t
150150#define BITS_NEEDED_TO_STORE_POS_WITHIN_BUCKET 3
151- /* Iterator table value indicating iteration is complete */
152- #define HASHTABLE_ITER_END_TABLE 2
153151
154152/* Selecting the number of buckets.
155153 *
@@ -1978,11 +1976,17 @@ size_t hashtableScanDefrag(hashtable *ht, size_t cursor, hashtableScanFunction f
19781976 * Call hashtableNext to fetch each entry. You must call hashtableResetIterator
19791977 * when you are done with the iterator.
19801978 */
1979+
1980+ #define HASHTABLE_ITER_UNINITIALIZED -1
1981+ #define HASHTABLE_ITER_PRIMARY_TABLE 0
1982+ #define HASHTABLE_ITER_REHASH_TABLE 1
1983+ #define HASHTABLE_ITER_FINISHED 2
1984+
19811985void hashtableInitIterator (hashtableIterator * iterator , hashtable * ht , uint8_t flags ) {
19821986 iter * iter ;
19831987 iter = iteratorFromOpaque (iterator );
19841988 iter -> hashtable = ht ;
1985- iter -> table = 0 ;
1989+ iter -> table = HASHTABLE_ITER_PRIMARY_TABLE ;
19861990 iter -> index = -1 ;
19871991 iter -> flags = flags ;
19881992}
@@ -1997,7 +2001,7 @@ void hashtableReinitIterator(hashtableIterator *iterator, hashtable *ht) {
19972001/* Resets a stack-allocated iterator. */
19982002void hashtableResetIterator (hashtableIterator * iterator ) {
19992003 iter * iter = iteratorFromOpaque (iterator );
2000- if (!(iter -> index == -1 && iter -> table == 0 )) {
2004+ if (!(iter -> index == -1 && iter -> table == HASHTABLE_ITER_PRIMARY_TABLE )) {
20012005 if (isSafe (iter )) {
20022006 hashtableResumeRehashing (iter -> hashtable );
20032007 assert (iter -> hashtable -> pause_rehash >= 0 );
@@ -2028,13 +2032,16 @@ void hashtableReleaseIterator(hashtableIterator *iterator) {
20282032bool hashtableNext (hashtableIterator * iterator , void * * elemptr ) {
20292033 iter * iter = iteratorFromOpaque (iterator );
20302034
2031- assert (iter -> table <= HASHTABLE_ITER_END_TABLE );
2032- if (iter -> table == HASHTABLE_ITER_END_TABLE ) {
2035+ assert (iter -> table <= HASHTABLE_ITER_FINISHED );
2036+ /* Check if iterator is exhausted or in undefined state */
2037+ if (iter -> table == HASHTABLE_ITER_FINISHED ||
2038+ (iter -> table == HASHTABLE_ITER_REHASH_TABLE && !hashtableIsRehashing (iter -> hashtable )) ||
2039+ (iter -> index >= 0 && iter -> hashtable -> tables [iter -> table ] && (size_t )iter -> index >= numBuckets (iter -> hashtable -> bucket_exp [iter -> table ]))) {
20332040 return false;
20342041 }
20352042
20362043 while (1 ) {
2037- if (iter -> index == -1 && iter -> table == 0 ) {
2044+ if (iter -> index == -1 && iter -> table == HASHTABLE_ITER_PRIMARY_TABLE ) {
20382045 /* It's the first call to next. */
20392046 if (isSafe (iter )) {
20402047 hashtablePauseRehashing (iter -> hashtable );
@@ -2079,9 +2086,9 @@ bool hashtableNext(hashtableIterator *iterator, void **elemptr) {
20792086 iter -> pos_in_bucket = 0 ;
20802087 iter -> index ++ ;
20812088 if ((size_t )iter -> index >= numBuckets (iter -> hashtable -> bucket_exp [iter -> table ])) {
2082- if (hashtableIsRehashing (iter -> hashtable ) && iter -> table == 0 ) {
2089+ if (hashtableIsRehashing (iter -> hashtable ) && iter -> table == HASHTABLE_ITER_PRIMARY_TABLE ) {
20832090 iter -> index = 0 ;
2084- iter -> table ++ ;
2091+ iter -> table = HASHTABLE_ITER_REHASH_TABLE ;
20852092 } else {
20862093 /* Done. */
20872094 break ;
@@ -2110,7 +2117,7 @@ bool hashtableNext(hashtableIterator *iterator, void **elemptr) {
21102117 }
21112118 return true;
21122119 }
2113- iter -> table = HASHTABLE_ITER_END_TABLE ;
2120+ iter -> table = HASHTABLE_ITER_FINISHED ;
21142121 return false;
21152122}
21162123
0 commit comments