Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 38 additions & 38 deletions BitFaster.Caching/Lfu/ConcurrentLfu.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,4 @@
using System;

#if !NETSTANDARD2_0
using System.Buffers;
#endif

#if DEBUG
using System.Linq;
using System.Text;
#endif

using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
Expand All @@ -22,6 +12,15 @@
using BitFaster.Caching.Lru;
using BitFaster.Caching.Scheduler;

#if !NETSTANDARD2_0
using System.Buffers;
#endif

#if DEBUG
using System.Linq;
using System.Text;
#endif

namespace BitFaster.Caching.Lfu
{
/// <summary>
Expand Down Expand Up @@ -58,7 +57,7 @@ public sealed class ConcurrentLfu<K, V> : ICache<K, V>, IAsyncCache<K, V>, IBoun
private readonly IScheduler scheduler;

#if NETSTANDARD2_0
private readonly LfuNode<K, V>[] localDrainBuffer;
private readonly LfuNode<K, V>[] drainBuffer;
#endif

public ConcurrentLfu(int capacity)
Expand All @@ -84,7 +83,7 @@ public ConcurrentLfu(int concurrencyLevel, int capacity, IScheduler scheduler, I
this.scheduler = scheduler;

#if NETSTANDARD2_0
this.localDrainBuffer = new LfuNode<K, V>[this.readBuffer.Capacity];
this.drainBuffer = new LfuNode<K, V>[this.readBuffer.Capacity];
#endif
}

Expand Down Expand Up @@ -378,35 +377,22 @@ private void DrainBuffers()
private bool Maintenance(LfuNode<K, V> droppedWrite = null)
{
this.drainStatus.Set(DrainStatus.ProcessingToIdle);
var localDrainBuffer = RentDrainBuffer();

bool wasDrained = false;

#if !NETSTANDARD2_0
var localDrainBuffer = ArrayPool<LfuNode<K, V>>.Shared.Rent(this.readBuffer.Capacity);
#endif
int maxSweeps = 1;
int count = 0;
// extract to a buffer before doing book keeping work, ~2x faster
var count = readBuffer.DrainTo(localDrainBuffer);

for (int s = 0; s < maxSweeps; s++)
for (int i = 0; i < count; i++)
{
count = 0;

// extract to a buffer before doing book keeping work, ~2x faster
count = this.readBuffer.DrainTo(localDrainBuffer);

for (int i = 0; i < count; i++)
{
this.cmSketch.Increment(localDrainBuffer[i].Key);
}

for (int i = 0; i < count; i++)
{
OnAccess(localDrainBuffer[i]);
}
this.cmSketch.Increment(localDrainBuffer[i].Key);
}

wasDrained = count == 0;
for (int i = 0; i < count; i++)
{
OnAccess(localDrainBuffer[i]);
}

var wasDrained = count == 0;
count = this.writeBuffer.DrainTo(localDrainBuffer);

for (int i = 0; i < count; i++)
Expand All @@ -419,9 +405,7 @@ private bool Maintenance(LfuNode<K, V> droppedWrite = null)
OnWrite(droppedWrite);
}

#if !NETSTANDARD2_0
ArrayPool<LfuNode<K, V>>.Shared.Return(localDrainBuffer);
#endif
ReturnDrainBuffer(localDrainBuffer);

EvictEntries();
this.capacity.OptimizePartitioning(this.metrics, this.cmSketch.ResetSampleSize);
Expand Down Expand Up @@ -642,6 +626,22 @@ private void ReFitProtected()
}
}

private LfuNode<K, V>[] RentDrainBuffer()
{
#if !NETSTANDARD2_0
return ArrayPool<LfuNode<K, V>>.Shared.Rent(this.readBuffer.Capacity);
#else
return drainBuffer;
#endif
}

private void ReturnDrainBuffer(LfuNode<K, V>[] localDrainBuffer)
{
#if !NETSTANDARD2_0
ArrayPool<LfuNode<K, V>>.Shared.Return(localDrainBuffer);
#endif
}

[DebuggerDisplay("{Format(),nq}")]
private class DrainStatus
{
Expand Down