コード例 #1
0
        public FdbRangeQuery <TId> LookupGreaterThan([NotNull] IFdbReadOnlyTransaction trans, TValue value, bool orEqual, bool reverse = false)
        {
            var prefix = this.Subspace.Keys.EncodePartial(value);

            if (!orEqual)
            {
                prefix = FdbKey.Increment(prefix);
            }

            var space = new KeySelectorPair(
                KeySelector.FirstGreaterThan(prefix),
                KeySelector.FirstGreaterOrEqual(this.Subspace.ToRange().End)
                );

            return(trans
                   .GetRange(space, new FdbRangeOptions {
                Reverse = reverse
            })
                   .Select((kvp) => this.Subspace.Keys.Decode(kvp.Key).Item2));
        }
コード例 #2
0
        public async Task Test_Range_Except()
        {
            int K = 3;
            int N = 100;

            using (var db = await OpenTestPartitionAsync())
            {
                // get a clean new directory
                var location = await GetCleanDirectory(db, "Queries", "Except");

                // create K lists
                var lists = Enumerable.Range(0, K).Select(i => location.Partition.ByKey(i)).ToArray();

                // lists[0] contains all multiples of 1
                // lists[1] contains all multiples of 2
                // lists[k-1] contains all multiples of K

                // more generally: lists[k][i] = (..., Intersect, k, i * (k + 1)) = (k, i)

                var series = Enumerable.Range(1, K).Select(k => Enumerable.Range(1, N).Select(x => k * x).ToArray()).ToArray();
                //foreach(var serie in series)
                //{
                //	Console.WriteLine(String.Join(", ", serie));
                //}

                for (int k = 0; k < K; k++)
                {
                    //Console.WriteLine("> k = " + k);
                    using (var tr = db.BeginTransaction(this.Cancellation))
                    {
                        for (int i = 0; i < N; i++)
                        {
                            var key   = lists[k].Keys.Encode(series[k][i]);
                            var value = STuple.EncodeKey(k, i);
                            //Console.WriteLine("> " + key + " = " + value);
                            tr.Set(key, value);
                        }
                        await tr.CommitAsync();
                    }
                }

                // Intersect all lists together should produce all integers that are prime numbers
                IEnumerable <int> xs = series[0];
                for (int i = 1; i < K; i++)
                {
                    xs = xs.Except(series[i]);
                }
                var expected = xs.ToArray();
                Log("Expected: {0}", String.Join(", ", expected));

                using (var tr = db.BeginTransaction(this.Cancellation))
                {
                    var merge = tr.Except(
                        lists.Select(list => KeySelectorPair.Create(list.Keys.ToRange())),
                        kvp => location.Keys.DecodeLast <int>(kvp.Key)
                        );

                    Assert.That(merge, Is.Not.Null);
                    Assert.That(merge, Is.InstanceOf <FdbExceptIterator <KeyValuePair <Slice, Slice>, int, KeyValuePair <Slice, Slice> > >());

                    var results = await merge.ToListAsync();

                    Assert.That(results, Is.Not.Null);

                    Assert.That(results.Count, Is.EqualTo(expected.Length));

                    for (int i = 0; i < results.Count; i++)
                    {
                        Assert.That(location.Keys.DecodeLast <int>(results[i].Key), Is.EqualTo(expected[i]));
                    }
                }
            }
        }
コード例 #3
0
        /// <summary>Return a range of keys</summary>
        /// <param name="query">Source database query</param>
        /// <param name="range">Pair of key selectors</param>
        /// <returns>Query that will return the keys from the specified <paramref name="range"/></returns>
        public static IFdbAsyncSequenceQueryable <KeyValuePair <Slice, Slice> > Range(this IFdbDatabaseQueryable query, KeySelectorPair range)
        {
            if (query == null)
            {
                throw new ArgumentNullException(nameof(query));
            }

            var expr = FdbQueryExpressions.Range(range);

            return(query.Provider.CreateSequenceQuery(expr));
        }
コード例 #4
0
 public static FdbQueryRangeExpression RangeStartsWith(Slice prefix, FdbRangeOptions options = null)
 {
     // starts_with('A') means ['A', B')
     return(Range(KeySelectorPair.StartsWith(prefix), options));
 }
コード例 #5
0
 public static FdbQueryRangeExpression Range(KeySelectorPair range, FdbRangeOptions options = null)
 {
     return(new FdbQueryRangeExpression(range, options));
 }
 internal FdbQueryRangeExpression(KeySelectorPair range, FdbRangeOptions options)
 {
     this.Range   = range;
     this.Options = options;
 }
コード例 #7
0
        private static async Task BenchMergeSortAsync(IFdbDatabase db, int N, int K, int B, CancellationToken ct)
        {
            Console.WriteLine($"=== BenchMergeSort(N={N:N0}, K={K:N0}, B={B:N0}) ===");

            // create multiple lists
            var location = db.Root.ByKey("MergeSort");
            await db.WriteAsync(async tr =>
            {
                var subspace = await location.Resolve(tr);
                tr.ClearRange(subspace);
            }, 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):N0} items... ");
            foreach (var source in sources)
            {
                using (var tr = await db.BeginTransactionAsync(ct))
                {
                    var list = await location.ByKey(source).Resolve(tr);

                    for (int i = 0; i < N; i++)
                    {
                        tr.Set(list.Encode(rnd.Next()), Slice.FromInt32(i));
                    }
                    await tr.CommitAsync();
                }
            }
            Console.WriteLine("Done");

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

            using (var tr = await db.BeginTransactionAsync(ct))
            {
                var subspace = await location.Resolve(tr);

                var mergesort = tr
                                .MergeSort(
                    sources.Select(source => KeySelectorPair.StartsWith(subspace.Encode(source))),
                    (kvp) => subspace.DecodeLast <int>(kvp.Key)
                    )
                                .Take(B)
                                .Select(kvp => subspace.Unpack(kvp.Key));

                Console.Write($"> MergeSort with limit {B:N0}... ");
                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:N0} results from {K} lists of {N} items each");

                //foreach (var result in results)
                //{
                //	Console.WriteLine(result.Get<int>(-1));
                //}
            }
            Console.WriteLine();
        }