Tip
To create a thread-safe IThreadSafeCacheAccessorTKey, TValue instance that fits the best for your needs use the members of the ThreadSafeCacheFactory class.
[SerializableAttribute]
public class Cache<TKey, TValue> : IDictionary<TKey, TValue>,
ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>,
IEnumerable, ICache, IDictionary, ICollection, ISerializable,
IDeserializationCallback, IReadOnlyDictionary<TKey, TValue>, IReadOnlyCollection<KeyValuePair<TKey, TValue>>
<SerializableAttribute>
Public Class Cache(Of TKey, TValue)
Implements IDictionary(Of TKey, TValue), ICollection(Of KeyValuePair(Of TKey, TValue)),
IEnumerable(Of KeyValuePair(Of TKey, TValue)), IEnumerable,
ICache, IDictionary, ICollection, ISerializable, IDeserializationCallback,
IReadOnlyDictionary(Of TKey, TValue), IReadOnlyCollection(Of KeyValuePair(Of TKey, TValue))
[SerializableAttribute]
generic<typename TKey, typename TValue>
public ref class Cache : IDictionary<TKey, TValue>,
ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>,
IEnumerable, ICache, IDictionary, ICollection, ISerializable,
IDeserializationCallback, IReadOnlyDictionary<TKey, TValue>, IReadOnlyCollection<KeyValuePair<TKey, TValue>>
[<SerializableAttribute>]
type Cache<'TKey, 'TValue> =
class
interface IDictionary<'TKey, 'TValue>
interface ICollection<KeyValuePair<'TKey, 'TValue>>
interface IEnumerable<KeyValuePair<'TKey, 'TValue>>
interface IEnumerable
interface ICache
interface IDictionary
interface ICollection
interface ISerializable
interface IDeserializationCallback
interface IReadOnlyDictionary<'TKey, 'TValue>
interface IReadOnlyCollection<KeyValuePair<'TKey, 'TValue>>
end
CacheTKey, TValue type provides a fast-access storage with limited capacity and transparent access. If you need to store items that are expensive to retrieve (for example from a database or remote service) and you don't want to run out of memory because of just storing newer and newer elements without getting rid of old ones, then this type might fit your expectations. Once a value is stored in the cache, its retrieval by using its key is very fast, close to O(1).
A cache store must meet the following three criteria:
Since CacheTKey, TValue implements IDictionaryTKey, TValue interface, Add, Remove, ContainsKey and TryGetValue methods are available for it, and these methods work exactly the same way as in case the DictionaryTKey, TValue type. But using these methods usually are not necessary, unless we want to manually manage cache content or when cache is initialized without an item loader. Normally after cache is instantiated, it is needed to be accessed only by the getter accessor of its indexer.
using System;
using System.Collections.Generic;
using KGySoft.Collections;
class Example
{
private static Cache<int, bool> isPrimeCache;
public static void Main()
{
// Cache capacity is initialized to store maximum 4 values
isPrimeCache = new Cache<int, bool>(ItemLoader, 4);
// If cache is full the least recent used element will be deleted
isPrimeCache.Behavior = CacheBehavior.RemoveLeastRecentUsedElement;
// cache is now empty
DumpCache();
// reading the cache invokes the loader method
CheckPrime(13);
// reading a few more values
CheckPrime(23);
CheckPrime(33);
CheckPrime(43);
// dumping content
DumpCache();
// accessing an already read item does not invoke loader again
// Now it changes cache order because of the chosen behavior
CheckPrime(13);
DumpCache();
// reading a new element with full cache will delete an old one (now 23)
CheckPrime(111);
DumpCache();
// but accessing a deleted element causes to load it again
CheckPrime(23);
DumpCache();
// dumping some statistics
Console.WriteLine(isPrimeCache.GetStatistics().ToString());
}
// This is the item loader method. It can access database or perform slow calculations.
// If cache is meant to be serialized it should be a static method rather than an anonymous delegate or lambda expression.
private static bool ItemLoader(int number)
{
Console.WriteLine("Item loading has been invoked for value {0}", number);
// In this example item loader checks whether the given number is a prime by a not too efficient algorithm.
if (number <= 1)
return false;
if (number % 2 == 0)
return true;
int i = 3;
int sqrt = (int)Math.Floor(Math.Sqrt(number));
while (i <= sqrt)
{
if (number % i == 0)
return false;
i += 2;
}
return true;
}
private static void CheckPrime(int number)
{
// cache is used transparently here: indexer is always just read
bool isPrime = isPrimeCache[number];
Console.WriteLine("{0} is a prime: {1}", number, isPrime);
}
private static void DumpCache()
{
Console.WriteLine();
Console.WriteLine("Cache elements count: {0}", isPrimeCache.Count);
if (isPrimeCache.Count > 0)
{
// enumerating through the cache shows the elements in the evaluation order
Console.WriteLine("Cache elements:");
foreach (KeyValuePair<int, bool> item in isPrimeCache)
{
Console.WriteLine("\tKey: {0},\tValue: {1}", item.Key, item.Value);
}
}
Console.WriteLine();
}
}
// This code example produces the following output:
//
// Cache elements count: 0
//
// Item loading has been invoked for value 13
// 13 is a prime: True
// Item loading has been invoked for value 23
// 23 is a prime: True
// Item loading has been invoked for value 33
// 33 is a prime: False
// Item loading has been invoked for value 43
// 43 is a prime: True
//
// Cache elements count: 4
// Cache elements:
// Key: 13, Value: True
// Key: 23, Value: True
// Key: 33, Value: False
// Key: 43, Value: True
//
// 13 is a prime: True
//
// Cache elements count: 4
// Cache elements:
// Key: 23, Value: True
// Key: 33, Value: False
// Key: 43, Value: True
// Key: 13, Value: True
//
// Item loading has been invoked for value 111
// 111 is a prime: False
//
// Cache elements count: 4
// Cache elements:
// Key: 33, Value: False
// Key: 43, Value: True
// Key: 13, Value: True
// Key: 111, Value: False
//
// Item loading has been invoked for value 23
// 23 is a prime: True
//
// Cache elements count: 4
// Cache elements:
// Key: 43, Value: True
// Key: 13, Value: True
// Key: 111, Value: False
// Key: 23, Value: True
//
// Cache<Int32, Boolean> cache statistics:
// Count: 4
// Capacity: 4
// Number of writes: 6
// Number of reads: 7
// Number of cache hits: 1
// Number of deletes: 2
// Hit rate: 14,29%
CacheTKey, TValue | Initializes a new instance of the CacheTKey, TValue class with default capacity of 128 and no item loader. |
CacheTKey, TValue(IEqualityComparerTKey) | Initializes a new instance of the CacheTKey, TValue class with the specified comparer, default capacity of 128 and no item loader. |
CacheTKey, TValue(FuncTKey, TValue, IEqualityComparerTKey) | Creates a new CacheTKey, TValue instance with the given itemLoader and comparer using default capacity of 128. |
CacheTKey, TValue(IDictionaryTKey, TValue, IEqualityComparerTKey) | Initializes a new instance of the CacheTKey, TValue class from the specified dictionary and comparer, with no item loader. The Capacity will be initialized to the number of elements in dictionary. |
CacheTKey, TValue(Int32, IEqualityComparerTKey) | Initializes a new instance of the CacheTKey, TValue class with specified capacity capacity and comparer and no item loader. |
CacheTKey, TValue(SerializationInfo, StreamingContext) | Initializes a new instance of the CacheTKey, TValue class from serialized data. |
CacheTKey, TValue(FuncTKey, TValue, Int32, IEqualityComparerTKey) | Creates a new CacheTKey, TValue instance with the given itemLoader, capacity and comparer. |
Behavior | Gets or sets the cache behavior when cache is full and an element has to be removed. The cache is full, when Count reaches the Capacity. Default value: RemoveLeastRecentUsedElement. |
Capacity |
Gets or sets the capacity of the cache. If new value is smaller than elements count (value of the Count property),
then old or least used elements (depending on Behavior) will be removed from CacheTKey, TValue.
Default value: 128, if the CacheTKey, TValue was initialized without specifying a capacity; otherwise, as it was initialized. |
Comparer | Gets the IEqualityComparerT that is used to determine equality of keys for this CacheTKey, TValue. |
Count | Gets number of elements currently stored in this CacheTKey, TValue instance. |
DisposeDroppedValues |
Gets or sets whether internally dropped values are disposed if they implement IDisposable.
Default value: . |
EnsureCapacity |
Gets or sets whether adding the first item to the cache or resetting Capacity on a non-empty cache should
allocate memory for all cache entries.
Default value: , unless you use the IDictionaryTKey, TValue initializer constructor, which initializes this property to . |
Item | Gets or sets the value associated with the specified key. When an element with a non-existing key is read, and an item loader was specified by the appropriate constructor, then the value is retrieved by the specified loader delegate of this CacheTKey, TValue instance. |
Keys | Gets the keys stored in the cache in evaluation order. |
Values | Gets the values stored in the cache in evaluation order. |
Add | Adds an element with the provided key and value to the CacheTKey, TValue. |
Clear | Removes all keys and values from the CacheTKey, TValue. |
ContainsKey | Determines whether the CacheTKey, TValue contains a specific key. |
ContainsValue | Determines whether the CacheTKey, TValue contains a specific value. |
GetEnumerator | Returns an enumerator that iterates through the CacheTKey, TValue elements in the evaluation order. |
GetObjectData | In a derived class populates a SerializationInfo with the additional data of the derived type needed to serialize the target object. |
GetStatistics | Gets an ICacheStatistics instance that provides statistical information about this CacheTKey, TValue. |
GetThreadSafeAccessor | Gets a thread safe accessor for this CacheTKey, TValue instance. As it provides only a single readable indexer, it makes sense only if an item loader was passed to the appropriate constructor and the cache will not be accessed by other members but via the returned accessor. |
GetValueUncached | Loads the value of the key even if it already exists in the CacheTKey, TValue by using the item loader that was passed to the constructor. |
OnDeserialization | In a derived class restores the state the deserialized instance. |
RefreshValue | Refreshes the value of the key in the CacheTKey, TValue even if it already exists in the cache by using the item loader that was passed to the constructor. |
Remove | Removes the value with the specified key from the CacheTKey, TValue. |
Reset | Clears the CacheTKey, TValue and resets statistics. |
Touch | Renews the value with the specified key in the evaluation order. |
TryGetValue | Tries to gets the value associated with the specified key without using the item loader passed to the constructor. |
AddRangeKeyValuePairTKey, TValue |
Adds a collection to the target ICollectionT.
(Defined by CollectionExtensions) |
AsThreadSafeKeyValuePairTKey, TValue |
Returns a LockingCollectionT, which provides a thread-safe wrapper for the specified collection.
This only means that if the members are accessed through the returned LockingCollectionT, then the inner state of the wrapped collection remains always consistent and not that all the multi-threading concerns can be ignored.
See the Remarks section of the LockingCollectionT class for details and some examples. (Defined by CollectionExtensions) |
Convert |
Converts an Object specified in the obj parameter to the desired targetType.
See the Examples section of the generic ConvertTTarget(Object, CultureInfo) overload for an example. (Defined by ObjectExtensions) |
ConvertTTarget |
Converts an Object specified in the obj parameter to the desired TTarget.
(Defined by ObjectExtensions) |
ForEachKeyValuePairTKey, TValue |
Similarly to the List<T>.ForEach method, processes an action on each element of an enumerable collection.
(Defined by EnumerableExtensions) |
GetRandomElementKeyValuePairTKey, TValue |
Gets a random element from the enumerable source using a new FastRandom instance.
(Defined by EnumerableExtensions) |
GetRandomElementKeyValuePairTKey, TValue |
Gets a random element from the enumerable source using a specified Random instance.
(Defined by EnumerableExtensions) |
In |
Gets whether item is among the elements of set.
See the Examples section of the generic InT(T, T) overload for an example. (Defined by ObjectExtensions) |
IndexOf |
Searches for an element in the source enumeration where the specified predicate returns .
(Defined by EnumerableExtensions) |
IndexOf |
Searches for an element in the source enumeration.
(Defined by EnumerableExtensions) |
IndexOfKeyValuePairTKey, TValue |
Searches for an element in the source enumeration where the specified predicate returns .
(Defined by EnumerableExtensions) |
IndexOfKeyValuePairTKey, TValue |
Searches for an element in the source enumeration.
(Defined by EnumerableExtensions) |
IsNullOrEmpty |
Determines whether the specified source is or empty (has no elements).
(Defined by EnumerableExtensions) |
IsNullOrEmptyKeyValuePairTKey, TValue |
Determines whether the specified source is or empty (has no elements).
(Defined by EnumerableExtensions) |
JoinKeyValuePairTKey, TValue |
Concatenates the items of the source collection into a new string instance
using the specified separator between the items.
(Defined by EnumerableExtensions) |
JoinKeyValuePairTKey, TValue |
Concatenates the items of the source collection into a new string instance
using the specified separator between the items.
(Defined by EnumerableExtensions) |
ShuffleKeyValuePairTKey, TValue |
Shuffles an enumerable source (randomizes its elements) using a new FastRandom instance.
(Defined by EnumerableExtensions) |
ShuffleKeyValuePairTKey, TValue |
Shuffles an enumerable source (randomizes its elements) using the provided seed with a new FastRandom instance.
(Defined by EnumerableExtensions) |
ShuffleKeyValuePairTKey, TValue |
Shuffles an enumerable source (randomizes its elements) using the provided seed with a new FastRandom instance.
(Defined by EnumerableExtensions) |
ShuffleKeyValuePairTKey, TValue |
Shuffles an enumerable source (randomizes its elements) using a specified Random instance.
(Defined by EnumerableExtensions) |
ToCircularListKeyValuePairTKey, TValue |
Creates a CircularListT from an IEnumerableT.
(Defined by EnumerableExtensions) |
ToStringKeyedDictionaryKeyValuePairTKey, TValue |
Creates a StringKeyedDictionaryTValue from an IEnumerableT instance using the specified keySelector delegate and a comparer.
(Defined by EnumerableExtensions) |
ToStringKeyedDictionaryKeyValuePairTKey, TValue, TValue |
Creates a StringKeyedDictionaryTValue from an IEnumerableT instance using the specified key and value selector delegates and a comparer.
(Defined by EnumerableExtensions) |
TryAdd |
Tries to add the specified item to the collection.
(Defined by EnumerableExtensions) |
TryAddKeyValuePairTKey, TValue |
Tries to add the specified item to the collection.
(Defined by EnumerableExtensions) |
TryAddRange |
Tries to add the specified collection to the target collection.
(Defined by EnumerableExtensions) |
TryAddRangeKeyValuePairTKey, TValue |
Tries to add the specified collection to the target collection.
(Defined by EnumerableExtensions) |
TryClear |
Tries to remove all elements from the collection.
(Defined by EnumerableExtensions) |
TryClearKeyValuePairTKey, TValue |
Tries to remove all elements from the collection.
(Defined by EnumerableExtensions) |
TryConvert |
Tries to convert an Object specified in the obj parameter to the desired targetType.
See the Examples section of the ConvertTTarget(Object, CultureInfo) method for a related example. (Defined by ObjectExtensions) |
TryConvert |
Tries to convert an Object specified in the obj parameter to the desired targetType.
See the Examples section of the ConvertTTarget(Object, CultureInfo) method for a related example. (Defined by ObjectExtensions) |
TryConvertTTarget |
Tries to convert an Object specified in the obj parameter to the desired TTarget.
See the Examples section of the ConvertTTarget(Object, CultureInfo) method for a related example. (Defined by ObjectExtensions) |
TryConvertTTarget |
Tries to convert an Object specified in the obj parameter to the desired TTarget.
See the Examples section of the ConvertTTarget(Object, CultureInfo) method for a related example. (Defined by ObjectExtensions) |
TryGetCount |
Tries to get the number of elements in the source enumeration without enumerating it.
(Defined by EnumerableExtensions) |
TryGetCountKeyValuePairTKey, TValue |
Tries to get the number of elements in the source enumeration without enumerating it.
(Defined by EnumerableExtensions) |
TryGetElementAt |
Tries to get an item at the specified index in the collection.
(Defined by EnumerableExtensions) |
TryGetElementAtKeyValuePairTKey, TValue |
Tries to get an item at the specified index in the collection.
(Defined by EnumerableExtensions) |
TryInsert |
Tries to insert the specified item at the specified index to the collection.
(Defined by EnumerableExtensions) |
TryInsertKeyValuePairTKey, TValue |
Tries to insert the specified item at the specified index to the collection.
(Defined by EnumerableExtensions) |
TryInsertRange |
Tries to insert the specified collection into the target collection.
(Defined by EnumerableExtensions) |
TryInsertRangeKeyValuePairTKey, TValue |
Tries to insert the specified collection into the target collection.
(Defined by EnumerableExtensions) |
TryRemove |
Tries to remove the specified item from to the collection.
(Defined by EnumerableExtensions) |
TryRemoveKeyValuePairTKey, TValue |
Tries to remove the specified item from to the collection.
(Defined by EnumerableExtensions) |
TryRemoveAt |
Tries to remove an item at the specified index from the collection.
(Defined by EnumerableExtensions) |
TryRemoveAtKeyValuePairTKey, TValue |
Tries to remove an item at the specified index from the collection.
(Defined by EnumerableExtensions) |
TryRemoveRange |
Tries to remove count amount of items from the specified collection at the specified index.
(Defined by EnumerableExtensions) |
TryRemoveRangeKeyValuePairTKey, TValue |
Tries to remove count amount of items from the specified collection at the specified index.
(Defined by EnumerableExtensions) |
TryReplaceRange |
Tries to remove count amount of items from the target at the specified index, and
to insert the specified collection at the same position. The number of elements in collection can be different from the amount of removed items.
(Defined by EnumerableExtensions) |
TryReplaceRangeKeyValuePairTKey, TValue |
Tries to remove count amount of items from the target at the specified index, and
to insert the specified collection at the same position. The number of elements in collection can be different from the amount of removed items.
(Defined by EnumerableExtensions) |
TrySetElementAt |
Tries to set the specified item at the specified index in the collection.
(Defined by EnumerableExtensions) |
TrySetElementAtKeyValuePairTKey, TValue |
Tries to set the specified item at the specified index in the collection.
(Defined by EnumerableExtensions) |