-
Notifications
You must be signed in to change notification settings - Fork 46
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add delete by func #44
Comments
Hi, I think this can be added, but I'm wondering how the plan is to use this feature for your task. I understand that you eventually want to do something like this. m := map[int]bool{
1: true,
3: true,
8: true,
}
c.DeleteByFunc(func(key int, value int) bool {
return m[key]
}) Am I right? If so, I'm very curious how you will recognize m in advance. Or will there be some kind of tag stored inside the keys or values and it can be checked in this function? |
This could also be implemented more efficiently, but it probably doesn't make much sense given the very infrequent use of this operation. |
Oh, it would be cool to get a link to a similar function in ristretto, because I couldn't find anything like that. :( This feature does look useful though. |
I use GoCache on top of Ristretto. The use case is pretty specific - I cache read only objects in memory in order to speed up deserialization from DB. One nice feature of GoCache is the ability to invalidate multiple cached objects using tags, like described here: https://github.com/eko/gocache?tab=readme-ov-file#cache-invalidation-using-tags The actual code for Ristretto sits in https://github.com/eko/gocache/blob/master/store/ristretto/ristretto.go - the approach is simple enough (and a bit naive): Aggregate the cache keys and delete them one by one. In the code above I was thinking about a similar possibility to simulate this. Mostly, I can traverse a cache object list and delete objects according to a specific pattern or criterium (like a field value). This would be pretty straightforward, although the whole thing has a few issues with concurrencies, but these are the same as in the implementation of GoCache. An example to get the idea what I am thinking about: type ExampleObject struct {
Id string
ToDelete bool
}
//...
var exampleCache otter.Cache[string, ExampleObject] // cache key is Id of object
//...
exampleCache.DeleteByFunc(func(key string, value ExampleObject) bool {
return value.ToDelete
}) Something along this line. |
Hmm, that's still more like what the wrapper should implement. It's not exactly what gocache does, its implementation could be much more efficient, but it does something very unpleasant in terms of allocations. Ok, I'll add this feature, especially since it could close some other user requests as well, but if you really want something efficient in a case like this, it's better to do it on the wrapper side. P.S. I have a suspicion that this solution would work even better than what gocache does, because the constant |
Thanks so much! And yes, I was quite shocked to see this yesterday 😸 Never had a closer look into the tag code yet. |
Does your implementation delete the mapping even if it was changed by a concurrent write? If so you might make it conditional or document that behavior as a caveat. (Here is a Java version if that helps any) |
I decided to put it off for now (I shouldn't have 🙂), but it looks like a special effect of using RCU. Caffeine on the other hand is saved by using get + synchronized on updates. Elsewhere otter uses node deletion to protect against this, so let's do the same here. But the good news is that the Range implementation turned out to be smarter than I thought and it is finally possible to implement this function without keysToDelete. |
Furiously wonders how Ben has time to review pull requests and issues in many repos...😁 |
I was super exhausted last night and went to bed early, then unfortunately woke up at 4am... |
Ok, now the function implementation should be robust, if you know how to break its behavior now, then write. |
Looks cool - I will test it and report if I find any issues. |
I really like otter, but what do miss (in comparison to ristretto for example) is something similar to a tag option. I need it sometimes to invalidate a part of the cache, and an easy option (in my opinion at least) to implement this would be to add a function to delete a part of the the cache depending on a function.
This would go along something like this:
You probably need a mutex, but the general idea should be clear.
Any additional ideas are appreciated.
The text was updated successfully, but these errors were encountered: