From 3c353afe4dffa3da9c96ef25b02f0004676afe5f Mon Sep 17 00:00:00 2001 From: vnugent Date: Sat, 14 Oct 2023 15:50:46 -0400 Subject: experimential expansion and performance changes --- .../src/DataModel/EntityCacheExtensions.cs | 74 +++++++++++++++++++--- 1 file changed, 66 insertions(+), 8 deletions(-) (limited to 'lib/VNLib.Plugins.Extensions.VNCache/src/DataModel/EntityCacheExtensions.cs') diff --git a/lib/VNLib.Plugins.Extensions.VNCache/src/DataModel/EntityCacheExtensions.cs b/lib/VNLib.Plugins.Extensions.VNCache/src/DataModel/EntityCacheExtensions.cs index 73baa4a..363e1c9 100644 --- a/lib/VNLib.Plugins.Extensions.VNCache/src/DataModel/EntityCacheExtensions.cs +++ b/lib/VNLib.Plugins.Extensions.VNCache/src/DataModel/EntityCacheExtensions.cs @@ -54,12 +54,12 @@ namespace VNLib.Plugins.Extensions.VNCache.DataModel /// A token to cancel the operation /// A task that completes when the delete operation has compelted /// - public static Task DeleteAsync(this IGlobalCacheProvider cache, T entity, CancellationToken cancellation) where T: class, ICacheEntity + public static Task RemoveAsync(this IEntityCache cache, T entity, CancellationToken cancellation) where T: class, ICacheEntity { _ = entity ?? throw new ArgumentNullException(nameof(entity)); _ = cache ?? throw new ArgumentNullException(nameof(entity)); //Delete by its id - return cache.DeleteAsync(entity.Id, cancellation); + return cache.RemoveAsync(entity.Id, cancellation); } /// @@ -71,27 +71,85 @@ namespace VNLib.Plugins.Extensions.VNCache.DataModel /// The entity to set at the given key /// A task that completes when the add/update operation has compelted /// - public static Task AddOrUpdateAsync(this IGlobalCacheProvider cache, T entity, CancellationToken cancellation) where T: class, ICacheEntity + public static Task UpsertAsync(this IEntityCache cache, T entity, CancellationToken cancellation) where T: class, ICacheEntity { _ = entity ?? throw new ArgumentNullException(nameof(entity)); _ = cache ?? throw new ArgumentNullException(nameof(cache)); //Add/update with its id - return cache.AddOrUpdateAsync(entity.Id, null, entity, cancellation); + return cache.UpsertAsync(entity.Id, entity, cancellation); + } + + /// + /// Creates an wrapper using the current global cache provider. + /// Understand this will share the same cache store as other stores. Consider creating a scoped cache + /// to avoid key collisions + /// + /// + /// + /// The entity data serializer + /// The entity data deserializer + /// The new wrapper instance + /// + public static IEntityCache CreateEntityCache(this IGlobalCacheProvider cache, ICacheObjectSerialzer serialier, ICacheObjectDeserialzer deserializer) where T: class + { + _ = cache ?? throw new ArgumentNullException(nameof(cache)); + _ = serialier ?? throw new ArgumentNullException(nameof(serialier)); + _ = deserializer ?? throw new ArgumentNullException(nameof(deserializer)); + + return new EntityCacheImpl(cache, deserializer, serialier); + } + + /// + /// Creates an wrapper using the current global cache provider, + /// with a Json serializer/deserializer + /// + /// + /// + /// The new wrapper using json serialization + /// + public static IEntityCache CreateJsonEntityCache(this IGlobalCacheProvider cache) where T: class + { + _ = cache ?? throw new ArgumentNullException(nameof(cache)); + JsonCacheObjectSerializer json = new(); + return CreateEntityCache(cache, json, json); + } + + private sealed class EntityCacheImpl : IEntityCache where T : class + { + private readonly IGlobalCacheProvider _cacheProvider; + private readonly ICacheObjectDeserialzer _cacheObjectDeserialzer; + private readonly ICacheObjectSerialzer _cacheObjectSerialzer; + + public EntityCacheImpl(IGlobalCacheProvider cache, ICacheObjectDeserialzer deserializer, ICacheObjectSerialzer serializer) + { + _cacheProvider = cache; + _cacheObjectDeserialzer = deserializer; + _cacheObjectSerialzer = serializer; + } + + /// + public Task GetAsync(string id, CancellationToken token = default) => _cacheProvider.GetAsync(id, _cacheObjectDeserialzer, token); + + /// + public Task RemoveAsync(string id, CancellationToken token = default) => _cacheProvider.DeleteAsync(id, token); + + /// + public Task UpsertAsync(string id, T entity, CancellationToken token = default) => _cacheProvider.AddOrUpdateAsync(id, null, entity, _cacheObjectSerialzer, token); } - private sealed class ScopedCacheImpl: ScopedCache { private readonly IGlobalCacheProvider cache; + /// public override bool IsConnected { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => cache.IsConnected; } - + /// protected override ICacheKeyGenerator KeyGen { get; } public ScopedCacheImpl(IGlobalCacheProvider cache, ICacheKeyGenerator keyGen) @@ -171,7 +229,7 @@ namespace VNLib.Plugins.Extensions.VNCache.DataModel } /// - public override Task AddOrUpdateAsync(string key, string? newKey, IObjectData rawData, ICacheObjectSerialzer serialzer, CancellationToken cancellation) + public override Task AddOrUpdateAsync(string key, string? newKey, IObjectData rawData, CancellationToken cancellation) { _ = key ?? throw new ArgumentNullException(nameof(key)); @@ -181,7 +239,7 @@ namespace VNLib.Plugins.Extensions.VNCache.DataModel //If newkey exists, compute the secondary key string? secondary = newKey != null ? KeyGen.ComputedKey(newKey) : null; - return cache.AddOrUpdateAsync(primary, secondary, rawData, serialzer, cancellation); + return cache.AddOrUpdateAsync(primary, secondary, rawData, cancellation); } } } -- cgit