Skip to content

Commit

Permalink
Adjust dedup table bits
Browse files Browse the repository at this point in the history
  • Loading branch information
rickardp committed Feb 13, 2023
1 parent ee6dda4 commit ebbec8d
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 7 deletions.
27 changes: 25 additions & 2 deletions src/Combination.StringPools/StringPool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ namespace Combination.StringPools;
public static class StringPool
{
private const int DefaultPageSize = 16384; // Size of a pool memory page in bytes
private const int DefaultDeduplicationTableBits = 10; // Size of a pool memory page in bytes


/// <summary>
Expand All @@ -20,7 +21,18 @@ public static class StringPool
/// <param name="pageSize">The size of the memory pages to allocate (allocation increment quantum).</param>
/// <param name="initialPageCount">The initial number of pages to allocate.</param>
/// <returns>The newly create string pool.</returns>
public static IUtf8StringPool Utf8(int pageSize, int initialPageCount) => new Utf8StringPool(pageSize, initialPageCount, false);
public static IUtf8StringPool Utf8(int pageSize, int initialPageCount) => Utf8(pageSize, initialPageCount, DefaultDeduplicationTableBits);

/// <summary>
/// A Utf8 string pool that does not deduplicate strings, created with specified page size and initial page count.
/// </summary>
/// <param name="pageSize">The size of the memory pages to allocate (allocation increment quantum).</param>
/// <param name="initialPageCount">The initial number of pages to allocate.</param>
/// <param name="deduplicationTableBits">Number of bits in the deduplication table (size will be 2^bits).</param>
/// <returns>The newly create string pool.</returns>
public static IUtf8StringPool Utf8(int pageSize, int initialPageCount, int deduplicationTableBits) =>
new Utf8StringPool(pageSize, initialPageCount, false, deduplicationTableBits);


/// <summary>
/// A Utf8 string pool that de-duplicates equal strings, created with default page size and initial page count.
Expand All @@ -34,7 +46,18 @@ public static class StringPool
/// <param name="pageSize">The size of the memory pages to allocate (allocation increment quantum).</param>
/// <param name="initialPageCount">The initial number of pages to allocate.</param>
/// <returns>The newly create string pool.</returns>
public static IUtf8DeduplicatedStringPool DeduplicatedUtf8(int pageSize, int initialPageCount) => new Utf8StringPool(pageSize, initialPageCount, true);
public static IUtf8DeduplicatedStringPool DeduplicatedUtf8(int pageSize, int initialPageCount) =>
DeduplicatedUtf8(pageSize, initialPageCount, DefaultDeduplicationTableBits);

/// <summary>
/// A Utf8 string pool that de-duplicates equal strings, created with specified page size and initial page count.
/// </summary>
/// <param name="pageSize">The size of the memory pages to allocate (allocation increment quantum).</param>
/// <param name="initialPageCount">The initial number of pages to allocate.</param>
/// <param name="deduplicationTableBits">Number of bits in the deduplication table (size will be 2^bits).</param>
/// <returns>The newly create string pool.</returns>
public static IUtf8DeduplicatedStringPool DeduplicatedUtf8(int pageSize, int initialPageCount, int deduplicationTableBits) =>
new Utf8StringPool(pageSize, initialPageCount, true, deduplicationTableBits);

/// <summary>
/// The total number of bytes allocated in all string pools.
Expand Down
16 changes: 11 additions & 5 deletions src/Combination.StringPools/Utf8StringPool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ private const int
PoolIndexBits =
24; // Number of bits to use for pool index in handle (more bits = more pools, but less strings per pool)

private const int DeduplicationTableBits = 10; // Number of bits to use for deduplication table (2^bits entries)
private static readonly List<Utf8StringPool?> Pools = new();
internal static long totalAllocatedBytes, totalUsedBytes, totalAddedBytes;

Expand All @@ -21,28 +20,35 @@ private const int

private readonly List<ulong>?[]? deduplicationTable;
private readonly DisposeLock disposeLock = new();
private readonly int deduplicationTableBits = 10; // Number of bits to use for deduplication table (2^bits entries)
private readonly int pageSize;

private readonly object writeLock = new();

// ReSharper disable once MemberCanBePrivate.Global
public Utf8StringPool(int pageSize, int initialPageCount, bool deduplicateStrings)
public Utf8StringPool(int pageSize, int initialPageCount, bool deduplicateStrings, int deduplicationTableBits)
{
if (pageSize < 16)
{
// We need at least 16 bytes to store the length of the string and an actual string
throw new ArgumentOutOfRangeException(nameof(pageSize));
}

if (deduplicationTableBits < 2 || deduplicationTableBits > 24)
{
throw new ArgumentOutOfRangeException(nameof(deduplicationTableBits));
}

if (initialPageCount < 0)
{
throw new ArgumentOutOfRangeException(nameof(initialPageCount));
}

this.deduplicationTableBits = deduplicationTableBits;
this.pageSize = pageSize;
if (deduplicateStrings)
{
deduplicationTable = new List<ulong>?[1 << DeduplicationTableBits];
deduplicationTable = new List<ulong>?[1 << deduplicationTableBits];
}

bool didAlloc;
Expand Down Expand Up @@ -202,7 +208,7 @@ private bool TryDeduplicate(int stringHash, string value, out ulong offset)
return false;
}

var tableIndex = stringHash & ((1 << DeduplicationTableBits) - 1);
var tableIndex = stringHash & ((1 << deduplicationTableBits) - 1);
var table = deduplicationTable[tableIndex];
if (table is null)
{
Expand Down Expand Up @@ -233,7 +239,7 @@ private void AddToDeduplicationTable(int stringHash, ulong handle)
return;
}

var tableIndex = stringHash & ((1 << DeduplicationTableBits) - 1);
var tableIndex = stringHash & ((1 << deduplicationTableBits) - 1);
var table = deduplicationTable[tableIndex] ?? (deduplicationTable[tableIndex] = new List<ulong>());

table.Add(handle);
Expand Down

0 comments on commit ebbec8d

Please sign in to comment.