public async Task Test_FdbCounter_Can_Increment_And_SetTotal() { using (var db = await OpenTestPartitionAsync()) { var location = db.Root["counters"]["simple"]; await CleanLocation(db, location); var counter = new FdbHighContentionCounter(location); await db.WriteAsync(async tr => await counter.Add(tr, 100), this.Cancellation); var res = await db.ReadAsync(tr => counter.GetSnapshot(tr), this.Cancellation); Assert.That(res, Is.EqualTo(100)); await db.WriteAsync(async tr => await counter.Add(tr, -10), this.Cancellation); res = await db.ReadAsync(tr => counter.GetSnapshot(tr), this.Cancellation); Assert.That(res, Is.EqualTo(90)); await db.WriteAsync(async tr => await counter.SetTotal(tr, 500), this.Cancellation); res = await db.ReadAsync(tr => counter.GetSnapshot(tr), this.Cancellation); Assert.That(res, Is.EqualTo(500)); } }
public async Task Bench_FdbCounter_Increment_Sequentially() { const int N = 100; using (var db = await OpenTestPartitionAsync()) { var location = db.Root["counters"]["big"]; await CleanLocation(db, location); var c = new FdbHighContentionCounter(location); Log("Doing " + N + " inserts in one thread..."); var sw = Stopwatch.StartNew(); for (int i = 0; i < N; i++) { await db.WriteAsync(async tr => await c.Add(tr, 1), this.Cancellation); } sw.Stop(); Log("> " + N + " completed in " + sw.Elapsed.TotalMilliseconds.ToString("N1") + " ms (" + (sw.Elapsed.TotalMilliseconds * 1000 / N).ToString("N0") + " µs/add)"); #if DEBUG await DumpSubspace(db, location); #endif var res = await db.ReadAsync(async tr => await c.GetSnapshot(tr), this.Cancellation); Assert.That(res, Is.EqualTo(N)); } }
public async Task Bench_FdbCounter_Increment_Concurrently() { const int B = 100; // repeat the process 10 times... foreach (int W in new [] { 1, 2, 5, 10, 20, 50, 100 }) { int N = B * W; using (var db = await OpenTestPartitionAsync()) { var location = db.Root["counters"]["big"][W.ToString()]; await CleanLocation(db, location); var c = new FdbHighContentionCounter(location); Log("Doing " + W + " x " + B + " inserts in " + W + " threads..."); var signal = new TaskCompletionSource <object>(); var workers = Enumerable.Range(0, W) .Select(async(id) => { await signal.Task.ConfigureAwait(false); for (int i = 0; i < B; i++) { await db.WriteAsync(async tr => await c.Add(tr, 1), this.Cancellation); } }).ToArray(); var sw = Stopwatch.StartNew(); // start ThreadPool.UnsafeQueueUserWorkItem((_) => signal.TrySetResult(null), null); // wait await Task.WhenAll(workers); sw.Stop(); Log("> " + N + " completed in " + sw.Elapsed.TotalMilliseconds.ToString("N1") + " ms (" + (sw.Elapsed.TotalMilliseconds * 1000 / B).ToString("N0") + " µs/add)"); long n = await db.ReadAsync(tr => c.GetSnapshot(tr), this.Cancellation); if (n != N) { // fail await DumpSubspace(db, location); Assert.That(n, Is.EqualTo(N), "Counter value does not match (first call)"); } // wait a bit, in case there was some coalesce still running... await Task.Delay(200); n = await db.ReadAsync(tr => c.GetSnapshot(tr), this.Cancellation); if (n != N) { // fail await DumpSubspace(db, location); Assert.That(n, Is.EqualTo(N), "Counter value does not match (second call)"); } } } }