aboutsummaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorLibravatar vnugent <public@vaughnnugent.com>2023-10-14 15:50:46 -0400
committerLibravatar vnugent <public@vaughnnugent.com>2023-10-14 15:50:46 -0400
commit3c353afe4dffa3da9c96ef25b02f0004676afe5f (patch)
tree1e3c5889734c029701205c55fa842552ded81c2b /plugins
parent531baabc8289eeaa2aad63cb0e86cc3dd978d97e (diff)
experimential expansion and performance changes
Diffstat (limited to 'plugins')
-rw-r--r--plugins/ObjectCacheServer/src/BucketLocalManagerFactory.cs153
-rw-r--r--plugins/ObjectCacheServer/src/Cache/CacheStore.cs7
-rw-r--r--plugins/ObjectCacheServer/src/Cache/CacheSystemUtil.cs5
-rw-r--r--plugins/ObjectCacheServer/src/Clustering/CacheNodeReplicationMaanger.cs4
-rw-r--r--plugins/ObjectCacheServer/src/Clustering/PeerDiscoveryManager.cs2
-rw-r--r--plugins/ObjectCacheServer/src/ObjectCacheServerEntry.cs12
6 files changed, 168 insertions, 15 deletions
diff --git a/plugins/ObjectCacheServer/src/BucketLocalManagerFactory.cs b/plugins/ObjectCacheServer/src/BucketLocalManagerFactory.cs
new file mode 100644
index 0000000..40f4c29
--- /dev/null
+++ b/plugins/ObjectCacheServer/src/BucketLocalManagerFactory.cs
@@ -0,0 +1,153 @@
+/*
+* Copyright (c) 2023 Vaughn Nugent
+*
+* Library: VNLib
+* Package: VNLib.Plugins.Extensions.VNCache
+* File: BucketLocalManagerFactory.cs
+*
+* BucketLocalManagerFactory.cs is part of VNLib.Plugins.Extensions.VNCache
+* which is part of the larger VNLib collection of libraries and utilities.
+*
+* VNLib.Plugins.Extensions.VNCache 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.
+*
+* VNLib.Plugins.Extensions.VNCache 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.Buffers;
+using System.Text.Json;
+using System.Collections.Generic;
+using System.Runtime.CompilerServices;
+
+using VNLib.Plugins;
+using VNLib.Utils;
+using VNLib.Utils.Memory;
+using VNLib.Utils.Extensions;
+using VNLib.Plugins.Extensions.Loading;
+
+/*
+ * How bucket local memory works:
+ *
+ * The object cache library allows us to create a memory manager for use with
+ * an individual bucket. Each bucket is mutually exclusive, so memory operations
+ * are "thread-safe" This means we can create a heap for each bucket and use it
+ * for all memory operations for that bucket. Since no contention will occur,
+ * we can get a little more performance out of the memory operations. The internal
+ * heap impls will still likely have locks enabled, but no contention will occur
+ */
+
+namespace VNLib.Data.Caching.ObjectCache.Server
+{
+ [ConfigurationName("memory_manager", Required = false)]
+ internal sealed class BucketLocalManagerFactory : VnDisposeable, ICacheMemoryManagerFactory
+ {
+ private readonly LinkedList<BucketLocalManager> _managers = new ();
+ private readonly bool _zeroAll;
+
+ ///<inheritdoc/>
+ public ICacheEntryMemoryManager CreateForBucket(uint bucketId)
+ {
+ //Init a new heap for the individual bucket
+ IUnmangedHeap localHeap = MemoryUtil.InitializeNewHeapForProcess();
+
+ BucketLocalManager manager = new (localHeap, bucketId, _zeroAll);
+ _managers.AddLast(manager);
+
+ return manager;
+ }
+
+ public BucketLocalManagerFactory(PluginBase plugin) : this(plugin, null)
+ { }
+
+ public BucketLocalManagerFactory(PluginBase plugin, IConfigScope? config)
+ {
+ if (config != null)
+ {
+ //Try to get the zero all flag
+ if (config.TryGetValue("zero_all", out JsonElement zeroEl))
+ {
+ _zeroAll = zeroEl.GetBoolean();
+ }
+ }
+ }
+
+ protected override void Free()
+ {
+ //Free heaps on exit
+ foreach (BucketLocalManager manager in _managers)
+ {
+ manager.Heap.Dispose();
+ }
+ }
+
+ /*
+ * Buckets are mutually exclusive, so we can use a single heap for each bucket
+ * to get a little more performance on memory operations
+ */
+
+ private sealed record class BucketLocalManager(IUnmangedHeap Heap, uint BucketId, bool Zero) : ICacheEntryMemoryManager
+ {
+
+ ///<inheritdoc/>
+ public object AllocHandle(uint size) => Heap.Alloc<byte>(size, Zero);
+
+ ///<inheritdoc/>
+ public void FreeHandle(object handle)
+ {
+ _ = handle ?? throw new ArgumentNullException(nameof(handle));
+ MemoryHandle<byte> _handle = Unsafe.As<object, MemoryHandle<byte>>(ref handle);
+
+ //Free the handle
+ _handle.Dispose();
+ }
+
+ ///<inheritdoc/>
+ public uint GetHandleSize(object handle)
+ {
+ _ = handle ?? throw new ArgumentNullException(nameof(handle));
+ MemoryHandle<byte> _handle = Unsafe.As<object, MemoryHandle<byte>>(ref handle);
+
+ return (uint)_handle.Length;
+ }
+
+ ///<inheritdoc/>
+ public Span<byte> GetSpan(object handle, uint offset, uint length)
+ {
+ _ = handle ?? throw new ArgumentNullException(nameof(handle));
+ MemoryHandle<byte> _handle = Unsafe.As<object, MemoryHandle<byte>>(ref handle);
+
+ return _handle.GetOffsetSpan(offset, checked((int)length));
+ }
+
+ ///<inheritdoc/>
+ public MemoryHandle PinHandle(object handle, int offset)
+ {
+ _ = handle ?? throw new ArgumentNullException(nameof(handle));
+ MemoryHandle<byte> _handle = Unsafe.As<object, MemoryHandle<byte>>(ref handle);
+
+ //Pin the handle
+ return _handle.Pin(offset);
+ }
+
+ ///<inheritdoc/>
+ public void ResizeHandle(object handle, uint newSize)
+ {
+ _ = handle ?? throw new ArgumentNullException(nameof(handle));
+ MemoryHandle<byte> _handle = Unsafe.As<object, MemoryHandle<byte>>(ref handle);
+
+ //Resize the handle
+ _handle.ResizeIfSmaller(newSize);
+ }
+ }
+ }
+}
diff --git a/plugins/ObjectCacheServer/src/Cache/CacheStore.cs b/plugins/ObjectCacheServer/src/Cache/CacheStore.cs
index f94a3f5..5795222 100644
--- a/plugins/ObjectCacheServer/src/Cache/CacheStore.cs
+++ b/plugins/ObjectCacheServer/src/Cache/CacheStore.cs
@@ -107,11 +107,14 @@ Cache Configuration:
//Get the event listener
ICacheListenerEventQueue queue = plugin.GetOrCreateSingleton<CacheListenerPubQueue>();
+ //Get the memory manager
+ ICacheMemoryManagerFactory manager = plugin.GetOrCreateSingleton<BucketLocalManagerFactory>();
+
//Load the blob cache table system
- IBlobCacheTable bc = plugin.LoadMemoryCacheSystem(config, plugin.CacheHeap, cacheConf);
+ IBlobCacheTable bc = plugin.LoadMemoryCacheSystem(config, manager, cacheConf);
//Endpoint only allows for a single reader
- return new(bc, queue, plugin.Log, plugin.CacheHeap);
+ return new(bc, queue, plugin.Log, plugin.ListenerHeap);
}
/*
diff --git a/plugins/ObjectCacheServer/src/Cache/CacheSystemUtil.cs b/plugins/ObjectCacheServer/src/Cache/CacheSystemUtil.cs
index 2071d2b..a02fe75 100644
--- a/plugins/ObjectCacheServer/src/Cache/CacheSystemUtil.cs
+++ b/plugins/ObjectCacheServer/src/Cache/CacheSystemUtil.cs
@@ -30,7 +30,6 @@ 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.Cache
@@ -52,7 +51,7 @@ namespace VNLib.Data.Caching.ObjectCache.Server.Cache
/// <param name="cacheConf">The cache configuration object</param>
/// <returns>The loaded <see cref="IBlobCacheTable"/> implementation</returns>
/// <exception cref="FileNotFoundException"></exception>
- public static IBlobCacheTable LoadMemoryCacheSystem(this PluginBase plugin, IConfigScope config, IUnmangedHeap heap, CacheConfiguration cacheConf)
+ public static IBlobCacheTable LoadMemoryCacheSystem(this PluginBase plugin, IConfigScope config, ICacheMemoryManagerFactory heap, CacheConfiguration cacheConf)
{
//First, try to load persitant cache store
PersistantCacheManager? pCManager = GetPersistantStore(plugin, config);
@@ -79,7 +78,7 @@ namespace VNLib.Data.Caching.ObjectCache.Server.Cache
return table;
}
- private static IBlobCacheTable GetInternalBlobCache(IUnmangedHeap heap, CacheConfiguration config, IPersistantCacheStore? store)
+ private static IBlobCacheTable GetInternalBlobCache(ICacheMemoryManagerFactory heap, CacheConfiguration config, IPersistantCacheStore? store)
{
return new BlobCacheTable(config.BucketCount, config.MaxCacheEntries, heap, store);
}
diff --git a/plugins/ObjectCacheServer/src/Clustering/CacheNodeReplicationMaanger.cs b/plugins/ObjectCacheServer/src/Clustering/CacheNodeReplicationMaanger.cs
index 5a04737..19f09dc 100644
--- a/plugins/ObjectCacheServer/src/Clustering/CacheNodeReplicationMaanger.cs
+++ b/plugins/ObjectCacheServer/src/Clustering/CacheNodeReplicationMaanger.cs
@@ -76,11 +76,11 @@ namespace VNLib.Data.Caching.ObjectCache.Server.Clustering
//Load the node config
_nodeConfig = plugin.GetOrCreateSingleton<NodeConfig>();
_cacheStore = plugin.GetOrCreateSingleton<CacheStore>();
- _peerAdapter = plugin.GetOrCreateSingleton<PeerDiscoveryManager>();
+ _peerAdapter = plugin.GetOrCreateSingleton<PeerDiscoveryManager>();
//Init fbm config with fixed message size
_replicationClientConfig = FBMDataCacheExtensions.GetDefaultConfig(
- (plugin as ObjectCacheServerEntry)!.CacheHeap,
+ (plugin as ObjectCacheServerEntry)!.ListenerHeap,
MAX_MESSAGE_SIZE,
debugLog: plugin.IsDebug() ? plugin.Log : null
);
diff --git a/plugins/ObjectCacheServer/src/Clustering/PeerDiscoveryManager.cs b/plugins/ObjectCacheServer/src/Clustering/PeerDiscoveryManager.cs
index 65cc009..6475f9c 100644
--- a/plugins/ObjectCacheServer/src/Clustering/PeerDiscoveryManager.cs
+++ b/plugins/ObjectCacheServer/src/Clustering/PeerDiscoveryManager.cs
@@ -135,7 +135,7 @@ namespace VNLib.Data.Caching.ObjectCache.Server.Clustering
if (allAds.Length > 0)
{
- //Discover all kown nodes
+ //Discover all known nodes
await Config.Config.DiscoverNodesAsync(allAds, exitToken);
}
diff --git a/plugins/ObjectCacheServer/src/ObjectCacheServerEntry.cs b/plugins/ObjectCacheServer/src/ObjectCacheServerEntry.cs
index a566390..aada787 100644
--- a/plugins/ObjectCacheServer/src/ObjectCacheServerEntry.cs
+++ b/plugins/ObjectCacheServer/src/ObjectCacheServerEntry.cs
@@ -32,6 +32,7 @@ using VNLib.Utils.Logging;
using VNLib.Utils.Memory.Diagnostics;
using VNLib.Plugins.Extensions.Loading;
using VNLib.Plugins.Extensions.Loading.Routing;
+
using VNLib.Data.Caching.ObjectCache.Server.Endpoints;
using VNLib.Data.Caching.ObjectCache.Server.Clustering;
@@ -42,12 +43,9 @@ namespace VNLib.Data.Caching.ObjectCache.Server
{
public override string PluginName => "ObjectCache.Service";
- private readonly Lazy<IUnmangedHeap> _cacheHeap;
+ private readonly Lazy<IUnmangedHeap> _cacheHeap;
- /// <summary>
- /// Gets the shared heap for the plugin
- /// </summary>
- internal IUnmangedHeap CacheHeap => _cacheHeap.Value;
+ internal IUnmangedHeap ListenerHeap => _cacheHeap.Value;
public ObjectCacheServerEntry()
{
@@ -55,14 +53,14 @@ namespace VNLib.Data.Caching.ObjectCache.Server
_cacheHeap = new Lazy<IUnmangedHeap>(InitializeHeap, LazyThreadSafetyMode.PublicationOnly);
}
- private IUnmangedHeap InitializeHeap()
+ internal IUnmangedHeap InitializeHeap()
{
//Create default heap
IUnmangedHeap _heap = MemoryUtil.InitializeNewHeapForProcess();
try
{
//If the plugin is in debug mode enable heap tracking
- return this.IsDebug() ? new TrackedHeapWrapper(_heap) : _heap;
+ return this.IsDebug() ? new TrackedHeapWrapper(_heap, true) : _heap;
}
catch
{