/// <summary>Returns a Key Selector pair that defines the range of all items contained under this tuple</summary>
        public static FdbKeySelectorPair ToSelectorPair([NotNull] this IFdbTuple tuple)
        {
            if (tuple == null)
            {
                throw new ArgumentNullException("tuple");
            }

            return(FdbKeySelectorPair.StartsWith(tuple.ToSlice()));
        }
        private static async Task BenchMergeSortAsync(IFdbDatabase db, int N, int K, int B, CancellationToken ct)
        {
            // create multiple lists
            var location = db.Partition("MergeSort");
            await db.ClearRangeAsync(location, ct);

            var sources = Enumerable.Range(0, K).Select(i => 'A' + i).ToArray();
            var rnd     = new Random();

            // insert a number of random number lists
            Console.Write("> Inserting " + (K * N).ToString("N0", CultureInfo.InvariantCulture) + " items... ");
            foreach (var source in sources)
            {
                using (var tr = db.BeginTransaction(ct))
                {
                    var list = location.Partition(source);
                    for (int i = 0; i < N; i++)
                    {
                        tr.Set(list.Pack(rnd.Next()), Slice.FromInt32(i));
                    }
                    await tr.CommitAsync();
                }
            }
            Console.WriteLine("Done");

            // merge/sort them to get only one (hopefully sorted) list

            using (var tr = db.BeginTransaction(ct))
            {
                var mergesort = tr
                                .MergeSort(
                    sources.Select(source => FdbKeySelectorPair.StartsWith(location.Pack(source))),
                    (kvp) => location.UnpackLast <int>(kvp.Key)
                    )
                                .Take(B)
                                .Select(kvp => location.Unpack(kvp.Key));

                Console.Write("> MergeSort with limit " + B + "... ");
                var sw      = Stopwatch.StartNew();
                var results = await mergesort.ToListAsync();

                sw.Stop();
                Console.WriteLine("Done");

                Console.WriteLine("Took " + FormatTimeMilli(sw.Elapsed.TotalMilliseconds) + " to merge sort " + results.Count + " results from " + K + " lists of " + N + " items each");

                //foreach (var result in results)
                //{
                //	Console.WriteLine(result.Get<int>(-1));
                //}
            }
        }
 public static FdbQueryRangeExpression RangeStartsWith(Slice prefix, FdbRangeOptions options = null)
 {
     // starts_with('A') means ['A', B')
     return(Range(FdbKeySelectorPair.StartsWith(prefix), options));
 }