{"id":22835222,"url":"https://github.com/jchristn/caching","last_synced_at":"2025-07-16T22:37:07.625Z","repository":{"id":60772367,"uuid":"45368820","full_name":"jchristn/Caching","owner":"jchristn","description":"Simple FIFO and LRU cache in C#","archived":false,"fork":false,"pushed_at":"2025-01-07T15:21:02.000Z","size":5490,"stargazers_count":33,"open_issues_count":0,"forks_count":6,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-06-28T02:05:00.091Z","etag":null,"topics":["cache","caching","fifo","fifo-cache","lru","lru-cache","nuget"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jchristn.png","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","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":["jchristn"],"custom":["https://paypal.me/joelchristner"]}},"created_at":"2015-11-02T02:53:38.000Z","updated_at":"2025-06-18T12:09:02.000Z","dependencies_parsed_at":"2025-05-05T03:51:38.302Z","dependency_job_id":null,"html_url":"https://github.com/jchristn/Caching","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/jchristn/Caching","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jchristn%2FCaching","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jchristn%2FCaching/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jchristn%2FCaching/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jchristn%2FCaching/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jchristn","download_url":"https://codeload.github.com/jchristn/Caching/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jchristn%2FCaching/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265546431,"owners_count":23785969,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cache","caching","fifo","fifo-cache","lru","lru-cache","nuget"],"created_at":"2024-12-12T22:08:44.758Z","updated_at":"2025-07-16T22:37:07.585Z","avatar_url":"https://github.com/jchristn.png","language":"C#","funding_links":["https://github.com/sponsors/jchristn","https://paypal.me/joelchristner"],"categories":[],"sub_categories":[],"readme":"# Caching\n\nSimple, fast, effective FIFO and LRU Cache with events and persistence.\n\n [![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) \n\nThis 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.\n \n## New in v3.1.x\n\n- Expiration attribute for cached entries\n- Minor refactor and bugfixes\n\n## Usage\n\nAdd reference to the Caching DLL and include the Caching namespace:\n```csharp\nusing Caching;\n```\n\nInitialize the desired cache:\n```csharp\nclass Person\n{\n  public string FirstName;\n  public string LastName;\n}\n\nFIFOCache\u003cstring, Person\u003e cache = new FIFOCache\u003cstring, Person\u003e(capacity, evictCount);\nLRUCache\u003cstring, Person\u003e cache = new LRUCache\u003cstring, Person\u003e(capacity, evictCount) \n\n// T1 is the type of the key\n// T2 is the type of the value\n// capacity (int) is the maximum number of entries\n// evictCount (int) is the number to remove when the cache reaches capacity\n// debug (boolean) enables console logging (use sparingly)\n```\n\nAdd an item to the cache:\n```csharp\ncache.AddReplace(key, data);\n// key (T1) is a unique identifier\n// data (T2) is whatever data you like\n\nbool success = cache.TryAddReplace(key, data);\nif (!success) { ... }\n```\n\nAdd an item to the cache with expiration:\n```csharp\ncache.AddReplace(key, data, DateTime.UtcNow.AddSeconds(10));\nbool success = cache.TryAddReplace(key, data, DateTime.UtcNow.AddSeconds(10));\n```\n\nGet an item from the cache:\n```csharp\nPerson data = cache.Get(key);\n// throws KeyNotFoundException if not present\n\nif (!cache.TryGet(key, out data)) \n{ \n  // handle errors \n}\nelse \n{ \n  // use your data! \n}\n```\n\nRemove an item from the cache:\n```csharp\ncache.Remove(key);\n```\n\nOther helpful methods:\n```csharp\nT1 oldestKey = cache.Oldest();\nT1 newestKey = cache.Newest();\nint numEntries = cache.Count();\nList\u003cT1\u003e keys = cache.GetKeys();\ncache.Clear();\n```\n\nRetrieve all cached contents (while preserving the cache):\n```csharp\nDictionary\u003cT1, T2\u003e dump = cache.All();\n```\n\n## Persistence\n\nIf 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:\n\n1) Implement the ```IPersistenceDriver``` abstract class; refer to the ```Test.Persistence``` project for a sample implementation that uses a directory on the local hard drive\n2) Instantiate the cache (```FIFOCache``` or ```LRUCache```) and pass the instance of the ```IPersistenceDriver``` into the constructor\n3) If you wish to prepopulate the cache from the persistence driver, call ```.Prepopulate()``` before using the cache.\n4) If you clear the cache, the persistence layer will also be cleared.\n\n```csharp\n// implementation of PersistenceDriver\npublic class MyPersistenceDriver : IPersistenceDriver\n{\n  public override void Delete(string key) { ... }\n  public override void Clear() { ... }\n  public override bool Exists(string key) { ... }\n  public override byte[] Get(string key) { ... }\n  public override void Write(string key, byte[] data) { ... }\n  public override byte[] ToBytes(object data) { ... }\n  public override T FromBytes\u003cT\u003e(byte[] data) { ... }\n  public override List\u003cstring\u003e Enumerate() { ... }\n}\n\n// instantiate the cache\nMyPersistenceDriver persistence = new MyPersistenceDriver();\nLRUCache\u003cstring, byte[]\u003e cache = new LRUCache\u003cstring, byte[]\u003e(capacity, evictCount, persistence);\ncache.Prepopulate();\n```\n\nAs 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.\n\n## Events\n\nIf 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.\n\n```csharp\nFIFOCache\u003cstring, byte[]\u003e cache = new FIFOCache\u003cstring, byte[]\u003e(_Capacity, _EvictCount);\ncache.Events.Added += Added;\ncache.Events.Cleared += Cleared;\ncache.Events.Disposed += Disposed;\ncache.Events.Evicted += Evicted;\ncache.Events.Expired += Expired;\ncache.Events.Prepopulated += Prepopulated;\ncache.Events.Removed += Removed;\ncache.Events.Replaced += Replaced;\n\nstatic void Replaced(object sender, DataEventArgs\u003cstring, byte[]\u003e e)\n{\n    Console.WriteLine(\"*** Cache entry \" + e.Key + \" replaced\");\n}\n\nstatic void Removed(object sender, DataEventArgs\u003cstring, byte[]\u003e e)\n{\n    Console.WriteLine(\"*** Cache entry \" + e.Key + \" removed\");\n}\n\nstatic void Prepopulated(object sender, DataEventArgs\u003cstring, byte[]\u003e e)\n{\n    Console.WriteLine(\"*** Cache entry \" + e.Key + \" prepopulated from persistent storage\");\n}\n\nstatic void Evicted(object sender, List\u003cstring\u003e e)\n{\n    Console.WriteLine(\"*** Eviction event involving \" + e.Count + \" entries\");\n    foreach (string curr in e) Console.WriteLine(\"    | \" + curr);\n}\n\nstatic void Expired(object sender, string key)\n{\n    Console.WriteLine(\"*** Key \" + key + \" expired and removed from the cache\");\n}\n\nstatic void Disposed(object sender, EventArgs e)\n{\n    Console.WriteLine(\"*** Disposed\");\n}\n\nstatic void Cleared(object sender, EventArgs e)\n{\n    Console.WriteLine(\"*** Cache cleared\");\n}\n\nstatic void Added(object sender, DataEventArgs\u003cstring, byte[]\u003e e)\n{\n    Console.WriteLine(\"*** Cache entry \" + e.Key + \" added\");\n}\n```\n\n## Version History\n\nRefer to ```CHANGELOG.md``` for version history.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjchristn%2Fcaching","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjchristn%2Fcaching","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjchristn%2Fcaching/lists"}