summaryrefslogtreecommitdiff
path: root/src/ziplist.c
diff options
context:
space:
mode:
authorsundb <sundbcn@gmail.com>2021-09-09 23:18:53 +0800
committerGitHub <noreply@github.com>2021-09-09 18:18:53 +0300
commit3ca6972ecd3e9963f65b9cb1ff050ad60f03563e (patch)
tree9f82d9d622f5d161bc0d72c83f8f31555f5a652d /src/ziplist.c
parent86b0de5c41c96225377b83090fbdbe0209c2d9b9 (diff)
downloadredis-3ca6972ecd3e9963f65b9cb1ff050ad60f03563e.tar.gz
Replace all usage of ziplist with listpack for t_zset (#9366)
Part two of implementing #8702 (zset), after #8887. ## Description of the feature Replaced all uses of ziplist with listpack in t_zset, and optimized some of the code to optimize performance. ## Rdb format changes New `RDB_TYPE_ZSET_LISTPACK` rdb type. ## Rdb loading improvements: 1) Pre-expansion of dict for validation of duplicate data for listpack and ziplist. 2) Simplifying the release of empty key objects when RDB loading. 3) Unify ziplist and listpack data verify methods for zset and hash, and move code to rdb.c. ## Interface changes 1) New `zset-max-listpack-entries` config is an alias for `zset-max-ziplist-entries` (same with `zset-max-listpack-value`). 2) OBJECT ENCODING will return listpack instead of ziplist. ## Listpack improvements: 1) Add `lpDeleteRange` and `lpDeleteRangeWithEntry` functions to delete a range of entries from listpack. 2) Improve the performance of `lpCompare`, converting from string to integer is faster than converting from integer to string. 3) Replace `snprintf` with `ll2string` to improve performance in converting numbers to strings in `lpGet()`. ## Zset improvements: 1) Improve the performance of `zzlFind` method, use `lpFind` instead of `lpCompare` in a loop. 2) Use `lpDeleteRangeWithEntry` instead of `lpDelete` twice to delete a element of zset. ## Tests 1) Add some unittests for `lpDeleteRange` and `lpDeleteRangeWithEntry` function. 2) Add zset RDB loading test. 3) Add benchmark test for `lpCompare` and `ziplsitCompare`. 4) Add empty listpack zset corrupt dump test.
Diffstat (limited to 'src/ziplist.c')
-rw-r--r--src/ziplist.c30
1 files changed, 28 insertions, 2 deletions
diff --git a/src/ziplist.c b/src/ziplist.c
index b55c85fcf..34adad622 100644
--- a/src/ziplist.c
+++ b/src/ziplist.c
@@ -1498,6 +1498,7 @@ int ziplistValidateIntegrity(unsigned char *zl, size_t size, int deep,
return 1;
unsigned int count = 0;
+ unsigned int header_count = intrev16ifbe(ZIPLIST_LENGTH(zl));
unsigned char *p = ZIPLIST_ENTRY_HEAD(zl);
unsigned char *prev = NULL;
size_t prev_raw_size = 0;
@@ -1512,7 +1513,7 @@ int ziplistValidateIntegrity(unsigned char *zl, size_t size, int deep,
return 0;
/* Optionally let the caller validate the entry too. */
- if (entry_cb && !entry_cb(p, cb_userdata))
+ if (entry_cb && !entry_cb(p, header_count, cb_userdata))
return 0;
/* Move to the next entry */
@@ -1531,7 +1532,6 @@ int ziplistValidateIntegrity(unsigned char *zl, size_t size, int deep,
return 0;
/* Check that the count in the header is correct */
- unsigned int header_count = intrev16ifbe(ZIPLIST_LENGTH(zl));
if (header_count != UINT16_MAX && count != header_count)
return 0;
@@ -2464,6 +2464,32 @@ int ziplistTest(int argc, char **argv, int accurate) {
printf("%lld\n", usec()-start);
}
+ printf("Benchmark ziplistCompare with string\n");
+ {
+ unsigned long long start = usec();
+ for (int i = 0; i < 2000; i++) {
+ unsigned char *eptr = ziplistIndex(zl,0);
+ while (eptr != NULL) {
+ ziplistCompare(eptr,(unsigned char*)"nothing",7);
+ eptr = ziplistNext(zl,eptr);
+ }
+ }
+ printf("Done. usec=%lld\n", usec()-start);
+ }
+
+ printf("Benchmark ziplistCompare with number\n");
+ {
+ unsigned long long start = usec();
+ for (int i = 0; i < 2000; i++) {
+ unsigned char *eptr = ziplistIndex(zl,0);
+ while (eptr != NULL) {
+ ziplistCompare(eptr,(unsigned char*)"99999",5);
+ eptr = ziplistNext(zl,eptr);
+ }
+ }
+ printf("Done. usec=%lld\n", usec()-start);
+ }
+
zfree(zl);
}