glav / Glav.CacheAdapter

MIT License
8 stars 11 forks source link

Get all keys of items in cache #13

Open andrewmurray opened 5 years ago

andrewmurray commented 5 years ago

Is there a way to retrieve all of the keys of the items stored in cache?

glav commented 5 years ago

Not really no. Each cache engine has a different implementation and from memory, not each one supported it. There could be support added depending on the cache implenmentation tho and also added the a features supported. Alternatively for those that do not support it, we could use the parent-child relationship feature which tries to associate a parent key to multiple child keys and track it that way. A little inefficient in that scenario tho.

Jogai commented 5 years ago

Well, I did somethig like that for another memoryprovider. I'll share my code, maybe it helps you:

Using system.runtime cache is the easiest:

        using System.Runtime.Caching;

            List<string> cacheKeys = new List<string> { "supply", "known", "keys", "here" };

            MemoryCache currentCache = MemoryCache.Default;

            foreach (KeyValuePair<string, object> item in currentCache)
            {
                if (item.Key.StartsWith(String.Format(@"CachePrefix{0}", obj.Number)))
                {
                    cacheKeys.Add(item.Key);
                }
            }

            foreach (string cacheKey in cacheKeys)
            {
                currentCache.Remove(cacheKey);
            }

And for Microsoft.Extensions caching:

        using Microsoft.Extensions.Caching.Memory;
            List<string> cacheKeys = new List<string> { "supply", "known", "keys", "here" };

            //The next line is different, this depends if this cacheAdapter can do something like this
            MemoryCacheProvider provider = cache.CacheProvider as MemoryCacheProvider; 
            FieldInfo cacheInfo = provider.GetType().GetField("cache", BindingFlags.Instance | BindingFlags.NonPublic);
            MemoryCache currentCache = cacheInfo.GetValue(provider) as MemoryCache;

            PropertyInfo collectionInfo = currentCache.GetType().GetProperty("EntriesCollection", BindingFlags.NonPublic | BindingFlags.Instance);

            if (collectionInfo.GetValue(currentCache) is ICollection collection)
            {
                foreach (object item in collection)
                {
                    PropertyInfo keyInfo = item.GetType().GetProperty("Key");
                    string key = keyInfo.GetValue(item).ToString();
                    if (key.StartsWith(String.Format(@"CachePrefix{0}", obj.Number)))
                    {
                        cacheKeys.Add(key);
                    }
                }
            }

            foreach (string cacheKey in cacheKeys)
            {
                cache.Remove(cacheKey);
            }
glav commented 4 years ago

Thanks for this and apologies for the slow reply. Would be happy for you to PR this :-)