Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/jchristn/caching
Simple FIFO and LRU cache in C#
https://github.com/jchristn/caching
cache caching fifo fifo-cache lru lru-cache nuget
Last synced: 25 days ago
JSON representation
Simple FIFO and LRU cache in C#
- Host: GitHub
- URL: https://github.com/jchristn/caching
- Owner: jchristn
- License: mit
- Created: 2015-11-02T02:53:38.000Z (over 9 years ago)
- Default Branch: master
- Last Pushed: 2024-07-09T21:31:59.000Z (7 months ago)
- Last Synced: 2024-10-30T04:55:30.438Z (3 months ago)
- Topics: cache, caching, fifo, fifo-cache, lru, lru-cache, nuget
- Language: C#
- Homepage:
- Size: 5.23 MB
- Stars: 29
- Watchers: 3
- Forks: 5
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- Funding: .github/FUNDING.yml
- License: LICENSE.md
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
# Caching
Simple, fast, effective FIFO and LRU Cache with events and persistence.
[![NuGet Version](https://img.shields.io/nuget/v/Caching.svg?style=flat)](https://www.nuget.org/packages/Caching/) [![NuGet](https://img.shields.io/nuget/dt/Caching.svg)](https://www.nuget.org/packages/Caching)
This Caching library provides a simple implementation of a FIFO cache (first-in-first-out) and an LRU (least-recently-used) cache. It is written in C# and is designed to be thread-safe.
## New in v3.1.x- Expiration attribute for cached entries
- Minor refactor and bugfixes## Usage
Add reference to the Caching DLL and include the Caching namespace:
```csharp
using Caching;
```Initialize the desired cache:
```csharp
class Person
{
public string FirstName;
public string LastName;
}FIFOCache cache = new FIFOCache(capacity, evictCount);
LRUCache cache = new LRUCache(capacity, evictCount)// T1 is the type of the key
// T2 is the type of the value
// capacity (int) is the maximum number of entries
// evictCount (int) is the number to remove when the cache reaches capacity
// debug (boolean) enables console logging (use sparingly)
```Add an item to the cache:
```csharp
cache.AddReplace(key, data);
// key (T1) is a unique identifier
// data (T2) is whatever data you likebool success = cache.TryAddReplace(key, data);
if (!success) { ... }
```Add an item to the cache with expiration:
```csharp
cache.AddReplace(key, data, DateTime.UtcNow.AddSeconds(10));
bool success = cache.TryAddReplace(key, data, DateTime.UtcNow.AddSeconds(10));
```Get an item from the cache:
```csharp
Person data = cache.Get(key);
// throws KeyNotFoundException if not presentif (!cache.TryGet(key, out data))
{
// handle errors
}
else
{
// use your data!
}
```Remove an item from the cache:
```csharp
cache.Remove(key);
```Other helpful methods:
```csharp
T1 oldestKey = cache.Oldest();
T1 newestKey = cache.Newest();
int numEntries = cache.Count();
List keys = cache.GetKeys();
cache.Clear();
```Retrieve all cached contents (while preserving the cache):
```csharp
Dictionary dump = cache.All();
```## Persistence
If you wish to include a persistence layer with the cache, i.e. to store and manage cached objects on another repository in addition to memory:
1) Implement the ```IPersistenceDriver``` abstract class; refer to the ```Test.Persistence``` project for a sample implementation that uses a directory on the local hard drive
2) Instantiate the cache (```FIFOCache``` or ```LRUCache```) and pass the instance of the ```IPersistenceDriver``` into the constructor
3) If you wish to prepopulate the cache from the persistence driver, call ```.Prepopulate()``` before using the cache.
4) If you clear the cache, the persistence layer will also be cleared.```csharp
// implementation of PersistenceDriver
public class MyPersistenceDriver : IPersistenceDriver
{
public override void Delete(string key) { ... }
public override void Clear() { ... }
public override bool Exists(string key) { ... }
public override byte[] Get(string key) { ... }
public override void Write(string key, byte[] data) { ... }
public override byte[] ToBytes(object data) { ... }
public override T FromBytes(byte[] data) { ... }
public override List Enumerate() { ... }
}// instantiate the cache
MyPersistenceDriver persistence = new MyPersistenceDriver();
LRUCache cache = new LRUCache(capacity, evictCount, persistence);
cache.Prepopulate();
```As objects are written to the cache, they are added to persistent storage through the ```Write``` method. When they are removed or evicted, they are eliminated via the ```Delete``` method. When the cache is cleared, the persistence layer is also cleared.
## Events
If you wish to invoke events when certain cache actions are taken, attach event handlers to the entries found in ```FIFOCache.Events``` or ```LRUCache.Events```. These events are invoked synchronously after the associated cache operation.
```csharp
FIFOCache cache = new FIFOCache(_Capacity, _EvictCount);
cache.Events.Added += Added;
cache.Events.Cleared += Cleared;
cache.Events.Disposed += Disposed;
cache.Events.Evicted += Evicted;
cache.Events.Expired += Expired;
cache.Events.Prepopulated += Prepopulated;
cache.Events.Removed += Removed;
cache.Events.Replaced += Replaced;static void Replaced(object sender, DataEventArgs e)
{
Console.WriteLine("*** Cache entry " + e.Key + " replaced");
}static void Removed(object sender, DataEventArgs e)
{
Console.WriteLine("*** Cache entry " + e.Key + " removed");
}static void Prepopulated(object sender, DataEventArgs e)
{
Console.WriteLine("*** Cache entry " + e.Key + " prepopulated from persistent storage");
}static void Evicted(object sender, List e)
{
Console.WriteLine("*** Eviction event involving " + e.Count + " entries");
foreach (string curr in e) Console.WriteLine(" | " + curr);
}static void Expired(object sender, string key)
{
Console.WriteLine("*** Key " + key + " expired and removed from the cache");
}static void Disposed(object sender, EventArgs e)
{
Console.WriteLine("*** Disposed");
}static void Cleared(object sender, EventArgs e)
{
Console.WriteLine("*** Cache cleared");
}static void Added(object sender, DataEventArgs e)
{
Console.WriteLine("*** Cache entry " + e.Key + " added");
}
```## Version History
Refer to ```CHANGELOG.md``` for version history.