Skip to content

A thread-safe, lazy-loading cache for .NET applications that provides automatic indexing of the cached items

License

Notifications You must be signed in to change notification settings

rent-a-developer/AutoIndexCache

Repository files navigation

license semver

AutoIndexCache

A thread-safe cache for .NET applications that provides automatic indexing of the cached items.

using System;
using AutoIndexCache;

public class User
{
    public Int64 GroupId { get; set; }
    public Int64 Id { get; set; }
    public Boolean IsActive { get; set; }
    public String UserName { get; set; }
}

public class Program
{
    public static void Main(String[] args)
    {
        var cache = new AutoIndexCache();

        // Fill the cache with items:
        cache.Items<User>().Fill(LoadUsers());

        // Get all users:
        cache.Items<User>().GetAllItems();

        // Get the user that has the Id 1:
        cache.Items<User>().UniqueIndex(a => a.Id).GetItemOrDefault(1);

        // Get all users that belong to group 1:
        cache.Items<User>().NonUniqueIndex(a => a.GroupId).GetItems(1);

        // Get all active users of group 10:
        cache.Items<User>().NonUniqueIndex(a => (a.IsActive, a.GroupId)).GetItems((true, 10));

        // Get all Ids of users:
        cache.Items<User>().UniqueIndex(a => a.Id).GetKeys();
    }

    private static User[] LoadUsers()
    {
        var result = new User[10_000];

        for (var i = 1; i <= result.Length; i++)
        {
            result[i-1] = new() { Id = i, UserName = "User " + i, GroupId = i % 2 == 0 ? 2 : 1, IsActive = i % 2 == 0 };
        }

        return result;
    }
}

Performance

AutoIndexCache is blazingly fast (as a cache should be).
However, some overhead is still needed to make it thread-safe and for the auto indexing, so a hand crafted custom solution might be even faster.

Benchmarks

In the following benchmarks AutoIndexCache is compared to the Dictionary<TKey,TValue> type.
You can find the source code of the bechmarks here.

image

Explanation

..._Dicationary

In these benchmarks the Dictionary<TKey,TValue> is used to index cached items.
There is hardly any faster soltuion in .NET to index cached items.
However, the Dictionary is completely non-thread-safe.

..._AutoIndexCache

In these benchmarks the AutoIndexCache is used.

..._AutoIndexCacheOptimized

In these bechmarks, also, the AutoIndexCache is used.
However, a trick was applied to drastically improve the performance:

To access cached items you need to call the AutoIndexCache.Items method.
And to access indexes you need to call the ItemsList.NonUniqueIndex and ItemsList.UniqueIndex methods.
These methods have some overhead, because they need to be thread-safe.

Instead of calling these method each time you want to access cached items or indexes, you can just call them once and store their return values in fields (so in essence, you are caching the cache 😃).
This way the performance of the cache is improved drastically.

So instead of this:

class Service
{
    private readonly AutoIndexCache cache;

    public Service(AutoIndexCache cache)
    {
        this.cache = cache;
    }

    public User? GetUserById(Int64 id)
    {
        return this.cache.Items<User>().UniqueIndex(a => a.Id).GetItemOrDefault(id);
    }
}

you do this:

class Service
{
    private readonly AutoIndexCache cache;
    private readonly IItemList<User> users;
    private readonly IUniqueIndex<User, Int32> userById;

    public Service(AutoIndexCache cache)
    {
        this.cache = cache;
        this.users = this.cache.Items<User>();
        this.userById = this.users.UniqueIndex(a => a.Id);
    }

    public User? GetUserById(Int64 id)
    {
        return this.userById.GetItemOrDefault(id);
    }
}

License

This library is licensed under the MIT license.

Installation

First, install NuGet.

Then download a release from the releases page and install via the NuGet Package Manager:

PM> Install-Package AutoIndexCache -Source PathToTheNuGetPackage

Documentation

The API documentation can be found here.

Contributors

Main contributors

About

A thread-safe, lazy-loading cache for .NET applications that provides automatic indexing of the cached items

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages