예제 #1
0
 public bool TryGet(T key, out Span <byte> value)
 {
     _pool.Reset();
     if (_map.TryGetValue(key, out var vs))
     {
         value = _pool.GetSpan(vs.Length);
         vs.CopyTo(value);
         return(true);
     }
     else
     {
         value = Span <byte> .Empty;
         return(false);
     }
 }
예제 #2
0
        private static void DoBenchmark(IPEndPoint endpoint, ILog log)
        {
            var rand = new Random(); // non-deterministic on purpose

            var genWatch = new Stopwatch();

            genWatch.Start();

            var generator = new CoinGenerator(rand);

            generator.GenerateSketches(CoinIoCount);

            log.Log(LogSeverity.Info,
                    $"{CoinIoCount} coin I/Os generated in " + (genWatch.ElapsedMilliseconds / 1000f) + " seconds");

            var rawSocket = new Socket(endpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

            rawSocket.Connect(endpoint);
            var socket = new SocketLikeAdapter(rawSocket);

            EnsureGenesisExists(socket);

            var handle = OpenBlock(CommittedBlockId.Genesis, socket, log);

            // Process coins
            var requestPool    = new SpanPool <byte>(1024 * 1024);
            var responseBuffer = new Span <byte>(new byte[4096]);

            var watch        = new Stopwatch();
            var commitWatch  = new Stopwatch();
            var outpointSeed = generator.Random.Next();

            for (var i = 0; i < generator.CoinSketches.Length; i++)
            {
                if (i % EpochSize == 0)
                {
                    watch.Reset();
                    watch.Start();
                }

                var sketch   = generator.CoinSketches[i];
                var outpoint = GetOutpoint(sketch, outpointSeed);

                if (sketch.IsProduction)
                {
                    // intended side effect on 'requestPool'
                    var writeCoinRequest = new ProduceCoinRequest(
                        new RequestId((uint)i),
                        ref outpoint,
                        OutpointFlags.None,
                        handle,
                        satoshis: 123,
                        nLockTime: 42,
                        scriptSizeInBytes: 100,
                        requestPool);

                    var script = writeCoinRequest.Script;
                    script[0] = (byte)i;
                }

                if (sketch.IsRead)
                {
                    // intended side effect on 'requestPool'
                    var readCoinRequest =
                        new GetCoinRequest(new RequestId((uint)i), ref outpoint, handle, requestPool);
                }

                if (sketch.IsConsumption)
                {
                    // intended side effect on 'requestPool'
                    var writeCoinRequest = new ConsumeCoinRequest(
                        new RequestId((uint)i), ref outpoint, handle, requestPool);
                }

                if (i % BatchSize == BatchSize - 1)
                {
                    // send all the requests as a batch
                    socket.Send(requestPool.Allocated());
                    requestPool.Reset();

                    for (var j = 0; j < BatchSize; j++)
                    {
                        socket.Receive(responseBuffer.Slice(0, 4));
                        var responseSize = responseBuffer[0];
                        socket.Receive(responseBuffer.Slice(4, responseSize - 4));
                    }
                }

                if (i % EpochSize == EpochSize - 1)
                {
                    watch.Stop();

                    var nextBlockId = GetBlockId();

                    commitWatch.Reset();
                    commitWatch.Start();
                    CommitBlock(handle, nextBlockId, socket);
                    commitWatch.Stop();

                    handle = OpenBlock(nextBlockId, socket, log);

                    var elapsed = watch.ElapsedMilliseconds / 1000.0; // seconds

                    var iops = (int)(EpochSize / elapsed);

                    log.Log(LogSeverity.Info,
                            $"Epoch {i / EpochSize} at {iops} IOps. Commit in {commitWatch.Elapsed.TotalMilliseconds} ms.");
                }
            }
        }