mirror of
https://github.com/redis/redis.git
synced 2026-02-03 20:39:54 -05:00
Merge 6d08c6a678 into b5a37c0e42
This commit is contained in:
commit
4b0859dc7b
3 changed files with 41 additions and 2 deletions
|
|
@ -1456,6 +1456,45 @@ unsigned char *lpBatchDelete(unsigned char *lp, unsigned char **ps, unsigned lon
|
|||
return lpShrinkToFit(lp);
|
||||
}
|
||||
|
||||
/* Trim a listpack, remove 'ltrim' elements from left and 'rtrim' elements from right. */
|
||||
unsigned char *lpTrim(unsigned char *lp, unsigned long ltrim, unsigned long rtrim) {
|
||||
if (ltrim == 0 && rtrim == 0) return lp;
|
||||
size_t bytes = lpBytes(lp);
|
||||
unsigned long llen = lpLength(lp);
|
||||
if (ltrim + rtrim >= llen) {
|
||||
/* Remove all elements */
|
||||
lp[LP_HDR_SIZE] = LP_EOF;
|
||||
lpSetTotalBytes(lp, LP_HDR_SIZE + 1);
|
||||
lpSetNumElements(lp, 0);
|
||||
return lpShrinkToFit(lp);
|
||||
}
|
||||
unsigned long rangelen = llen - ltrim - rtrim;
|
||||
unsigned char *first, *tail; /* first points to the first byte we want to save,
|
||||
and tail points to the byte after the last byte we want to save */
|
||||
first = lpSeek(lp, ltrim);
|
||||
assert(first != NULL);
|
||||
tail = lp + bytes - 1; /* When rtrim is zero, tail points to the EOF char */
|
||||
if (rtrim) {
|
||||
if (rangelen < rtrim) {
|
||||
tail = first;
|
||||
unsigned long num = rangelen;
|
||||
while (num--) {
|
||||
tail = lpSkip(tail);
|
||||
}
|
||||
assert(tail[0] != LP_EOF);
|
||||
lpAssertValidEntry(lp, bytes, tail);
|
||||
} else {
|
||||
tail = lpSeek(lp, llen - (int)rtrim);
|
||||
}
|
||||
}
|
||||
size_t rangebytes = tail - first;
|
||||
memmove(lp + LP_HDR_SIZE, first, rangebytes);
|
||||
lp[LP_HDR_SIZE + rangebytes] = LP_EOF;
|
||||
lpSetTotalBytes(lp, LP_HDR_SIZE + rangebytes + 1);
|
||||
lpSetNumElements(lp, rangelen);
|
||||
return lpShrinkToFit(lp);
|
||||
}
|
||||
|
||||
/* Merge listpacks 'first' and 'second' by appending 'second' to 'first'.
|
||||
*
|
||||
* NOTE: The larger listpack is reallocated to contain the new merged listpack.
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ unsigned char *lpBatchAppend(unsigned char *lp, listpackEntry *entries, unsigned
|
|||
unsigned char *lpBatchInsert(unsigned char *lp, unsigned char *p, int where,
|
||||
listpackEntry *entries, unsigned int len, unsigned char **newp);
|
||||
unsigned char *lpBatchDelete(unsigned char *lp, unsigned char **ps, unsigned long count);
|
||||
unsigned char *lpTrim(unsigned char *lp, unsigned long ltrim, unsigned long rtrim);
|
||||
unsigned char *lpMerge(unsigned char **first, unsigned char **second);
|
||||
unsigned char *lpDup(unsigned char *lp);
|
||||
unsigned long lpLength(unsigned char *lp);
|
||||
|
|
|
|||
|
|
@ -961,8 +961,7 @@ void ltrimCommand(client *c) {
|
|||
quicklistDelRange(o->ptr,0,ltrim);
|
||||
quicklistDelRange(o->ptr,-rtrim,rtrim);
|
||||
} else if (o->encoding == OBJ_ENCODING_LISTPACK) {
|
||||
o->ptr = lpDeleteRange(o->ptr,0,ltrim);
|
||||
o->ptr = lpDeleteRange(o->ptr,-rtrim,rtrim);
|
||||
o->ptr = lpTrim(o->ptr, ltrim, rtrim);
|
||||
} else {
|
||||
serverPanic("Unknown list encoding");
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue