From 32f15b47c67aceb00911643f61acc4b415be0527 Mon Sep 17 00:00:00 2001 From: mkaruza Date: Wed, 16 Apr 2025 14:44:51 +0200 Subject: [PATCH] fix(set_family): Transfer TTL flag from link to object in delete When extracting DensePtr from LinkObject we need to transfer TTL flag before this DensePtr is assigned. Fixes #3915 Signed-off-by: mkaruza --- src/core/dense_set.cc | 2 ++ src/core/string_set_test.cc | 12 ++++++++++++ src/server/set_family_test.cc | 13 +++++++++++++ 3 files changed, 27 insertions(+) diff --git a/src/core/dense_set.cc b/src/core/dense_set.cc index c3273ba88a34..d78b572a6e30 100644 --- a/src/core/dense_set.cc +++ b/src/core/dense_set.cc @@ -648,6 +648,8 @@ void DenseSet::Delete(DensePtr* prev, DensePtr* ptr) { DenseLinkKey* plink = prev->AsLink(); DensePtr tmp = DensePtr::From(plink); + // Transfer TTL flag + tmp.SetTtl(prev->HasTtl()); DCHECK(ObjectAllocSize(tmp.GetObject())); FreeLink(plink); diff --git a/src/core/string_set_test.cc b/src/core/string_set_test.cc index 4a9f1fcd7f30..2e3f033f2817 100644 --- a/src/core/string_set_test.cc +++ b/src/core/string_set_test.cc @@ -767,4 +767,16 @@ TEST_F(StringSetTest, ReallocIfNeeded) { EXPECT_EQ(*ss_->Find(build_str(i * 10)), build_str(i * 10)); } +TEST_F(StringSetTest, TransferTTLFlagLinkToObjectOnDelete) { + for (size_t i = 0; i < 10; i++) { + EXPECT_TRUE(ss_->Add(absl::StrCat(i), 1)); + } + for (size_t i = 0; i < 9; i++) { + EXPECT_TRUE(ss_->Erase(absl::StrCat(i))); + } + auto it = ss_->Find("9"sv); + EXPECT_TRUE(it.HasExpiry()); + EXPECT_EQ(1u, it.ExpiryTime()); +} + } // namespace dfly diff --git a/src/server/set_family_test.cc b/src/server/set_family_test.cc index ffddcc3b46f0..54bc93269aab 100644 --- a/src/server/set_family_test.cc +++ b/src/server/set_family_test.cc @@ -412,4 +412,17 @@ TEST_F(SetFamilyTest, SAddEx) { EXPECT_THAT(Run({"saddex", "key", "KEEPTTL", "2"}), ErrArg("wrong number of arguments")); } +TEST_F(SetFamilyTest, CheckSetLinkExpiryTransfer) { + for (int i = 0; i < 10; i++) { + EXPECT_THAT(Run({"SADDEX", "key", "5", absl::StrCat(i)}), IntArg(1)); + } + for (int i = 0; i < 9; i++) { + Run({"SREM", "key", absl::StrCat(i)}); + } + EXPECT_THAT(Run({"SCARD", "key"}), IntArg(1)); + AdvanceTime(6000); + Run({"SMEMBERS", "key"}); + EXPECT_THAT(Run({"SCARD", "key"}), IntArg(0)); +} + } // namespace dfly