diff --git a/src/storage/src/redis_zsets.cc b/src/storage/src/redis_zsets.cc index 4f1436b542..a4153c9d9a 100644 --- a/src/storage/src/redis_zsets.cc +++ b/src/storage/src/redis_zsets.cc @@ -307,13 +307,17 @@ Status RedisZSets::ZAdd(const Slice& key, const std::vector& score_ *ret = 0; uint32_t statistic = 0; std::unordered_set unique; - std::vector filtered_score_members; - for (const auto& sm : score_members) { - if (unique.find(sm.member) == unique.end()) { - unique.insert(sm.member); - filtered_score_members.push_back(sm); + std::list mid_score_members; + for (auto it = score_members.rbegin(); it != score_members.rend(); ++it) { + if (unique.find(it->member) == unique.end()) { + unique.insert(it->member); + mid_score_members.push_front(*it); } } + std::vector filtered_score_members; + for (auto &item : mid_score_members) { + filtered_score_members.push_back(std::move(item)); + } char score_buf[8]; int32_t version = 0; diff --git a/tests/integration/zset_test.go b/tests/integration/zset_test.go index 7cc81bbcef..fdd2dc7139 100644 --- a/tests/integration/zset_test.go +++ b/tests/integration/zset_test.go @@ -233,7 +233,26 @@ var _ = Describe("Zset Commands", func() { Member: "two", }})) }) - + // Caiyu's test: verify that zadd with multiple scores for the same member in + //a single command only keeps the last score, consistent with Redis behavior + It("should ZAdd with duplicate member in one command", func() { + added, err := client.ZAdd(ctx, "myzset", redis.Z{ + Score: 100, + Member: "one", + }, redis.Z{ + Score: 98, + Member: "one", + }).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(added).To(Equal(int64(1))) + + vals, err := client.ZRangeWithScores(ctx, "myzset", 0, -1).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(vals).To(Equal([]redis.Z{{ + Score: 98, + Member: "one", + }})) + }) It("should ZAdd bytes", func() { added, err := client.ZAdd(ctx, "zset", redis.Z{ Score: 1,