Aiursoft.InMemoryKvDb 1.0.4

There is a newer version of this package available.
See the version list below for details.
dotnet add package Aiursoft.InMemoryKvDb --version 1.0.4                
NuGet\Install-Package Aiursoft.InMemoryKvDb -Version 1.0.4                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Aiursoft.InMemoryKvDb" Version="1.0.4" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Aiursoft.InMemoryKvDb --version 1.0.4                
#r "nuget: Aiursoft.InMemoryKvDb, 1.0.4"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Aiursoft.InMemoryKvDb as a Cake Addin
#addin nuget:?package=Aiursoft.InMemoryKvDb&version=1.0.4

// Install Aiursoft.InMemoryKvDb as a Cake Tool
#tool nuget:?package=Aiursoft.InMemoryKvDb&version=1.0.4                

Aiursoft InMemoryKvDb

MIT licensed Pipeline stat Test Coverage NuGet version (Aiursoft.InMemoryKvDb) ManHours

Aiursoft InMemoryKvDb is a lightweight, thread-safe, in-memory key-value database with support for automatic Least Recently Used (LRU) cache eviction. It allows for efficient storage and retrieval of key-value pairs while preventing unbounded memory usage by leveraging configurable LRU eviction policies.

This library is ideal for scenarios where you need an in-memory cache that automatically discards the least recently accessed items, such as storing temporary user data, caching API responses, or handling in-memory operations for temporary data processing, without worrying about potential memory overflows.

Why this project

The traditional way to create an In-Memory Key-Value Database in C# is:

public class InMemoryDatabase : ISingletonDependency
{
    private ConcurrentDictionary<Guid, Player> Players { get; } = new();
    
    public Player GetOrAddPlayer(Guid id)
    {
        lock (Players)
        {
            return Players.GetOrAdd(id, _ => new Player(id)
            {
                NickName = "Anonymous " + new Random().Next(1000, 9999)
            });
        }
    }
    
}

However, if a hacker keeps calling GetOrAddPlayer with a new Guid, the Players dictionary will grow infinitely. And cause you OutOfMemoryException.

Installation

First, install Aiursoft.InMemoryKvDb to your ASP.NET Core project from nuget.org:

dotnet add package Aiursoft.InMemoryKvDb

Add the service to your IServiceCollection in Startup.cs (or Program.cs in .NET 6 and later):

Registering and Using Aiursoft.InMemoryKvDb with Different Methods

1. Service Registration Methods

Aiursoft.InMemoryKvDb offers four different registration methods to suit varying caching needs. Choose the one that fits your requirements:

1.1 Using AddNamedLruMemoryStore<T>

This method registers a named LruMemoryStore provider, where each name is associated with a separate LRU store.

services.AddNamedLruMemoryStore<Player>(
    id => new Player(id) { NickName = "Anonymous " + new Random().Next(1000, 9999) },
    maxCachedItemsCount: 4096);
  • onNotFound: A custom creation function that generates a new item when it is not found.
  • maxCachedItemsCount: Sets the maximum cache size. When this limit is exceeded, the LRU eviction mechanism is triggered.
1.2 Using AddNamedLruMemoryStoreManualCreate<T>

This method also registers a named LruMemoryStore provider, but it does not automatically invoke onNotFound when a new item needs to be created. Creation logic is managed manually.

services.AddNamedLruMemoryStoreManualCreate<Player>(maxCachedItemsCount: 2048);
  • Suitable for scenarios where auto-creation is not required or item generation needs manual control.
1.3 Using AddLruMemoryStore<T>

This method registers a regular LruMemoryStore that is not name-based, treating each store instance as a standalone entity.

services.AddLruMemoryStore<Player>(
    id => new Player(id) { NickName = "Guest" + new Random().Next(1000, 9999) },
    maxCachedItemsCount: 1024);
  • LruMemoryStore is suitable for simpler scenarios where named namespace management or switching between store instances is not necessary.
1.4 Using AddLruMemoryStoreManualCreate<T>

This method is similar to AddLruMemoryStore, but it does not auto-create new items, requiring manual addition and management.

services.AddLruMemoryStoreManualCreate<Player>(maxCachedItemsCount: 512);
  • Best suited for flexible data item management or specific creation control requirements.

2. Accessing the Store
2.1 Accessing NamedLruMemoryStoreProvider<T>

When using AddNamedLruMemoryStore or AddNamedLruMemoryStoreManualCreate, you can access specific named stores through NamedLruMemoryStoreProvider<T>.

var namedProvider = serviceProvider.GetRequiredService<NamedLruMemoryStoreProvider<Player>>();
var normalPlayerDb = namedProvider.GetStore("NormalPlayerDb");
var highLevelPlayerDb = namedProvider.GetStore("HighLevelPlayerDb");

// Retrieve or add a player
var playerId = Guid.NewGuid();
var player = normalPlayerDb.GetOrAdd(playerId);
2.2 Accessing LruMemoryStore<T>

When using AddLruMemoryStore or AddLruMemoryStoreManualCreate, you can directly use the store instance.

var store = serviceProvider.GetRequiredService<LruMemoryStore<Player>>();
var playerId = Guid.NewGuid();
var player = store.GetOrAdd(playerId);

3. LRU Eviction Mechanism

Regardless of the chosen storage type, all instances follow the LRU (Least Recently Used) strategy. When the cache reaches its maximum capacity, the least recently used items will be automatically evicted to free up space.

4. Configuration Options
  • maxCachedItemsCount: Controls the maximum cache size, triggering eviction when this limit is exceeded.
  • onNotFound (for auto-creating stores only): A custom function to generate new items when they are not found.

Example Scenario
services.AddNamedLruMemoryStore<Player>(
    id => new Player(id) { NickName = "Guest" + new Random().Next(1000, 9999) },
    maxCachedItemsCount: 2048);

By using AddNamedLruMemoryStore, you can efficiently cache player data across different namespaces while ensuring controlled memory usage, reducing the risk of OutOfMemoryException.


Choosing the Right Method

  • Auto-Create: Ideal for automatically generating cached objects and reducing code complexity.
  • Manual-Create: Suitable for scenarios requiring fine-grained control over data creation logic.
  • Named Stores: Useful for distinguishing data storage across different contexts.
  • Non-Named Stores: Best for simpler caching needs.

Contributing

Contributions are welcome! Please open an issue or submit a pull request for any feature requests, bug fixes, or other improvements.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.0.6 199 11/11/2024
1.0.5 96 11/11/2024
1.0.4 93 11/11/2024
1.0.3 91 11/11/2024
1.0.2 90 11/11/2024
1.0.1 92 11/11/2024