Get next element in iterator. * * Note: You must NOT insert into the list while iterating over it. * You *may* delete from the list while iterating using the * quicklistDelEntry() function. * If you insert into the quicklist while iterating, you should * re-create the iterator after your addition. * * iter = quicklistGetIterator(quicklist, ); * quicklistEntry entry; * while (qu
| 1139 | * If return value is 0, the contents of 'entry' are not valid. |
| 1140 | */ |
| 1141 | int quicklistNext(quicklistIter *iter, quicklistEntry *entry) { |
| 1142 | initEntry(entry); |
| 1143 | |
| 1144 | if (!iter) { |
| 1145 | D("Returning because no iter!"); |
| 1146 | return 0; |
| 1147 | } |
| 1148 | |
| 1149 | entry->quicklist = iter->quicklist; |
| 1150 | entry->node = iter->current; |
| 1151 | |
| 1152 | if (!iter->current) { |
| 1153 | D("Returning because current node is NULL") |
| 1154 | return 0; |
| 1155 | } |
| 1156 | |
| 1157 | unsigned char *(*nextFn)(unsigned char *, unsigned char *) = NULL; |
| 1158 | int offset_update = 0; |
| 1159 | |
| 1160 | if (!iter->zi) { |
| 1161 | /* If !zi, use current index. */ |
| 1162 | quicklistDecompressNodeForUse(iter->current); |
| 1163 | iter->zi = ziplistIndex(iter->current->zl, iter->offset); |
| 1164 | } else { |
| 1165 | /* else, use existing iterator offset and get prev/next as necessary. */ |
| 1166 | if (iter->direction == AL_START_HEAD) { |
| 1167 | nextFn = ziplistNext; |
| 1168 | offset_update = 1; |
| 1169 | } else if (iter->direction == AL_START_TAIL) { |
| 1170 | nextFn = ziplistPrev; |
| 1171 | offset_update = -1; |
| 1172 | } |
| 1173 | iter->zi = nextFn(iter->current->zl, iter->zi); |
| 1174 | iter->offset += offset_update; |
| 1175 | } |
| 1176 | |
| 1177 | entry->zi = iter->zi; |
| 1178 | entry->offset = iter->offset; |
| 1179 | |
| 1180 | if (iter->zi) { |
| 1181 | /* Populate value from existing ziplist position */ |
| 1182 | ziplistGet(entry->zi, &entry->value, &entry->sz, &entry->longval); |
| 1183 | return 1; |
| 1184 | } else { |
| 1185 | /* We ran out of ziplist entries. |
| 1186 | * Pick next node, update offset, then re-run retrieval. */ |
| 1187 | quicklistCompress(iter->quicklist, iter->current); |
| 1188 | if (iter->direction == AL_START_HEAD) { |
| 1189 | /* Forward traversal */ |
| 1190 | D("Jumping to start of next node"); |
| 1191 | iter->current = iter->current->next; |
| 1192 | iter->offset = 0; |
| 1193 | } else if (iter->direction == AL_START_TAIL) { |
| 1194 | /* Reverse traversal */ |
| 1195 | D("Jumping to end of previous node"); |
| 1196 | iter->current = iter->current->prev; |
| 1197 | iter->offset = -1; |
| 1198 | } |
no test coverage detected