Force 'quicklist' to meet compression guidelines set by compress depth. * The only way to guarantee interior nodes get compressed is to iterate * to our "interior" compress depth then compress the next node we find. * If compress depth is larger than the entire list, we return immediately. */
| 270 | * to our "interior" compress depth then compress the next node we find. |
| 271 | * If compress depth is larger than the entire list, we return immediately. */ |
| 272 | REDIS_STATIC void __quicklistCompress(const quicklist *quicklist, |
| 273 | quicklistNode *node) { |
| 274 | /* If length is less than our compress depth (from both sides), |
| 275 | * we can't compress anything. */ |
| 276 | if (!quicklistAllowsCompression(quicklist) || |
| 277 | quicklist->len < (unsigned int)(quicklist->compress * 2)) |
| 278 | return; |
| 279 | |
| 280 | #if 0 |
| 281 | /* Optimized cases for small depth counts */ |
| 282 | if (quicklist->compress == 1) { |
| 283 | quicklistNode *h = quicklist->head, *t = quicklist->tail; |
| 284 | quicklistDecompressNode(h); |
| 285 | quicklistDecompressNode(t); |
| 286 | if (h != node && t != node) |
| 287 | quicklistCompressNode(node); |
| 288 | return; |
| 289 | } else if (quicklist->compress == 2) { |
| 290 | quicklistNode *h = quicklist->head, *hn = h->next, *hnn = hn->next; |
| 291 | quicklistNode *t = quicklist->tail, *tp = t->prev, *tpp = tp->prev; |
| 292 | quicklistDecompressNode(h); |
| 293 | quicklistDecompressNode(hn); |
| 294 | quicklistDecompressNode(t); |
| 295 | quicklistDecompressNode(tp); |
| 296 | if (h != node && hn != node && t != node && tp != node) { |
| 297 | quicklistCompressNode(node); |
| 298 | } |
| 299 | if (hnn != t) { |
| 300 | quicklistCompressNode(hnn); |
| 301 | } |
| 302 | if (tpp != h) { |
| 303 | quicklistCompressNode(tpp); |
| 304 | } |
| 305 | return; |
| 306 | } |
| 307 | #endif |
| 308 | |
| 309 | /* Iterate until we reach compress depth for both sides of the list.a |
| 310 | * Note: because we do length checks at the *top* of this function, |
| 311 | * we can skip explicit null checks below. Everything exists. */ |
| 312 | quicklistNode *forward = quicklist->head; |
| 313 | quicklistNode *reverse = quicklist->tail; |
| 314 | int depth = 0; |
| 315 | int in_depth = 0; |
| 316 | while (depth++ < quicklist->compress) { |
| 317 | quicklistDecompressNode(forward); |
| 318 | quicklistDecompressNode(reverse); |
| 319 | |
| 320 | if (forward == node || reverse == node) |
| 321 | in_depth = 1; |
| 322 | |
| 323 | /* We passed into compress depth of opposite side of the quicklist |
| 324 | * so there's no need to compress anything and we can exit. */ |
| 325 | if (forward == reverse || forward->next == reverse) |
| 326 | return; |
| 327 | |
| 328 | forward = forward->next; |
| 329 | reverse = reverse->prev; |
no outgoing calls
no test coverage detected