Пример #1
0
        private async Task PushQueueAsync(IFdbTransaction tr, IDynamicKeySubspace queue, Slice taskId)
        {
            //TODO: use a high contention algo ?
            // - must support Push and Pop
            // - an empty queue must correspond to an empty subspace

            // get the current size of the queue
            var range   = queue.ToRange();
            var lastKey = await tr.Snapshot.GetKeyAsync(KeySelector.LastLessThan(range.End)).ConfigureAwait(false);

            int count = lastKey < range.Begin ? 0 : queue.DecodeFirst <int>(lastKey) + 1;

            // set the value
            tr.Set(queue.Encode(count, GetRandomId()), taskId);
        }
Пример #2
0
        private static async Task BenchSerialWriteAsync(IFdbDatabase db, int N, CancellationToken ct)
        {
            // read a lot of small keys, one by one

            Console.WriteLine($"=== BenchSerialWrite(N={N:N0}) ===");

            var                 location = db.Root.ByKey("hello");
            var                 sw       = Stopwatch.StartNew();
            IFdbTransaction     trans    = null;
            IDynamicKeySubspace subspace = null;

            try
            {
                for (int i = 0; i < N; i++)
                {
                    if (trans == null)
                    {
                        trans = await db.BeginTransactionAsync(ct);

                        subspace = await location.Resolve(trans);
                    }
                    trans.Set(subspace.Encode(i), Slice.FromInt32(i));
                    if (trans.Size > 100 * 1024)
                    {
                        await trans.CommitAsync();

                        trans.Dispose();
                        trans = null;
                    }
                }
                await trans.CommitAsync();
            }
            finally
            {
                trans?.Dispose();
            }
            sw.Stop();
            Console.WriteLine($"Took {sw.Elapsed.TotalSeconds:N3} sec to read {N:N0} items ({FormatTimeMicro(sw.Elapsed.TotalMilliseconds / N)}/read, {N/sw.Elapsed.TotalSeconds:N0} read/sec)");
            Console.WriteLine();
        }
Пример #3
0
        private async Task <KeyValuePair <Slice, Slice> > FindRandomItem(IFdbTransaction tr, IDynamicKeySubspace ring)
        {
            var range = ring.ToRange();

            // start from a random position around the ring
            var key = ring.Encode(GetRandomId());

            // We want to find the next item in the clockwise direction. If we reach the end of the ring, we "wrap around" by starting again from the start
            // => So we do find_next(key <= x < MAX) and if that does not produce any result, we do a find_next(MIN <= x < key)

            // When the ring only contains a few items (or is empty), there is more than 50% change that we wont find anything in the first read.
            // To reduce the latency for this case, we will issue both range reads at the same time, and discard the second one if the first returned something.
            // This should reduce the latency in half when the ring is empty, or when it contains only items before the random key.

            var candidate = await tr.GetRange(key, range.End).FirstOrDefaultAsync();

            if (!candidate.Key.IsPresent)
            {
                candidate = await tr.GetRange(range.Begin, key).FirstOrDefaultAsync();
            }

            return(candidate);
        }