public virtual void TestThreadCorrectness() { const int NUM_THREADS = 4; const int CACHE_SIZE = 512; int OBJ_COUNT = 3 * CACHE_SIZE; DoubleBarrelLRUCache<CloneableObject, object> c = new DoubleBarrelLRUCache<CloneableObject, object>(1024); CloneableObject[] objs = new CloneableObject[OBJ_COUNT]; for (int i = 0; i < OBJ_COUNT; i++) { objs[i] = new CloneableObject(new object()); } CacheThread[] threads = new CacheThread[NUM_THREADS]; DateTime endTime = DateTime.Now.AddSeconds(1); for (int i = 0; i < NUM_THREADS; i++) { threads[i] = new CacheThread(this, c, objs, endTime); threads[i].Start(); } for (int i = 0; i < NUM_THREADS; i++) { threads[i].Join(); Assert.False(threads[i].Failed); } //System.out.println("hits=" + totHit + " misses=" + totMiss); }
public CacheThread(TestDoubleBarrelLRUCache outerInstance, DoubleBarrelLRUCache<CloneableObject, object> c, CloneableObject[] objs, long endTime) { this.OuterInstance = outerInstance; this.c = c; this.Objs = objs; this.EndTime = endTime; }
private void TestCache(DoubleBarrelLRUCache<CloneableInteger, object> cache, int n) { object dummy = new object(); for (int i = 0; i < n; i++) { cache.Put(new CloneableInteger(i), dummy); } // access every 2nd item in cache for (int i = 0; i < n; i += 2) { Assert.IsNotNull(cache.Get(new CloneableInteger(i))); } // add n/2 elements to cache, the ones that weren't // touched in the previous loop should now be thrown away for (int i = n; i < n + (n / 2); i++) { cache.Put(new CloneableInteger(i), dummy); } // access every 4th item in cache for (int i = 0; i < n; i += 4) { Assert.IsNotNull(cache.Get(new CloneableInteger(i))); } // add 3/4n elements to cache, the ones that weren't // touched in the previous loops should now be thrown away for (int i = n; i < n + (n * 3 / 4); i++) { cache.Put(new CloneableInteger(i), dummy); } // access every 4th item in cache for (int i = 0; i < n; i += 4) { Assert.IsNotNull(cache.Get(new CloneableInteger(i))); } }
/// <summary>Returns the TermInfo for a Term in the set, or null. </summary> private TermInfo Get(Term term, bool useCache, IState state) { if (size == 0) { return(null); } EnsureIndexIsRead(); TermInfo ti; ThreadResources resources = GetThreadResources(state); DoubleBarrelLRUCache <CloneableTerm, TermInfo> cache = null; if (useCache) { cache = termInfoCache; // check the cache first if the term was recently looked up ti = cache.Get(new CloneableTerm(DeepCopyOf(term))); if (ti != null) { return(ti); } } // optimize sequential access: first try scanning cached enum w/o seeking SegmentTermEnum enumerator = resources.termEnum; if (enumerator.Term != null && ((enumerator.Prev() != null && term.CompareTo(enumerator.Prev()) > 0) || term.CompareTo(enumerator.Term) >= 0)) { int enumOffset = (int)(enumerator.position / totalIndexInterval) + 1; if (indexTerms.Length == enumOffset || term.CompareTo(indexTerms[enumOffset]) < 0) { // no need to seek int numScans = enumerator.ScanTo(term, state); if (enumerator.Term != null && term.CompareTo(enumerator.Term) == 0) { ti = enumerator.TermInfo(); if (cache != null && numScans > 1) { // we only want to put this TermInfo into the cache if // scanEnum skipped more than one dictionary entry. // This prevents RangeQueries or WildcardQueries to // wipe out the cache when they iterate over a large numbers // of terms in order cache.Put(new CloneableTerm(DeepCopyOf(term)), ti); } } else { ti = null; } return(ti); } } // random-access: must seek SeekEnum(enumerator, GetIndexOffset(term), state); enumerator.ScanTo(term, state); if (enumerator.Term != null && term.CompareTo(enumerator.Term) == 0) { ti = enumerator.TermInfo(); if (cache != null) { cache.Put(new CloneableTerm(DeepCopyOf(term)), ti); } } else { ti = null; } return(ti); }