Skip to content

Generic in-memory cache manager, with optional capacity limit and LFU+LRU eviction policy.

Notifications You must be signed in to change notification settings

erancha/CacheManager

Repository files navigation

CacheManager

This solution contains a simple generic in-memory cache manager and two console applications:

  • CacheManager.Core

    • Class library with a generic cache manager interface and implementation using Dictionary<TKey, TValue>.
    • Types:
      • ICacheManager<TKey, TValue>: basic Put, TryGet, Remove, and Snapshot operations.
      • CacheManager<TKey, TValue>: concrete implementation backed by Dictionary<TKey, TValue>.
        • Optional capacity-limited mode with LFU (Least Frequently Used) eviction and LRU (Least Recently Used) as a tie-breaker.
          • Default: unlimited capacity (no eviction), created with new CacheManager<TKey, TValue>().
          • Bounded: new CacheManager<TKey, TValue>(maxEntries: 100) enables LFU+LRU-based eviction when the number of items exceeds maxEntries.
  • CacheManager.OpGenerator

    • Console app that generates a randomized sequence of cache operations (PUT / GET / REMOVE).
    • Writes them into a text file named cache_input_operations.txt in the solution root.
  • CacheManager.Tester

    • Console app that reads cache_input_operations.txt, executes the operations on the cache, and then:
      • Writes the final cache state into cache_baseline_*.txt (if it does not yet exist).
      • On subsequent runs, compares the new cache state to the existing cache_baseline_*.txt to check for consistent behavior.
      • Supports testing with different cache capacities to validate eviction behavior.

Prerequisites

  • .NET SDK 8 (or later compatible) installed.

How to run

From a terminal / bash shell, go to the solution folder:

cd /mnt/c/Projects/CacheManager

1. Generate randomized operations

By default, the generator creates 1000 operations over 100 keys.

dotnet run --project ./CacheManager.OpGenerator/CacheManager.OpGenerator.csproj

You can optionally pass:

  • First argument: number of operations
  • Second argument: number of distinct keys

Example (1000000 operations over 10000 keys):

dotnet run --project ./CacheManager.OpGenerator/CacheManager.OpGenerator.csproj -- 1000000 10000

This creates or overwrites cache_input_operations.txt in /mnt/c/Projects/CacheManager.

2. Execute operations and write/compare cache state

The tester accepts two optional parameters:

  • First argument: number of test iterations (how many times to replay cache_input_operations.txt before snapshot/compare).
  • Second argument: max entries (maximum number of cache entries before eviction kicks in). If omitted or non-positive, the cache is unlimited.

Understanding Max Entries

The max entries parameter controls the maximum number of entries the cache can hold before eviction occurs:

  • Unlimited entries (default): max entries is omitted, null, or non-positive

    • No eviction occurs regardless of cache size
    • Creates snapshot file: cache_baseline_unlimited.txt
    • Example: dotnet run --project ./CacheManager.Tester/CacheManager.Tester.csproj
  • Limited entries: max entries is a positive integer

    • When cache exceeds this limit, LFU+LRU eviction is triggered
    • LFU (Least Frequently Used): Items with lowest access count are evicted first
    • LRU (Least Recently Used): Among items with same access count, least recently accessed is evicted
    • Creates snapshot file: cache_baseline_max_entries_{max_entries}.txt
    • Example: dotnet run --project ./CacheManager.Tester/CacheManager.Tester.csproj -- 10 1000

Eviction Behavior Examples

# Test with unlimited capacity (no eviction) - run operations 10 times
dotnet run --project ./CacheManager.Tester/CacheManager.Tester.csproj -- 10

# Test with max entries of 50 - run operations 10 times
dotnet run --project ./CacheManager.Tester/CacheManager.Tester.csproj -- 10 50

# Test with max entries of 100 - run operations 10 times
dotnet run --project ./CacheManager.Tester/CacheManager.Tester.csproj -- 10 100

Arguments:

  • First argument (optional): Number of iterations to run the operations (default: 1)
  • Second argument (optional): Maximum cache entries for eviction testing (default: unlimited)

Each max entries setting creates its own baseline file, allowing you to test and compare behavior across different cache sizes.

Behavior:

  • First run: creates cache_baseline.txt from the current final cache contents and reports that a baseline snapshot was written.
  • Subsequent runs with the same cache_input_operations.txt: prints a message indicating whether the behavior is consistent with the previous run and shows the elapsed time for the execution.

Quick Test All Implementations

To run all three implementations (C#, Node.js, and Java) at once:

./test-all.sh

The test-all.sh script supports the following parameters:

Parameters

  • --max-entries N: Set maximum cache entries for eviction testing (default: unlimited)
  • --iterations N: Set number of test iterations (default: 1)
  • --help: Show help message with usage examples

Usage Examples

# Run with unlimited cache (default behavior)
./test-all.sh

# Run with 1000 entry limit to test eviction behavior
./test-all.sh --max-entries 1000

# Run 5 iterations with 1000 entry limit
./test-all.sh --max-entries 1000 --iterations 5

# Show help and available options
./test-all.sh --help

About

Generic in-memory cache manager, with optional capacity limit and LFU+LRU eviction policy.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published