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); } }
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."); } } }