jellydator / ttlcache

An in-memory cache with item expiration and generics
MIT License
941 stars 121 forks source link

The most optimal way to invalidate records by matching fields #145

Closed sergiizemlianyi-bc closed 2 months ago

sergiizemlianyi-bc commented 2 months ago

Hi,

I am working on implementing flow of cache records invalidation by matching internal record fields. What would be the most efficient approach? Currently I see it can be calling

items := cache.Items()
for _, item := range items{
   check, if matches, delete from original cache instance
}

I am concerned about copying whole cache.

Also I can call Range(fn func(item *Item[K, V]) bool) but looks like this method is designed for validation rather than for write operations.

Any more optimal approaches how to delete record matching some fields?

Thanks

swithek commented 2 months ago

Write operations can be performed in Range(). It doesn't block when the callback is being executed.

sergiizemlianyi-bc commented 2 months ago

@swithek thanks, few clarifications..

1-- I assume Range() is faster since it ranges over pointers rather than returns a full copy of cache like Items() ?

2-- from Range() comment

If fn returns false, // Range stops the iteration.

So essentially false in callback function should signal error right? I wonder why it is true/false instead of returning error and failing Range if error != nil ?

swithek commented 2 months ago

Range() mimics the behaviour of for i := range x {}, in which one can use break to stop the iteration. The use of break doesn't necessarily mean that there's an error, it just stops the execution. Though I understand that Range() cannot mimic the functionality of return in a normal range block, which prevents error propagation. We might address this in the next major release.

Also, the design of this method was inspired by sync.Map's Range().