@@ -35,7 +35,9 @@ class IntrusiveStringSet {
3535 : buckets_it_(it), end_(end), entry_(entry) {
3636 }
3737
38- iterator (Buckets::iterator it, Buckets::iterator end) : buckets_it_(it), end_(end) {
38+ iterator (Buckets::iterator it, Buckets::iterator end, std::uint32_t time_now,
39+ std::uint32_t * set_size)
40+ : buckets_it_(it), end_(end), time_now_(time_now), set_size_(set_size) {
3941 SetEntryIt ();
4042 }
4143
@@ -54,9 +56,11 @@ class IntrusiveStringSet {
5456 // void Advance();
5557
5658 iterator& operator ++() {
57- // TODO add expiration logic
58- if (entry_)
59+ if (entry_) {
60+ if (entry_.ExpireIfNeeded (time_now_, &buckets_it_->obj_malloc_used_ ))
61+ (*set_size_)--;
5962 ++entry_;
63+ }
6064 if (!entry_) {
6165 ++buckets_it_;
6266 SetEntryIt ();
@@ -95,14 +99,16 @@ class IntrusiveStringSet {
9599 Buckets::iterator buckets_it_;
96100 Buckets::iterator end_;
97101 IntrusiveStringList::iterator entry_;
102+ std::uint32_t time_now_;
103+ std::uint32_t * set_size_;
98104 };
99105
100106 iterator begin () {
101- return iterator (entries_.begin (), entries_.end ());
107+ return iterator (entries_.begin (), entries_.end (), time_now_, &size_ );
102108 }
103109
104110 iterator end () {
105- return iterator (entries_.end (), entries_.end ());
111+ return iterator (entries_.end (), entries_.end (), time_now_, &size_ );
106112 }
107113
108114 explicit IntrusiveStringSet (PMR_NS::memory_resource* mr = PMR_NS::get_default_resource())
@@ -111,14 +117,18 @@ class IntrusiveStringSet {
111117
112118 static constexpr uint32_t kMaxBatchLen = 32 ;
113119
114- ISLEntry Add (std::string_view str, uint32_t ttl_sec = UINT32_MAX) {
120+ ISLEntry Add (std::string_view str, bool keepttl = true , uint32_t ttl_sec = UINT32_MAX) {
115121 if (entries_.empty () || size_ >= entries_.size ()) {
116122 Reserve (Capacity () * 2 );
117123 }
118124 uint64_t hash = Hash (str);
119125 const auto bucket_id = BucketId (hash);
120126
121127 if (auto item = FindInternal (bucket_id, str, hash); item.first != IntrusiveStringList::end ()) {
128+ // Update ttl if found
129+ if (!keepttl) {
130+ item.first .SetExpiryTime (EntryTTL (ttl_sec), &entries_[item.second ].obj_malloc_used_ );
131+ }
122132 return {};
123133 }
124134
@@ -160,8 +170,9 @@ class IntrusiveStringSet {
160170 Reserve (span.size ());
161171 unsigned res = 0 ;
162172 for (auto & s : span) {
163- res++;
164- Add (s, ttl_sec);
173+ if (Add (s, keepttl, ttl_sec)) {
174+ res++;
175+ }
165176 }
166177 return res;
167178 }
@@ -173,7 +184,7 @@ class IntrusiveStringSet {
173184 other->set_time (time_now ());
174185 for (uint32_t bucket_id = 0 ; bucket_id < entries_.size (); ++bucket_id) {
175186 for (auto it = entries_[bucket_id].begin (); it != entries_[bucket_id].end (); ++it) {
176- other->Add (it->Key (), it.HasExpiry () ? it->ExpiryTime () : UINT32_MAX);
187+ other->Add (it->Key (), true , it.HasExpiry () ? it->ExpiryTime () : UINT32_MAX);
177188 }
178189 }
179190 }
@@ -229,7 +240,7 @@ class IntrusiveStringSet {
229240 uint64_t hash = Hash (str);
230241 auto bucket_id = BucketId (hash);
231242 auto item = FindInternal (bucket_id, str, hash);
232- return entries_[item.second ].Erase (str);
243+ return entries_[item.second ].Erase (str, &size_ );
233244 }
234245
235246 iterator Find (std::string_view member) {
@@ -239,7 +250,11 @@ class IntrusiveStringSet {
239250 uint64_t hash = Hash (member);
240251 auto bucket_id = BucketId (hash);
241252 auto res = FindInternal (bucket_id, member, hash);
242- return {res.first ? entries_.begin () + res.second : entries_.end (), entries_.end (), res.first };
253+ return {
254+ res.first ? entries_.begin () + res.second : entries_.end (),
255+ entries_.end (),
256+ res.first ,
257+ };
243258 }
244259
245260 bool Contains (std::string_view member) {
@@ -369,7 +384,6 @@ class IntrusiveStringSet {
369384 std::uint32_t capacity_log_ = 0 ;
370385 std::uint32_t size_ = 0 ; // number of elements in the set.
371386 std::uint32_t time_now_ = 0 ;
372-
373387 Buckets entries_;
374388};
375389
0 commit comments