From 1a8ab1457244d15b19ddcc94958f645f5ec2abc7 Mon Sep 17 00:00:00 2001 From: vnugent Date: Thu, 22 Jun 2023 21:16:28 -0400 Subject: Save checkpoint --- .../src/Endpoints/CacheSystemUtil.cs | 242 --------------------- 1 file changed, 242 deletions(-) delete mode 100644 plugins/ObjectCacheServer/src/Endpoints/CacheSystemUtil.cs (limited to 'plugins/ObjectCacheServer/src/Endpoints/CacheSystemUtil.cs') diff --git a/plugins/ObjectCacheServer/src/Endpoints/CacheSystemUtil.cs b/plugins/ObjectCacheServer/src/Endpoints/CacheSystemUtil.cs deleted file mode 100644 index 669b84f..0000000 --- a/plugins/ObjectCacheServer/src/Endpoints/CacheSystemUtil.cs +++ /dev/null @@ -1,242 +0,0 @@ -/* -* Copyright (c) 2023 Vaughn Nugent -* -* Library: VNLib -* Package: ObjectCacheServer -* File: CacheSystemUtil.cs -* -* CacheSystemUtil.cs is part of ObjectCacheServer which is part of the larger -* VNLib collection of libraries and utilities. -* -* ObjectCacheServer is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License as -* published by the Free Software Foundation, either version 3 of the -* License, or (at your option) any later version. -* -* ObjectCacheServer is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see https://www.gnu.org/licenses/. -*/ - -using System; -using System.IO; -using System.Text.Json; -using System.Collections; -using System.Collections.Generic; -using System.Runtime.CompilerServices; - -using VNLib.Plugins; -using VNLib.Utils.Memory; -using VNLib.Plugins.Extensions.Loading; - -namespace VNLib.Data.Caching.ObjectCache.Server -{ - internal static class CacheSystemUtil - { - const string PERSISTANT_ASM_CONFIF_KEY = "persistant_cache_asm"; - const string USER_CACHE_ASM_CONFIG_KEY = "custom_cache_impl_asm"; - const string LOAD_METHOD_NAME = "OnRuntimeLoad"; - const string TEARDOWN_METHOD_NAME = "OnSystemDetach"; - - /// - /// Loads the implementation (dynamic or default) into the process - /// and initializes it and it's backing store. - /// - /// - /// The configuration object that contains loading variables - /// The heap for memory cache table to allocate buffers from - /// The cache configuration object - /// The loaded implementation - /// - public static IBlobCacheTable LoadMemoryCacheSystem(this PluginBase plugin, IConfigScope config, IUnmangedHeap heap, CacheConfiguration cacheConf) - { - //First, try to load persitant cache store - PersistantCacheManager? pCManager = GetPersistantStore(plugin, config); - - IBlobCacheTable table; - - //See if the user defined a custom cache table implementation - if (config.TryGetValue(USER_CACHE_ASM_CONFIG_KEY, out JsonElement customEl)) - { - string asmName = customEl.GetString() ?? throw new FileNotFoundException("User defined a custom blob cache assembly but the file name was null"); - - //Return the runtime loaded table - table = LoadCustomMemCacheTable(plugin, asmName, pCManager); - } - else - { - //Default type - table = GetInternalBlobCache(heap, cacheConf, pCManager); - } - - //Initialize the subsystem from the cache table - pCManager?.InitializeSubsystem(table); - - return table; - } - - private static IBlobCacheTable GetInternalBlobCache(IUnmangedHeap heap, CacheConfiguration config, IPersistantCacheStore? store) - { - return new BlobCacheTable(config.BucketCount, config.MaxCacheEntries, heap, store); - } - - private static IBlobCacheTable LoadCustomMemCacheTable(PluginBase plugin, string asmName, IPersistantCacheStore? store) - { - //Load the custom assembly - AssemblyLoader customTable = plugin.LoadAssembly(asmName); - - try - { - //Try get onload method and pass the persistant cache instance - Action? onLoad = customTable.TryGetMethod>(LOAD_METHOD_NAME); - onLoad?.Invoke(plugin, store); - } - catch - { - customTable.Dispose(); - throw; - } - - return new RuntimeBlobCacheTable(customTable); - } - - private static PersistantCacheManager? GetPersistantStore(PluginBase plugin, IConfigScope config) - { - //Get the persistant assembly - if (!config.TryGetValue(PERSISTANT_ASM_CONFIF_KEY, out JsonElement asmEl)) - { - return null; - } - - string? asmName = asmEl.GetString(); - if (asmName == null) - { - return null; - } - - //Load the dynamic assembly into the alc - AssemblyLoader loader = plugin.LoadAssembly(asmName); - try - { - //Call the OnLoad method - Action? loadMethod = loader.TryGetMethod>(LOAD_METHOD_NAME); - - loadMethod?.Invoke(plugin, config); - } - catch - { - loader.Dispose(); - throw; - } - - //Return the - return new(loader); - } - - - private sealed class RuntimeBlobCacheTable : IBlobCacheTable - { - - private readonly IBlobCacheTable _table; - private readonly Action? OnDetatch; - - public RuntimeBlobCacheTable(AssemblyLoader loader) - { - OnDetatch = loader.TryGetMethod(TEARDOWN_METHOD_NAME); - _table = loader.Resource; - } - - public void Dispose() - { - //We can let the loader dispose the cache table, but we can notify of detatch - OnDetatch?.Invoke(); - } - - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - IBlobCacheBucket IBlobCacheTable.GetBucket(ReadOnlySpan objectId) => _table.GetBucket(objectId); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public IEnumerator GetEnumerator() => _table.GetEnumerator(); - - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable)_table).GetEnumerator(); - } - - internal sealed class PersistantCacheManager : IPersistantCacheStore - { - const string INITIALIZE_METHOD_NAME = "OnInitializeForBucket"; - - - /* - * Our referrence can be technically unloaded, but so will - * this instance, since its loaded into the current ALC, so - * this referrence may exist for the lifetime of this instance. - * - * It also implements IDisposable, which the assembly loader class - * will call when this plugin is unloaded, we dont need to call - * it here, but we can signal a detach. - * - * Since the store implements IDisposable, its likely going to - * check for dispose on each call, so we don't need to add - * and additional disposed check since the method calls must be fast. - */ - - private readonly IPersistantCacheStore store; - - private readonly Action? InitMethod; - private readonly Action? OnServiceDetatch; - - public PersistantCacheManager(AssemblyLoader loader) - { - //Try to get the Initialize method - InitMethod = loader.TryGetMethod>(INITIALIZE_METHOD_NAME); - - //Get the optional detatch method - OnServiceDetatch = loader.TryGetMethod(TEARDOWN_METHOD_NAME); - - store = loader.Resource; - } - - /// - /// Optionally initializes the backing store by publishing the table's bucket - /// id's so it's made aware of the memory cache bucket system. - /// - /// The table containing buckets to publish - public void InitializeSubsystem(IBlobCacheTable table) - { - //Itterate all buckets - foreach (IBlobCacheBucket bucket in table) - { - InitMethod?.Invoke(bucket.Id); - } - } - - void IDisposable.Dispose() - { - //Assembly loader will dispose the type, we can just signal a detach - - OnServiceDetatch?.Invoke(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - bool IPersistantCacheStore.OnCacheMiss(uint bucketId, string key, IMemoryCacheEntryFactory factory, out CacheEntry entry) - { - return store.OnCacheMiss(bucketId, key, factory, out entry); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - void IPersistantCacheStore.OnEntryDeleted(uint bucketId, string key) => store.OnEntryDeleted(bucketId, key); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - void IPersistantCacheStore.OnEntryEvicted(uint bucketId, string key, in CacheEntry entry) => store.OnEntryEvicted(bucketId, key, in entry); - } - } -} -- cgit