< Summary

Information
Class: Intentum.AI.Caching.Redis.RedisEmbeddingCache
Assembly: Intentum.AI.Caching.Redis
File(s): /home/runner/work/Intentum/Intentum/src/Intentum.AI.Caching.Redis/RedisEmbeddingCache.cs
Line coverage
92%
Covered lines: 48
Uncovered lines: 4
Coverable lines: 52
Total lines: 100
Line coverage: 92.3%
Branch coverage
75%
Covered branches: 9
Total branches: 12
Branch coverage: 75%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.cctor()100%11100%
.ctor(...)100%11100%
.ctor(...)50%44100%
Get(...)100%44100%
Set(...)100%11100%
Remove(...)100%11100%
Clear()100%110%
GetCacheKey(...)100%11100%
Serialize(...)100%22100%
Deserialize(...)50%2283.33%

File(s)

/home/runner/work/Intentum/Intentum/src/Intentum.AI.Caching.Redis/RedisEmbeddingCache.cs

#LineLine coverage
 1using System.Text.Json;
 2using Intentum.AI.Embeddings;
 3using Microsoft.Extensions.Caching.Distributed;
 4
 5namespace Intentum.AI.Caching.Redis;
 6
 7/// <summary>
 8/// Redis-backed distributed cache implementation for embeddings using IDistributedCache.
 9/// Suitable for multi-node production; use MemoryEmbeddingCache for single-node or development.
 10/// </summary>
 11public sealed class RedisEmbeddingCache : IEmbeddingCache
 12{
 13    private const string KeyPrefix = "Intentum:Embedding:";
 114    private static readonly JsonSerializerOptions JsonOptions = new()
 115    {
 116        PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
 117        WriteIndented = false
 118    };
 19
 20    private readonly IDistributedCache _cache;
 21    private readonly DistributedCacheEntryOptions _defaultOptions;
 22
 23    /// <summary>
 24    /// Creates a Redis embedding cache with default expiration (24 hours).
 25    /// </summary>
 26    public RedisEmbeddingCache(IDistributedCache cache)
 327        : this(cache, new DistributedCacheEntryOptions
 328        {
 329            AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(24)
 330        })
 331    {
 332    }
 33
 34    /// <summary>
 35    /// Creates a Redis embedding cache with custom cache entry options.
 36    /// </summary>
 337    public RedisEmbeddingCache(IDistributedCache cache, DistributedCacheEntryOptions? defaultOptions)
 338    {
 339        _cache = cache ?? throw new ArgumentNullException(nameof(cache));
 340        _defaultOptions = defaultOptions ?? new DistributedCacheEntryOptions
 341        {
 342            AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(24)
 343        };
 344    }
 45
 46    /// <inheritdoc />
 47    public IntentEmbedding? Get(string behaviorKey)
 348    {
 349        var key = GetCacheKey(behaviorKey);
 350        var bytes = _cache.Get(key);
 351        if (bytes is null || bytes.Length == 0)
 252            return null;
 53
 154        return Deserialize(bytes);
 355    }
 56
 57    /// <inheritdoc />
 58    public void Set(string behaviorKey, IntentEmbedding embedding)
 259    {
 260        var key = GetCacheKey(behaviorKey);
 261        var bytes = Serialize(embedding);
 262        _cache.Set(key, bytes, _defaultOptions);
 263    }
 64
 65    /// <inheritdoc />
 66    public void Remove(string behaviorKey)
 167    {
 168        var key = GetCacheKey(behaviorKey);
 169        _cache.Remove(key);
 170    }
 71
 72    /// <inheritdoc />
 73    public void Clear()
 074    {
 75        // IDistributedCache has no global Clear; callers can use a dedicated Redis key prefix and FLUSHDB in Redis, or 
 076        throw new NotSupportedException(
 077            "Clear is not supported by Redis embedding cache. Use Redis FLUSHDB for the database or remove keys by prefi
 78    }
 79
 80    private static string GetCacheKey(string behaviorKey)
 681    {
 682        return KeyPrefix + behaviorKey;
 683    }
 84
 85    private static byte[] Serialize(IntentEmbedding embedding)
 286    {
 287        var dto = new EmbeddingDto(embedding.Source, embedding.Score, embedding.Vector?.ToList());
 288        return JsonSerializer.SerializeToUtf8Bytes(dto, JsonOptions);
 289    }
 90
 91    private static IntentEmbedding? Deserialize(byte[] bytes)
 192    {
 193        var dto = JsonSerializer.Deserialize<EmbeddingDto>(bytes, JsonOptions);
 194        if (dto is null)
 095            return null;
 196        return new IntentEmbedding(dto.Source, dto.Score, dto.Vector);
 197    }
 98
 1299    private sealed record EmbeddingDto(string Source, double Score, List<double>? Vector);
 100}