public virtual void TestConcurrentHashMap() { // don't make threadCount and keyCount random, otherwise easily OOMs or fails otherwise: const int threadCount = 8, keyCount = 1024; RunnableAnonymousInnerClassHelper[] workers = new RunnableAnonymousInnerClassHelper[threadCount]; WeakIdentityMap <object, int?> map = WeakIdentityMap <object, int?> .NewConcurrentHashMap(Random().NextBoolean()); // we keep strong references to the keys, // so WeakIdentityMap will not forget about them: AtomicReferenceArray <object> keys = new AtomicReferenceArray <object>(keyCount); for (int j = 0; j < keyCount; j++) { keys[j] = new object(); } try { for (int t = 0; t < threadCount; t++) { Random rnd = new Random(Random().Next()); var worker = new RunnableAnonymousInnerClassHelper(this, keyCount, map, keys, rnd); workers[t] = worker; worker.Start(); } } finally { foreach (var w in workers) { w.Join(); } } // LUCENENET: Since assertions were done on the other threads, we need to check the // results here. for (int i = 0; i < workers.Length; i++) { assertTrue(string.Format(CultureInfo.InvariantCulture, "worker thread {0} of {1} failed \n" + workers[i].Error, i, workers.Length), workers[i].Error == null); } // clear strong refs for (int j = 0; j < keyCount; j++) { keys[j] = null; } // check that GC does not cause problems in reap() method: int size = map.Count; for (int i = 0; size > 0 && i < 10; i++) { #if !NETSTANDARD1_6 try { #endif GC.Collect(); int newSize = map.Count; Assert.IsTrue(size >= newSize, "previousSize(" + size + ")>=newSize(" + newSize + ")"); size = newSize; Thread.Sleep(new TimeSpan(100L)); int c = 0; foreach (object k in map.Keys) { Assert.IsNotNull(k); c++; } newSize = map.Count; Assert.IsTrue(size >= c, "previousSize(" + size + ")>=iteratorSize(" + c + ")"); Assert.IsTrue(c >= newSize, "iteratorSize(" + c + ")>=newSize(" + newSize + ")"); size = newSize; #if !NETSTANDARD1_6 } #pragma warning disable 168 catch (ThreadInterruptedException ie) #pragma warning restore 168 { } #endif } }
public virtual void TestCRTReopen() { //test behaving badly //should be high enough int maxStaleSecs = 20; //build crap data just to store it. string s = " abcdefghijklmnopqrstuvwxyz "; char[] chars = s.ToCharArray(); StringBuilder builder = new StringBuilder(2048); for (int i = 0; i < 2048; i++) { builder.Append(chars[Random().Next(chars.Length)]); } string content = builder.ToString(); SnapshotDeletionPolicy sdp = new SnapshotDeletionPolicy(new KeepOnlyLastCommitDeletionPolicy()); Directory dir = new NRTCachingDirectory(NewFSDirectory(CreateTempDir("nrt")), 5, 128); IndexWriterConfig config = new IndexWriterConfig( #pragma warning disable 612, 618 Version.LUCENE_46, #pragma warning restore 612, 618 new MockAnalyzer(Random())); config.SetIndexDeletionPolicy(sdp); config.SetOpenMode(OpenMode.CREATE_OR_APPEND); IndexWriter iw = new IndexWriter(dir, config); SearcherManager sm = new SearcherManager(iw, true, new SearcherFactory()); TrackingIndexWriter tiw = new TrackingIndexWriter(iw); ControlledRealTimeReopenThread <IndexSearcher> controlledRealTimeReopenThread = new ControlledRealTimeReopenThread <IndexSearcher>(tiw, sm, maxStaleSecs, 0); controlledRealTimeReopenThread.SetDaemon(true); controlledRealTimeReopenThread.Start(); IList <ThreadClass> commitThreads = new List <ThreadClass>(); for (int i = 0; i < 500; i++) { if (i > 0 && i % 50 == 0) { ThreadClass commitThread = new RunnableAnonymousInnerClassHelper(this, sdp, dir, iw); commitThread.Start(); commitThreads.Add(commitThread); } Document d = new Document(); d.Add(new TextField("count", i + "", Field.Store.NO)); d.Add(new TextField("content", content, Field.Store.YES)); long start = Environment.TickCount; long l = tiw.AddDocument(d); controlledRealTimeReopenThread.WaitForGeneration(l); long wait = Environment.TickCount - start; assertTrue("waited too long for generation " + wait, wait < (maxStaleSecs * 1000)); IndexSearcher searcher = sm.Acquire(); TopDocs td = searcher.Search(new TermQuery(new Term("count", i + "")), 10); sm.Release(searcher); assertEquals(1, td.TotalHits); } foreach (ThreadClass commitThread in commitThreads) { commitThread.Join(); } controlledRealTimeReopenThread.Dispose(); sm.Dispose(); iw.Dispose(); dir.Dispose(); }
public virtual void TestConcurrentHashMap() { // don't make threadCount and keyCount random, otherwise easily OOMs or fails otherwise: const int threadCount = 8, keyCount = 1024; RunnableAnonymousInnerClassHelper[] workers = new RunnableAnonymousInnerClassHelper[threadCount]; WeakIdentityMap<object, int?> map = WeakIdentityMap<object, int?>.NewConcurrentHashMap(Random().NextBoolean()); // we keep strong references to the keys, // so WeakIdentityMap will not forget about them: AtomicReferenceArray<object> keys = new AtomicReferenceArray<object>(keyCount); for (int j = 0; j < keyCount; j++) { keys[j] = new object(); } try { for (int t = 0; t < threadCount; t++) { Random rnd = new Random(Random().Next()); var worker = new RunnableAnonymousInnerClassHelper(this, keyCount, map, keys, rnd); workers[t] = worker; worker.Start(); } } finally { foreach (var w in workers) { w.Join(1000L); } } // LUCENENET: Since assertions were done on the other threads, we need to check the // results here. for (int i = 0; i < workers.Length; i++) { assertTrue(string.Format(CultureInfo.InvariantCulture, "worker thread {0} of {1} failed \n" + workers[i].Error, i, workers.Length), workers[i].Error == null); } // clear strong refs for (int j = 0; j < keyCount; j++) { keys[j] = null; } // check that GC does not cause problems in reap() method: int size = map.Size(); for (int i = 0; size > 0 && i < 10; i++) { try { GC.Collect(); int newSize = map.Size(); Assert.IsTrue(size >= newSize, "previousSize(" + size + ")>=newSize(" + newSize + ")"); size = newSize; Thread.Sleep(new TimeSpan(100L)); int c = 0; for (IEnumerator<object> it = map.Keys.GetEnumerator(); it.MoveNext();) { Assert.IsNotNull(it.Current); c++; } newSize = map.Size(); Assert.IsTrue(size >= c, "previousSize(" + size + ")>=iteratorSize(" + c + ")"); Assert.IsTrue(c >= newSize, "iteratorSize(" + c + ")>=newSize(" + newSize + ")"); size = newSize; } catch (ThreadInterruptedException ie) { } } }