Defrag helper for dictEntries to be used during dict iteration (called on * each step). Returns a stat of how many pointers were moved. */
| 130 | /* Defrag helper for dictEntries to be used during dict iteration (called on |
| 131 | * each step). Returns a stat of how many pointers were moved. */ |
| 132 | long dictIterDefragEntry(dictIterator *iter) { |
| 133 | /* This function is a little bit dirty since it messes with the internals |
| 134 | * of the dict and it's iterator, but the benefit is that it is very easy |
| 135 | * to use, and require no other changes in the dict. */ |
| 136 | long defragged = 0; |
| 137 | dictht *ht; |
| 138 | /* Handle the next entry (if there is one), and update the pointer in the |
| 139 | * current entry. */ |
| 140 | if (iter->nextEntry) { |
| 141 | dictEntry *newde = activeDefragAlloc(iter->nextEntry); |
| 142 | if (newde) { |
| 143 | defragged++; |
| 144 | iter->nextEntry = newde; |
| 145 | iter->entry->next = newde; |
| 146 | } |
| 147 | } |
| 148 | /* handle the case of the first entry in the hash bucket. */ |
| 149 | ht = &iter->d->ht[iter->table]; |
| 150 | if (ht->table[iter->index] == iter->entry) { |
| 151 | dictEntry *newde = activeDefragAlloc(iter->entry); |
| 152 | if (newde) { |
| 153 | iter->entry = newde; |
| 154 | ht->table[iter->index] = newde; |
| 155 | defragged++; |
| 156 | } |
| 157 | } |
| 158 | return defragged; |
| 159 | } |
| 160 | |
| 161 | /* Defrag helper for dict main allocations (dict struct, and hash tables). |
| 162 | * receives a pointer to the dict* and implicitly updates it when the dict |
no test coverage detected