aboutsummaryrefslogtreecommitdiff
path: root/lib/VNLib.Data.Caching.ObjectCache/src/BlobCache.cs
diff options
context:
space:
mode:
Diffstat (limited to 'lib/VNLib.Data.Caching.ObjectCache/src/BlobCache.cs')
-rw-r--r--lib/VNLib.Data.Caching.ObjectCache/src/BlobCache.cs106
1 files changed, 62 insertions, 44 deletions
diff --git a/lib/VNLib.Data.Caching.ObjectCache/src/BlobCache.cs b/lib/VNLib.Data.Caching.ObjectCache/src/BlobCache.cs
index 26df351..fbb2dcc 100644
--- a/lib/VNLib.Data.Caching.ObjectCache/src/BlobCache.cs
+++ b/lib/VNLib.Data.Caching.ObjectCache/src/BlobCache.cs
@@ -23,116 +23,134 @@
*/
using System;
-using System.IO;
-using System.Linq;
using System.Collections.Generic;
-using System.Diagnostics.CodeAnalysis;
-using VNLib.Utils.IO;
-using VNLib.Utils.Logging;
-using VNLib.Utils.Memory;
using VNLib.Utils.Memory.Caching;
namespace VNLib.Data.Caching
{
+
/// <summary>
/// A general purpose binary data storage
/// </summary>
- public class BlobCache : LRUCache<string, MemoryHandle<byte>>
+ public class BlobCache : LRUCache<string, CacheEntry>
{
- readonly IUnmangedHeap Heap;
- readonly DirectoryInfo SwapDir;
- readonly ILogProvider Log;
///<inheritdoc/>
public override bool IsReadOnly { get; }
+
///<inheritdoc/>
protected override int MaxCapacity { get; }
-
-
+
+
/// <summary>
/// Initializes a new <see cref="BlobCache"/> store
/// </summary>
- /// <param name="swapDir">The <see cref="IsolatedStorageDirectory"/> to swap blob data to when cache</param>
/// <param name="maxCapacity">The maximum number of items to keep in memory</param>
- /// <param name="log">A <see cref="ILogProvider"/> to write log data to</param>
- /// <param name="heap">A <see cref="IUnmangedHeap"/> to allocate buffers and store <see cref="BlobItem"/> data in memory</param>
- public BlobCache(DirectoryInfo swapDir, int maxCapacity, ILogProvider log, IUnmangedHeap heap)
+ /// <exception cref="ArgumentException"></exception>
+ public BlobCache(int maxCapacity)
:base(StringComparer.Ordinal)
{
- IsReadOnly = false;
+ if(maxCapacity < 1)
+ {
+ throw new ArgumentException("The maxium capacity of the store must be a positive integer larger than 0", nameof(maxCapacity));
+ }
+
MaxCapacity = maxCapacity;
- SwapDir = swapDir;
+
//Update the lookup table size
LookupTable.EnsureCapacity(maxCapacity);
- //Set default heap if not specified
- Heap = heap;
- Log = log;
}
+
///<inheritdoc/>
- protected override bool CacheMiss(string key, [NotNullWhen(true)] out MemoryHandle<byte>? value)
+ protected override bool CacheMiss(string key, out CacheEntry value)
{
- value = null;
+ value = default;
return false;
}
+
///<inheritdoc/>
- protected override void Evicted(KeyValuePair<string, MemoryHandle<byte>> evicted)
+ protected override void Evicted(ref KeyValuePair<string, CacheEntry> evicted)
{
- //Dispose the blob
+ //Dispose the cache item
evicted.Value.Dispose();
}
+
/// <summary>
- /// If the <see cref="BlobItem"/> is found in the store, changes the key
+ /// If the <see cref="CacheEntry"/> is found in the store, changes the key
/// that referrences the blob.
/// </summary>
/// <param name="currentKey">The key that currently referrences the blob in the store</param>
/// <param name="newKey">The new key that will referrence the blob</param>
- /// <param name="blob">The <see cref="BlobItem"/> if its found in the store</param>
+ /// <param name="blob">The <see cref="CacheEntry"/> if its found in the store</param>
/// <returns>True if the record was found and the key was changes</returns>
- public bool TryChangeKey(string currentKey, string newKey, [NotNullWhen(true)] out MemoryHandle<byte>? blob)
+ public bool TryChangeKey(string currentKey, string newKey, out CacheEntry blob)
{
- if (LookupTable.Remove(currentKey, out LinkedListNode<KeyValuePair<string, MemoryHandle<byte>>>? node))
+ //Try to get the node at the current key
+ if (LookupTable.Remove(currentKey, out LinkedListNode<KeyValuePair<string, CacheEntry>> ? node))
{
//Remove the node from the ll
List.Remove(node);
- //Update the node kvp
- blob = node.Value.Value;
- node.Value = new KeyValuePair<string, MemoryHandle<byte>>(newKey, blob);
+
+ //Get the stored blob
+ blob = node.ValueRef.Value;
+
+ //Update the
+ node.Value = new KeyValuePair<string, CacheEntry>(newKey, blob);
+
//Add to end of list
List.AddLast(node);
+
//Re-add to lookup table with new key
LookupTable.Add(newKey, node);
+
return true;
}
- blob = null;
+
+ blob = default;
return false;
}
+
/// <summary>
- /// Removes the <see cref="BlobItem"/> from the store without disposing the blobl
+ /// Removes the <see cref="CacheEntry"/> from the store, and frees its resources
/// </summary>
- /// <param name="key">The key that referrences the <see cref="BlobItem"/> in the store</param>
+ /// <param name="key">The key that referrences the <see cref="CacheEntry"/> in the store</param>
/// <returns>A value indicating if the blob was removed</returns>
public override bool Remove(string key)
{
//Remove the item from the lookup table and if it exists, remove the node from the list
- if (LookupTable.Remove(key, out LinkedListNode<KeyValuePair<string, MemoryHandle<byte>>>? node))
+ if (!LookupTable.Remove(key, out LinkedListNode<KeyValuePair<string, CacheEntry>>? node))
+ {
+ return false;
+ }
+
+ //always dispose blob
+ using (node.ValueRef.Value)
{
- //Remove the new from the list
+ //Remove the node from the list
List.Remove(node);
- //dispose the buffer
- node.Value.Value.Dispose();
- return true;
}
- return false;
+ return true;
}
+
/// <summary>
- /// Removes and disposes all blobl elements in cache (or in the backing store)
+ /// Removes all cache entires and disposes their held resources
/// </summary>
public override void Clear()
{
- foreach (MemoryHandle<byte> blob in List.Select(kp => kp.Value))
+ //Start from first node
+ LinkedListNode<KeyValuePair<string, CacheEntry>>? node = List.First;
+
+ //Classic ll node itteration
+ while(node != null)
{
- blob.Dispose();
+ //Dispose the cache entry
+ node.ValueRef.Value.Dispose();
+
+ //Move to next node
+ node = node.Next;
}
+
+ //empty all cache entires in the store
base.Clear();
}
}