A helper for replying with a list's range between the inclusive start and end * indexes as multi-bulk, with support for negative indexes. Note that start * must be less than end or an empty array is returned. When the reverse * argument is set to a non-zero value, the reply is reversed so that elements * are returned from end to start. */
| 399 | * argument is set to a non-zero value, the reply is reversed so that elements |
| 400 | * are returned from end to start. */ |
| 401 | void addListRangeReply(client *c, robj_roptr o, long start, long end, int reverse) { |
| 402 | long rangelen, llen = listTypeLength(o); |
| 403 | |
| 404 | /* Convert negative indexes. */ |
| 405 | if (start < 0) start = llen+start; |
| 406 | if (end < 0) end = llen+end; |
| 407 | if (start < 0) start = 0; |
| 408 | |
| 409 | /* Invariant: start >= 0, so this test will be true when end < 0. |
| 410 | * The range is empty when start > end or start >= length. */ |
| 411 | if (start > end || start >= llen) { |
| 412 | addReply(c,shared.emptyarray); |
| 413 | return; |
| 414 | } |
| 415 | if (end >= llen) end = llen-1; |
| 416 | rangelen = (end-start)+1; |
| 417 | |
| 418 | /* Return the result in form of a multi-bulk reply */ |
| 419 | addReplyArrayLen(c,rangelen); |
| 420 | if (o->encoding == OBJ_ENCODING_QUICKLIST) { |
| 421 | int from = reverse ? end : start; |
| 422 | int direction = reverse ? LIST_HEAD : LIST_TAIL; |
| 423 | listTypeIterator *iter = listTypeInitIterator(o,from,direction); |
| 424 | |
| 425 | while(rangelen--) { |
| 426 | listTypeEntry entry; |
| 427 | listTypeNext(iter, &entry); |
| 428 | quicklistEntry *qe = &entry.entry; |
| 429 | if (qe->value) { |
| 430 | addReplyBulkCBuffer(c,qe->value,qe->sz); |
| 431 | } else { |
| 432 | addReplyBulkLongLong(c,qe->longval); |
| 433 | } |
| 434 | } |
| 435 | listTypeReleaseIterator(iter); |
| 436 | } else { |
| 437 | serverPanic("Unknown list encoding"); |
| 438 | } |
| 439 | } |
| 440 | |
| 441 | /* A housekeeping helper for list elements popping tasks. */ |
| 442 | void listElementsRemoved(client *c, robj *key, int where, robj *o, long count) { |
no test coverage detected