dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.46k stars 4.76k forks source link

Tagged memory cache implementation #36562

Open ScottArbeit opened 7 years ago

ScottArbeit commented 7 years ago

Way back, a long time ago, Azure Cloud Services had an in-role cache that supported tags (since deprecated in favor of Redis). I always liked that feature.

I have a use-case for it in a personal project, so I've written a TaggedMemoryCache that inherits from MemoryCache and extends it to wrap tagging around it. It supports cache items with or without tags; i.e. associating tags with cache items is completely optional, and if you create cache items without tags, performance is identical to MemoryCache.

The tag-specific overloads and functions run a tick slower than MemoryCache, because there's more work to do, but it's not offensive at all. Removes are equivalent to MemoryCache, and are captured lazily when GetByTag()/GetByTags() is called. Inserts are a little more than 2x slower, which makes sense... a second Dictionary to update and some overhead.

It's simple to change to overloads of Set() if the interface does change back to something like that. Right now, the interface is:

    public interface ITaggedMemoryCacheService : IMemoryCache
    {
        ICacheEntry CreateEntry(object key, string tag);
        ICacheEntry CreateEntry(object key, IEnumerable<string> tags);

        Dictionary<object, object> GetByTag(string tag);
        Dictionary<object, object> GetByTags(IEnumerable<string> tag);

        void RemoveByTag(string tag);
        void RemoveByTags(IEnumerable<string> tags);

        void RemoveTag(object key, string tag);
        void RemoveTags(object key, IEnumerable<string> tags);
    }

Anyway, it's rude to do a PR for something like this, so I figured I'd ask: is this something that the team would be interested in as a contribution? The code is tested, performs well-enough (at least for me), and is fairly straightforward. I'll be using it either way, but figured I'd see if it fits as a contribution.

Thanks! Scott

Tratcher commented 6 years ago

How about sharing a link to your repo/branch so we can take a look?

Jetski5822 commented 6 years ago

@ScottArbeit Got a link to this? We have a tagged redis implementation, and would rather use something that everyone else was using.

tmakin commented 6 years ago

Any updates on this one? I'm about to have a crack at my own version of this, but would happily use/contribute to another fork if there is one. Thanks!

Here are some useful resources for anyone else researching the subject: https://stackify.com/implementing-cache-tagging-redis/ https://github.com/withspectrum/redis-tag-cache/ https://github.com/thepirat000/CachingFramework.Redis/ https://github.com/jmenziessmith/TagCache.Redis