/// <summary>Return one or more fields of an hashset</summary> /// <param name="trans">Transaction that will be used for this request</param> /// <param name="id">Unique identifier of the hashset</param> /// <param name="fields">List of the fields to read</param> /// <returns>Dictionary containing the values of the selected fields, or Slice.Empty if that particular field does not exist.</returns> public async Task <IDictionary <string, Slice> > GetAsync([NotNull] IFdbReadOnlyTransaction trans, [NotNull] IFdbTuple id, [NotNull] params string[] fields) { if (trans == null) { throw new ArgumentNullException("trans"); } if (id == null) { throw new ArgumentNullException("id"); } if (fields == null) { throw new ArgumentNullException("fields"); } var keys = FdbTuple.EncodePrefixedKeys(GetKey(id), fields); var values = await trans.GetValuesAsync(keys).ConfigureAwait(false); Contract.Assert(values != null && values.Length == fields.Length); var results = new Dictionary <string, Slice>(values.Length, StringComparer.OrdinalIgnoreCase); for (int i = 0; i < fields.Length; i++) { results[fields[i]] = values[i]; } return(results); }
public async Task Run(IFdbDatabase db, TextWriter log, CancellationToken ct) { const int WORKERS = 1; const int RUN_IN_SECONDS = 100; await Init(db, ct); log.WriteLine("Initialized for " + this.Mode.ToString()); var timeline = new RobustTimeLine( TimeSpan.FromSeconds(1), RobustHistogram.TimeScale.Milliseconds, (histo, idx) => { if (idx == 0) { Console.WriteLine("T+s | " + RobustHistogram.GetDistributionScale(RobustHistogram.HorizontalScale, 1, 5000 - 1) + " | "); } Console.WriteLine(String.Format(CultureInfo.InvariantCulture, "{0,3} | {1} | {2,6:#,##0.0} ms (+/- {3:#0.000})", idx, histo.GetDistribution(1, 5000 - 1), histo.Median, histo.MedianAbsoluteDeviation())); if (log != Console.Out) { log.WriteLine(histo.GetReport(false)); } return(false); } ); var duration = Stopwatch.StartNew(); var foo = this.Subspace.Keys.Encode("foo"); var bar = Slice.FromString("bar"); var barf = Slice.FromString("barf"); long total = 0; timeline.Start(); var elapsed = await Program.RunConcurrentWorkersAsync( WORKERS, async (i, _ct) => { var dur = Stopwatch.StartNew(); int k = 0; while (dur.Elapsed.TotalSeconds < RUN_IN_SECONDS) { var sw = Stopwatch.StartNew(); switch (this.Mode) { case BenchMode.GetReadVersion: { await db.ReadAsync(tr => tr.GetReadVersionAsync(), ct); break; } case BenchMode.Get: { if (this.Value <= 1) { await db.ReadAsync(tr => tr.GetAsync(foo), ct); } else { var foos = FdbTuple.EncodePrefixedKeys(foo, Enumerable.Range(1, this.Value).ToArray()); await db.ReadAsync(tr => tr.GetValuesAsync(foos), ct); } break; } case BenchMode.Set: { await db.WriteAsync(tr => tr.Set(foo, bar), ct); break; } case BenchMode.Watch: { var w = await db.GetAndWatch(foo, ct); var v = w.Value; if (v == bar) { v = barf; } else { v = bar; } await db.WriteAsync((tr) => tr.Set(foo, v), ct); await w; break; } } sw.Stop(); timeline.Add(sw.Elapsed.TotalMilliseconds); Console.Write(k.ToString() + "\r"); ++k; Interlocked.Increment(ref total); } }, ct ); timeline.Stop(); Console.WriteLine("Done "); Console.WriteLine("# Ran {0} transactions in {1:0.0##} sec", total, elapsed.TotalSeconds); var global = timeline.MergeResults(); log.WriteLine("# Merged results:"); log.WriteLine(global.GetReport(true)); if (log != Console.Out) { Console.WriteLine("# Merged results:"); Console.WriteLine(global.GetReport(true)); } }