public void CouldMoveAtOnNonEmpty(int count) { Assert.Fail("Need a proper MA test"); var s = new AppendSeries <int, int>(); for (int i = 1; i <= count; i++) { s.Append(i, i); } var searchValue = count / 2; // TODO all corners all directions and all inner var c = s.GetCursor(); Assert.IsTrue(c.MoveAt(searchValue, Lookup.GT)); Assert.AreEqual(searchValue + 1, c.CurrentValue); Assert.AreEqual(searchValue + 1, c.CurrentKey); Assert.IsTrue(c.MoveAt(searchValue, Lookup.GE)); Assert.IsTrue(c.MoveAt(searchValue, Lookup.EQ)); Assert.IsTrue(c.MoveAt(searchValue, Lookup.LE)); Assert.IsTrue(c.MoveAt(searchValue, Lookup.LT)); c.Dispose(); s.Dispose(); }
public async Task CouldCancelCursor() { var s = new AppendSeries <int, int>(); var c = s.GetAsyncEnumerator(); var t = Task.Run(async() => { try { await c.MoveNextAsync(); Assert.Fail(); } catch (Exception ex) { Assert.True(true); } }); Thread.Sleep(100); c.TryComplete(true); t.Wait(); c.Dispose(); s.Dispose(); }
public void NewSeries() { var s = new Series <int, int>(Array.Empty <int>(), Array.Empty <int>()); Assert.AreEqual(s.Mutability, Mutability.ReadOnly); Assert.AreEqual(s.KeySorting, KeySorting.Strong); Assert.AreEqual(0, s.RowCount.Value); s.Dispose(); Assert.IsTrue(s.IsDisposed); var aps = new AppendSeries <int, int>(); Assert.AreEqual(aps.Mutability, Mutability.AppendOnly); Assert.AreEqual(aps.KeySorting, KeySorting.Strong); Assert.AreEqual(0, aps.RowCount.Value); aps.Dispose(); Assert.IsTrue(aps.IsDisposed); var mus = new MutableSeries <int, int>(); Assert.AreEqual(mus.Mutability, Mutability.Mutable); Assert.AreEqual(mus.KeySorting, KeySorting.Strong); Assert.AreEqual(0, mus.RowCount.Value); mus.MarkAppendOnly(); mus.MarkAppendOnly(); // ignored, does not throw Assert.AreEqual(Mutability.AppendOnly, mus.Mutability); mus.MarkReadOnly(); mus.MarkReadOnly(); // ignored, does not throw Assert.AreEqual(Mutability.ReadOnly, mus.Mutability); Assert.Throws <InvalidOperationException>(() => { mus.MarkAppendOnly(); }); mus.Dispose(); Assert.IsTrue(mus.IsDisposed); }
public void CouldNotMoveNextPreviousOnEmpty() { var s = new AppendSeries <int, int>(); var c = s.GetCursor(); Assert.IsFalse(c.MoveNext()); Assert.IsFalse(c.MovePrevious()); Assert.IsFalse(c.MoveFirst()); Assert.IsFalse(c.MoveLast()); s.Append(1, 1); Assert.IsTrue(c.MoveNext()); Assert.IsFalse(c.MovePrevious()); Assert.IsTrue(c.MoveFirst()); Assert.IsTrue(c.MoveLast()); s.Append(2, 2); Assert.IsTrue(c.MoveNext()); Assert.AreEqual(2, c.CurrentKey); Assert.AreEqual(2, c.CurrentValue); Assert.IsTrue(c.MovePrevious()); Assert.AreEqual(1, c.CurrentKey); Assert.AreEqual(1, c.CurrentValue); Assert.IsTrue(c.MoveFirst()); Assert.IsTrue(c.MoveLast()); c.Dispose(); s.Dispose(); }
public void DeadCursorDoesNotCauseEndlessLoopInNotifyUpdate() { var s = new AppendSeries <int, int>(); s.Append(1, 1); var cursor = s.GetAsyncEnumerator(); Assert.True(cursor.MoveNext()); Assert.False(cursor.MoveNext()); cursor.MoveNextAsync(); cursor.Dispose(); cursor = default; GC.Collect(2, GCCollectionMode.Forced, true); GC.Collect(2, GCCollectionMode.Forced, true); //var t = Task.Run(() => cursor.MoveNextAsync(cts.Token)); s.Append(2, 2); s.Append(3, 3); Assert.True(s.RowCount == 3); s.Dispose(); }
public void CouldMoveAtOnSingle() { Assert.Fail("Proper MA tests"); var s = new AppendSeries <int, int>(); s.Append(1, 1); var c = s.GetCursor(); Assert.IsFalse(c.MoveAt(1, Lookup.GT)); Assert.IsTrue(c.MoveAt(1, Lookup.GE)); Assert.IsTrue(c.MoveAt(1, Lookup.EQ)); Assert.IsTrue(c.MoveAt(1, Lookup.LE)); Assert.IsFalse(c.MoveAt(1, Lookup.LT)); c.Dispose(); s.Dispose(); }
[Test, Ignore("broken")] // TODO public void CouldAppendSeries() { var sa = new AppendSeries <int, int>(DataBlock.Create()); Assert.IsTrue(sa.TryAddLast(1, 1).Result); Assert.IsFalse(sa.TryAddLast(1, 1).Result); Assert.IsTrue(sa.TryAddLast(2, 2).Result); Assert.Throws <KeyNotFoundException>(() => { var _ = sa[0]; }); Assert.AreEqual(1, sa[1]); Assert.AreEqual(2, sa[2]); Assert.AreEqual(2, sa.Count()); for (int i = 3; i < 42000; i++) { Assert.IsTrue(sa.TryAddLast(i, i).Result); Assert.AreEqual(i, sa.Last.Present.Value); } //// TODO remove when implemented //Assert.Throws<NotImplementedException>(() => //{ // for (int i = 32000; i < 33000; i++) // { // Assert.IsTrue(sa.TryAddLast(i, i).Result); // } //}); GC.Collect(2, GCCollectionMode.Forced, true, true); GC.WaitForPendingFinalizers(); GC.Collect(2, GCCollectionMode.Forced, true, true); GC.WaitForPendingFinalizers(); sa.Dispose(); GC.Collect(2, GCCollectionMode.Forced, true, true); GC.WaitForPendingFinalizers(); GC.Collect(2, GCCollectionMode.Forced, true, true); GC.WaitForPendingFinalizers(); }
public void CouldMovePreviousFromInitialized(int count) { var s = new AppendSeries <int, int>(); for (int i = 1; i <= count; i++) { s.Append(i, i); } var c = s.GetCursor(); Assert.IsTrue(c.MovePrevious()); Assert.AreEqual(count, c.CurrentKey); Assert.AreEqual(count, c.CurrentValue); c.Dispose(); s.Dispose(); }
public async Task CouldEnumerateSMUsingCursor() { var s = new AppendSeries <int, int>(); var count = (int)TestUtils.GetBenchCount(); for (int i = 0; i < count; i++) { s.Append(i, i); } #pragma warning disable HAA0401 // Possible allocation of reference type enumerator var ae = s.GetAsyncEnumerator(); #pragma warning restore HAA0401 // Possible allocation of reference type enumerator var t = Task.Run(async() => { using (Benchmark.Run("SCM.AsyncEnumerator", count)) { var cnt = 0; while (await ae.MoveNextAsync()) { cnt++; } await ae.DisposeAsync(); Assert.AreEqual(count * 2, cnt); } Benchmark.Dump(); }); for (int i = count; i < count * 2; i++) { s.Append(i, i); } s.MarkReadOnly(); t.Wait(); s.Dispose(); }
public void CancelledCursorDoesntCauseEndlessLoopInNotifyUpdate() { var s = new AppendSeries <int, int>(); s.Append(1, 1); var c = s.GetAsyncEnumerator(); Assert.True(c.MoveNext()); Assert.False(c.MoveNext()); c.MoveNextAsync(); s.Append(2, 2); s.Append(3, 3); Assert.True(s.RowCount == 3); c.Dispose(); s.Dispose(); }
public void CouldMoveFirstLast(int count) { var s = new AppendSeries <int, int>(); for (int i = 1; i <= count; i++) { s.Append(i, i); } SCursor <int, int> c; c = s.GetCursor(); Assert.IsTrue(c.MoveFirst()); Assert.IsTrue(c.MoveLast()); c.Dispose(); c = s.GetCursor(); Assert.IsTrue(c.MoveLast()); Assert.IsTrue(c.MoveFirst()); c.Dispose(); s.Dispose(); }
public async Task NotificationWorksWhenCursorIsNotWating() { var s = new AppendSeries <int, int>(); s.Append(1, 1); s.Append(2, 2); var c = s.GetAsyncEnumerator(); Assert.True(await c.MoveNextAsync()); Assert.True(await c.MoveNextAsync()); Assert.IsTrue(c.MovePrevious()); s.Append(3, 3); await Task.Delay(250); Assert.AreEqual(1, c.CurrentKey); Assert.AreEqual(1, c.CurrentValue); c.Dispose(); s.Dispose(); }
public async Task CouldAsyncEnumerate() { var s = new AppendSeries <int, int>(); var count = (int)TestUtils.GetBenchCount(10_000_000, 5); for (int i = 0; i < count; i++) { s.Append(i, i); } var t = Task.Run(async() => { using (Benchmark.Run("SCM.AsyncEnumerator", count)) { var cnt = 0; await foreach (var _ in s) { cnt++; } Assert.AreEqual(count * 2, cnt); } Benchmark.Dump(); }); for (int i = count; i < count * 2; i++) { s.Append(i, i); } s.MarkReadOnly(); t.Wait(); s.Dispose(); }
public void CouldAppendSeriesBench() { if (AdditionalCorrectnessChecks.Enabled) { Console.WriteLine("AdditionalCorrectnessChecks.Enabled"); } int count = 10_000_000; int rounds = 100; var sa = new AppendSeries <int, int>(DataBlock.Create()); var sm = new SortedMap <int, int>(); //for (int r = 0; r < rounds; r++) //{ // using (Benchmark.Run("SM.TryAddLast", count)) // { // for (int i = r * count; i < (r + 1) * count; i++) // { // if (i == r * count + 3) // { // continue; // } // if (!sm.TryAddLast(i, i).Result) // { // Assert.Fail("Cannot add " + i); // } // } // } // Console.WriteLine($"Added {((r + 1) * count / 1000000).ToString("N")}"); //} for (int r = 0; r < rounds; r++) { using (Benchmark.Run("Append", count)) { for (int i = r * count; i < (r + 1) * count; i++) { if (i == r * count + 3) { continue; } if (!sa.TryAddLast(i, i).Result) { Console.WriteLine("Cannot add " + i); return; } } } Console.WriteLine($"Added {((r + 1) * count / 1000000).ToString("N")}"); } Benchmark.Dump(); Console.WriteLine("Finished, press enter"); Console.ReadLine(); sa.Dispose(); }
public async Task CouldReadDataStreamWhileWritingFromManyThreads() { var map = new AppendSeries <int, int>(); var writeCount = 0L; var count = 1000_000_000; var rounds = 1; var writeTask = Task.Run(async() => { using (Benchmark.Run("Write", count * rounds, true)) { for (int j = 0; j < rounds; j++) { var t1 = Task.Run(() => { try { for (int i = j * count; i < (j + 1) * count; i++) { map.DangerousTryAppend(i, i); // Thread.SpinWait(10); // Thread.Yield(); Interlocked.Increment(ref writeCount); } } catch (Exception e) { Console.WriteLine(e); throw; } }); await t1; } } }); AsyncCursor <int, int, SCursor <int, int> > cursor = null; var cnt = 0L; var readTask = Task.Run(async() => { for (int r = 0; r < 1; r++) { using (cursor = new AsyncCursor <int, int, SCursor <int, int> >(map.GetCursor())) { using (Benchmark.Run("Read", count * rounds, true)) { try { while (await cursor.MoveNextAsync()) { Interlocked.Increment(ref cnt); // Thread.Sleep(1); } } catch (Exception e) { Console.WriteLine(e); throw; } // Left from coreclr 19161 tests, TODO remove when everything works OK // here is a strong reference to cursor with side effects of printing to console // Console.WriteLine("Last value: " + cursor.Current.Key); // another strong reference after while loop, we dereference it's value and return from task // lastKey1 = cursor.CurrentKey; } } } }); var monitor = true; var monitorTask = Task.Run(async() => { try { var previousR = cursor?.CurrentKey; var previousW = Volatile.Read(ref writeCount); while (monitor) { await Task.Delay(1000); var r = cursor.CurrentKey; var w = Volatile.Read(ref writeCount); Console.WriteLine($"R: {r:N0} - {((r - previousR) / 1000000.0):N2} Mops \t | W: {w:N0}- {((w - previousW) / 1000000.0):N2} Mops"); if (r == previousR) { Console.WriteLine($"IsAwaiting {cursor.IsTaskAwating} IsCompl {cursor.IsCompleted} Counter {cursor._counter}"); } previousR = r; previousW = w; // cursor.TryComplete(false); } } catch (Exception e) { Console.WriteLine(e); throw; } }); await writeTask; Console.WriteLine("COMPLETE"); map.MarkReadOnly(); map.NotifyUpdate(); Console.WriteLine("Read after map complete:" + Interlocked.Read(ref cnt)); await readTask; Console.WriteLine("Read after finish:" + Interlocked.Read(ref cnt)); // Console.WriteLine("Last key: " + lastKey); Benchmark.Dump(); GC.KeepAlive(cursor); map.Dispose(); monitor = false; }
public async Task CouldEnumerateSCMUsingCursor() { var s = new AppendSeries <int, int>(); var count = 1_000_000; // Settings.SCMDefaultChunkLength - 1; for (int i = 0; i < count; i++) { s.Append(i, i); } Console.WriteLine("Added first half"); #pragma warning disable HAA0401 // Possible allocation of reference type enumerator var ae = s.GetAsyncEnumerator(); #pragma warning restore HAA0401 // Possible allocation of reference type enumerator var t = Task.Run(async() => { using (Benchmark.Run("SCM.AsyncEnumerator", count)) { try { var cnt = 0; while (await ae.MoveNextAsync()) { if (cnt != ae.Current.Key) { ThrowHelper.ThrowInvalidOperationException(); } cnt++; } await ae.DisposeAsync(); } catch (Exception ex) { Console.WriteLine("EXCEPTION: " + ex.ToString()); throw; } // Assert.AreEqual(scm.Count, cnt); } Benchmark.Dump(); }); // Thread.Sleep(1000); for (int i = count; i < count * 2; i++) { s.Append(i, i); //Thread.SpinWait(50); } // Thread.Sleep(2000); s.MarkReadOnly(); t.Wait(); s.Dispose(); }
public void CouldMovePartialFromMoving(int count) { var s = new AppendSeries <int, int>(); for (int i = 1; i <= count; i++) { s.Append(i, i); } SCursor <int, int> c; c = s.GetCursor(); c.MoveNext(); Assert.AreEqual(count - 1, c.Move(count * 2, true)); Assert.AreEqual(count, c.CurrentKey); Assert.AreEqual(count, c.CurrentValue); c.Dispose(); c = s.GetCursor(); c.MoveNext(); Assert.AreEqual(count - 1, c.Move(count * 200, true)); Assert.AreEqual(count, c.CurrentKey); Assert.AreEqual(count, c.CurrentValue); c.Dispose(); c = s.GetCursor(); c.MoveNext(); Assert.AreEqual(count - 1, c.Move(count + 1, true)); Assert.AreEqual(count, c.CurrentKey); Assert.AreEqual(count, c.CurrentValue); c.Dispose(); c = s.GetCursor(); c.MoveNext(); Assert.AreEqual(count - 1, c.Move(count, true)); Assert.AreEqual(count, c.CurrentKey); Assert.AreEqual(count, c.CurrentValue); c.Dispose(); // --------- c = s.GetCursor(); c.MovePrevious(); Assert.AreEqual(-count + 1, c.Move(-count * 2, true)); Assert.AreEqual(1, c.CurrentKey); Assert.AreEqual(1, c.CurrentValue); c.Dispose(); c = s.GetCursor(); c.MovePrevious(); Assert.AreEqual(-count + 1, c.Move(-count * 200, true)); Assert.AreEqual(1, c.CurrentKey); Assert.AreEqual(1, c.CurrentValue); c.Dispose(); c = s.GetCursor(); c.MovePrevious(); Assert.AreEqual(-count + 1, c.Move(-(count + 1), true)); Assert.AreEqual(1, c.CurrentKey); Assert.AreEqual(1, c.CurrentValue); c.Dispose(); c = s.GetCursor(); c.MovePrevious(); Assert.AreEqual(-count + 1, c.Move(-count, true)); Assert.AreEqual(1, c.CurrentKey); Assert.AreEqual(1, c.CurrentValue); c.Dispose(); s.Dispose(); }
public void CouldAppendSeries(int count) { //var counts = new[] { 50, 50000 }; //foreach (var count in counts) { var sa = new AppendSeries <int, int>(); Assert.IsTrue(sa.TryAppend(1, 1)); Assert.AreEqual(1, sa.RowCount, "Row count == 1"); Assert.IsFalse(sa.TryAppend(1, 1)); Assert.IsTrue(sa.TryAppend(2, 2)); Assert.Throws <KeyNotFoundException>(() => { var _ = sa[0]; }); Assert.AreEqual(1, sa[1]); Assert.AreEqual(2, sa[2]); Assert.AreEqual(2, sa.Count()); for (int i = 3; i < count; i++) { Assert.IsTrue(sa.TryAppend(i, i)); Assert.AreEqual(i, sa.Last.Present.Value); } GC.Collect(2, GCCollectionMode.Forced, true, true); GC.WaitForPendingFinalizers(); GC.Collect(2, GCCollectionMode.Forced, true, true); GC.WaitForPendingFinalizers(); //using (var cursor = sa.GetEnumerator()) //{ // for (int i = 1; i < count; i++) // { // Assert.IsTrue(cursor.MoveNext(), $"could MN {i}"); // Assert.AreEqual(i, cursor.CurrentKey); // Assert.AreEqual(i, cursor.CurrentValue); // } //} //using (var cursor = sa.GetEnumerator()) //{ // for (int i = count - 1; i >= 1; i--) // { // Assert.IsTrue(cursor.MovePrevious(), $"could MP {i}"); // Assert.AreEqual(i, cursor.CurrentKey); // Assert.AreEqual(i, cursor.CurrentValue); // } //} using (var cursor = sa.GetEnumerator()) { Assert.IsTrue(cursor.Move(count + 1, false) == 0); Assert.IsTrue(cursor.State == CursorState.Initialized); } using (var cursor = sa.GetEnumerator()) { Assert.AreEqual(count - 1, cursor.Move(count + 1, true)); Assert.IsTrue(cursor.State == CursorState.Moving); Assert.AreEqual(sa.Last.Present.Key, cursor.CurrentKey); Assert.AreEqual(sa.Last.Present.Value, cursor.CurrentValue); } using (var cursor = sa.GetEnumerator()) { Assert.AreEqual(-(count - 1), cursor.Move(-count - 1, true)); Assert.IsTrue(cursor.State == CursorState.Moving); Assert.AreEqual(sa.First.Present.Key, cursor.CurrentKey); Assert.AreEqual(sa.First.Present.Value, cursor.CurrentValue); } sa.Dispose(); GC.Collect(2, GCCollectionMode.Forced, true, true); GC.WaitForPendingFinalizers(); GC.Collect(2, GCCollectionMode.Forced, true, true); GC.WaitForPendingFinalizers(); } }
public void CouldAppendSeriesBench() { if (AdditionalCorrectnessChecks.Enabled) { Console.WriteLine("AdditionalCorrectnessChecks.Enabled"); } int count = (int)TestUtils.GetBenchCount(10_000_000, 100_000); int rounds = (int)TestUtils.GetBenchCount(100, 10); var sl = new SortedList <int, int>(); //var cursor = sa.GetAsyncCursor(); //cursor.MoveNextAsync(); var di = new Dictionary <int, int>(); //for (int r = 0; r < rounds; r++) //{ // using (Benchmark.Run("SL.Add", count)) // { // for (int i = r * count; i < (r + 1) * count; i++) // { // if (i == r * count + 3) // { // continue; // } // sl.Add(i, i); // } // } // Console.WriteLine($"Added {((r + 1) * count / 1000000):N}"); //} //for (int r = 0; r < rounds; r++) //{ // using (Benchmark.Run("DI.Add", count)) // { // for (int i = r * count; i < (r + 1) * count; i++) // { // if (i == r * count + 3) // { // continue; // } // di.Add(i, i); // } // } // Console.WriteLine($"Added {((r + 1) * count / 1000000):N}"); //} BufferPool <int> .MemoryPool.PrintStats(); for (int _ = 0; _ < 2; _++) { var sa = new AppendSeries <int, int>(); for (int r = 0; r < rounds; r++) { using (Benchmark.Run("Append", count)) { for (int i = r * count; i < (r + 1) * count; i++) { if (i == r * count + 3) { continue; } if (!sa.DangerousTryAppend(i, i)) { Console.WriteLine("Cannot add " + i); return; } } } Console.WriteLine($"Added {((r + 1) * count / 1_000_000):N}"); } Benchmark.Dump(); BufferPool <int> .MemoryPool.PrintStats(); sa.Dispose(); BufferPool <int> .MemoryPool.PrintStats(); } }