summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBinbin <binloveplay1314@qq.com>2021-07-11 16:26:31 +0800
committerGitHub <noreply@github.com>2021-07-11 11:26:31 +0300
commitfe5d325107c11ff4a0b5f40deae47c3016c9b9d7 (patch)
tree668bf0db3d866ce1b2395fd37b16178d0607a826
parent92e8004705bdac2ccb75c8be7c72f072d755a268 (diff)
downloadredis-fe5d325107c11ff4a0b5f40deae47c3016c9b9d7.tar.gz
Add test for ziplist (nextdiff == -4 && reqlen < 4) (#9218)
The if judgement `nextdiff == -4 && reqlen < 4` in __ziplistInsert. It's strange, but it's useful. Without it there will be problems during chain update. Till now these lines didn't have coverage in the tests, and there was a question if they are at all needed (#7170)
-rw-r--r--src/ziplist.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/src/ziplist.c b/src/ziplist.c
index ba4c85b35..9aab8822c 100644
--- a/src/ziplist.c
+++ b/src/ziplist.c
@@ -2558,6 +2558,60 @@ int ziplistTest(int argc, char **argv, int accurate) {
zfree(zl);
}
+ printf("__ziplistInsert nextdiff == -4 && reqlen < 4 (issue #7170):\n");
+ {
+ zl = ziplistNew();
+
+ /* We set some values to almost reach the critical point - 254 */
+ char A_252[253] = {0}, A_250[251] = {0};
+ memset(A_252, 'A', 252);
+ memset(A_250, 'A', 250);
+
+ /* After the rpush, the list look like: [one two A_252 A_250 three 10] */
+ zl = ziplistPush(zl, (unsigned char*)"one", 3, ZIPLIST_TAIL);
+ zl = ziplistPush(zl, (unsigned char*)"two", 3, ZIPLIST_TAIL);
+ zl = ziplistPush(zl, (unsigned char*)A_252, strlen(A_252), ZIPLIST_TAIL);
+ zl = ziplistPush(zl, (unsigned char*)A_250, strlen(A_250), ZIPLIST_TAIL);
+ zl = ziplistPush(zl, (unsigned char*)"three", 5, ZIPLIST_TAIL);
+ zl = ziplistPush(zl, (unsigned char*)"10", 2, ZIPLIST_TAIL);
+ ziplistRepr(zl);
+
+ p = ziplistIndex(zl, 2);
+ if (!ziplistCompare(p, (unsigned char*)A_252, strlen(A_252))) {
+ printf("ERROR: not \"A_252\"\n");
+ return 1;
+ }
+
+ /* When we remove A_252, the list became: [one two A_250 three 10]
+ * A_250's prev node became node two, because node two quite small
+ * So A_250's prevlenSize shrink to 1, A_250's total size became 253(1+2+250)
+ * The prev node of node three is still node A_250.
+ * We will not shrink the node three's prevlenSize, keep it at 5 bytes */
+ zl = ziplistDelete(zl, &p);
+ ziplistRepr(zl);
+
+ p = ziplistIndex(zl, 3);
+ if (!ziplistCompare(p, (unsigned char*)"three", 5)) {
+ printf("ERROR: not \"three\"\n");
+ return 1;
+ }
+
+ /* We want to insert a node after A_250, the list became: [one two A_250 10 three 10]
+ * Because the new node is quite small, node three prevlenSize will shrink to 1 */
+ zl = ziplistInsert(zl, p, (unsigned char*)"10", 2);
+ ziplistRepr(zl);
+
+ /* Last element should equal 10 */
+ p = ziplistIndex(zl, -1);
+ if (!ziplistCompare(p, (unsigned char*)"10", 2)) {
+ printf("ERROR: not \"10\"\n");
+ return 1;
+ }
+
+ zfree(zl);
+ }
+
+ printf("ALL TESTS PASSED!\n");
return 0;
}
#endif