diff options
author | Binbin <binloveplay1314@qq.com> | 2021-07-11 16:26:31 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-11 11:26:31 +0300 |
commit | fe5d325107c11ff4a0b5f40deae47c3016c9b9d7 (patch) | |
tree | 668bf0db3d866ce1b2395fd37b16178d0607a826 | |
parent | 92e8004705bdac2ccb75c8be7c72f072d755a268 (diff) | |
download | redis-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.c | 54 |
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 |