Skip to content

Commit

Permalink
PERFORMANCE: Lucene.Net.Facet.Taxonomy.WriterCache.NameInt32CacheLRU:…
Browse files Browse the repository at this point in the history
… Changed from Dictionary to ConcurrentDictionary so we can delete items from the cache while forward iterating through it. (see apache#261)
  • Loading branch information
NightOwl888 committed Jul 24, 2020
1 parent cfb72dc commit a0b53c6
Showing 1 changed file with 14 additions and 10 deletions.
24 changes: 14 additions & 10 deletions src/Lucene.Net.Facet/Taxonomy/WriterCache/NameIntCacheLRU.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using J2N.Collections.Concurrent;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;

namespace Lucene.Net.Facet.Taxonomy.WriterCache
{
Expand Down Expand Up @@ -39,6 +39,7 @@ public class NameInt32CacheLRU
internal long nMisses = 0; // for debug
internal long nHits = 0; // for debug
private readonly int maxCacheSize;
private readonly object syncLock = new object(); // LUCENENET specific so we don't lock this

internal NameInt32CacheLRU(int limit)
{
Expand All @@ -60,11 +61,13 @@ private void CreateCache(int maxSize)
{
if (maxSize < int.MaxValue)
{
cache = new LurchTable<object, int>(1000, LurchTableOrder.Access); //for LRU
cache = new LurchTable<object, int>(capacity: 1000, ordering: LurchTableOrder.Access); //for LRU
}
else
{
cache = new Dictionary<object, int>(1000); //no need for LRU
// LUCENENET specific - we use ConcurrentDictionary here because it supports deleting while
// iterating through the collection, but Dictionary does not.
cache = new ConcurrentDictionary<object, int>(concurrencyLevel: 3, capacity: 1000); //no need for LRU
}
}

Expand Down Expand Up @@ -149,7 +152,7 @@ internal virtual bool MakeRoomLRU()
return false;
}

lock (this)
lock (syncLock)
{
// Double-check that another thread didn't beat us to the operation
n = cache.Count - (2 * maxCacheSize) / 3;
Expand All @@ -159,13 +162,14 @@ internal virtual bool MakeRoomLRU()
}

//System.Diagnostics.Debug.WriteLine("Removing cache entries in MakeRoomLRU");

// LUCENENET: Loop in reverse so we can safely delete
// a range of items (0 - n) without a
// "Collection was modified" conflict
for (int i = n - 1; i >= 0; i--)
using (var it = cache.GetEnumerator())
{
cache.Remove(cache.Keys.ElementAt(i));
int i = 0;
while (i < n && it.MoveNext())
{
cache.Remove(it.Current.Key);
i++;
}
}
}
return true;
Expand Down

0 comments on commit a0b53c6

Please sign in to comment.