public void length_is_updated_when_index_higher_than_count_set() { BufferPool pool = new BufferPool(1, BufferManager); Assert.AreEqual(0, pool.Length); pool[3] = 5; Assert.AreEqual(4, pool.Length); }
public void a_write_will_automatically_grow_the_buffer_pool() { BufferPool pool = new BufferPool(1, BufferManager); int initialCapacity = pool.Capacity; pool[initialCapacity + 14] = 5; Assert.AreEqual(initialCapacity * 2, pool.Capacity); }
static SocketServer() { var max = CurrencyStoreSection.Instance.Server.Buffer.MaxLength; var size = CurrencyStoreSection.Instance.Server.Buffer.Size; socketArgsPool = new SocketArgsPool(max); bufferManager = new BufferPool(max * size, size); allowAllowAnonymous = CurrencyStoreSection.Instance.Authorization.AllowAnonymous; }
public void StartSound() { BufferSizeSamples = Sound.MillisecondsToSamples(Global.Config.SoundBufferSizeMs); MaxSamplesDeficit = BufferSizeSamples; _sourceID = AL.GenSource(); _bufferPool = new BufferPool(); _currentSamplesQueued = 0; }
public void ReleaseBufferTest() { string strBufferName = string.Empty; // TODO: 初始化为适当的值 long iInitialCapacity = 0; // TODO: 初始化为适当的值 long iBufferSize = 0; // TODO: 初始化为适当的值 BufferPool target = new BufferPool( strBufferName, iInitialCapacity, iBufferSize ); // TODO: 初始化为适当的值 byte[] byteBuffer = null; // TODO: 初始化为适当的值 target.ReleaseBuffer( byteBuffer ); Assert.Inconclusive( "无法验证不返回值的方法。" ); }
public void StopSound() { AL.SourceStop(_sourceID); AL.DeleteSource(_sourceID); _bufferPool.Dispose(); _bufferPool = null; BufferSizeSamples = 0; }
public void BufferPool() { BufferPool bp = new BufferPool(10000); int ct = 1000; for (int i = 0; i < ct; i++) { byte[] b = bp.GetBuffer(); Assert.AreEqual(10000, b.Length); bp.ReturnBuffer(b); } Console.WriteLine("{0} allocations for {1} uses of buffer pool.", bp.NumAllocations, ct); }
internal NetSocket(INetAddress address, BufferPool bufferPool, SocketEventArgPool socketPool, Socket baseSocket) { this.BufferPool = bufferPool; this.SocketPool = socketPool; this.BaseSocket = baseSocket; this.BaseSocket.NoDelay = true; this.IsClient = true; this.OnAccepted = delegate { }; this.OnReceived = delegate { }; this.OnSent = delegate { }; this.OnFault = delegate { }; }
public NetSocket(INetAddress address, BufferPool bufferPool, SocketEventArgPool socketPool) { this.Address = address; this.BufferPool = bufferPool; this.SocketPool = socketPool; this.BaseSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); this.BaseSocket.LingerState = new LingerOption(true, 0); this.BaseSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); this.IsClient = false; this.OnAccepted = delegate { }; this.OnReceived = delegate { }; this.OnSent = delegate { }; this.OnFault = delegate { }; }
public void ThreeThousandGetBuffers() { BufferPool pool = new BufferPool(10 * 1024 * 1024, 1, 1); //PLAN: //Just like HundredGetBuffers but with 3000 threads List<IBuffer> bufferList = new List<IBuffer>(); int threadNumber = 3000; int sizeOdd = 524288; int sizeEven = 524288; AquireBuffersConcurrently(pool, bufferList, threadNumber, sizeOdd, sizeEven); AssertIsContiguous(bufferList); Assert.IsTrue(pool.SlabCount == 150 || pool.SlabCount == 151, "SlabCount is " + pool.SlabCount + ". Was expecting 150 or 151"); }
private static void AquireBuffersConcurrently(BufferPool pool, List<IBuffer> bufferList, int threadNumber, int sizeOdd, int sizeEven) { object bufferList_sync = new object(); ManualResetEvent mre = new ManualResetEvent(false); for (int i = 0; i < threadNumber; i++) { Thread thread = new Thread(delegate(object number) { var size = ((int)number % 2 == 1 ? sizeOdd : sizeEven); //wait for signal mre.WaitOne(); //Aquire buffer IBuffer buff = pool.GetBuffer(size); //Add to Queue lock (bufferList_sync) { bufferList.Add(buff); } }); thread.IsBackground = true; thread.Start(i); } Thread.Sleep(500); //ensure all threads are waiting for signal mre.Set(); //signal event //Wait till all threads are done while (true) { lock (bufferList) { if (bufferList.Count == threadNumber) break; Thread.Sleep(500); } } }
public void StartSound() { BufferSizeSamples = Sound.MillisecondsToSamples(Global.Config.SoundBufferSizeMs); MaxSamplesDeficit = BufferSizeSamples; var format = new WaveFormat { SamplesPerSecond = Sound.SampleRate, BitsPerSample = Sound.BytesPerSample * 8, Channels = Sound.ChannelCount, FormatTag = WaveFormatTag.Pcm, BlockAlignment = Sound.BlockAlign, AverageBytesPerSecond = Sound.SampleRate * Sound.BlockAlign }; _sourceVoice = new SourceVoice(_device, format); _bufferPool = new BufferPool(); _runningSamplesQueued = 0; _sourceVoice.Start(); }
public void HundredGetBuffers() { BufferPool pool = new BufferPool(10 * 1024 * 1024, 1, 1); //PLAN: //Create 100 threads. Odd numbered threads will request buffer sizes of 314567 bytes //whereas even numbered threads will request buffer sizes of 314574 bytes //for a total allocation of 31457100 bytes. //If everything goes well there will be no overlap in allocated buffers //and there'll be no free space greater than 314574 (the lower number) on total slabs - 1 //and slabs should be 4 List<IBuffer> bufferList = new List<IBuffer>(); int threadNumber = 100; int sizeOdd = 314567; int sizeEven = 314574; AquireBuffersConcurrently(pool, bufferList, threadNumber, sizeOdd, sizeEven); AssertIsContiguous(bufferList); Assert.IsTrue(pool.SlabCount == 3 || pool.SlabCount == 4, "SlabCount is " + pool.SlabCount + ". Was expecting 3 or 4"); }
public void a_larger_length_makes_capacity_larger() { BufferManager manager = new BufferManager(10, 1000, 1); BufferPool pool = new BufferPool(1, manager); pool.SetLength(5000); Assert.AreNotEqual(5000, pool.Capacity); }
public void length_is_set_when_setting_length() { BufferPool pool = new BufferPool(1, BufferManager); pool.SetLength(5000, false); Assert.AreEqual(5000, pool.Length); }
/// <summary> /// This is called when client is aware of proxy /// So for HTTPS requests client would send CONNECT header to negotiate a secure tcp tunnel via proxy /// </summary> /// <param name="endPoint">The explicit endpoint.</param> /// <param name="clientConnection">The client connection.</param> /// <returns>The task.</returns> private async Task handleClient(ExplicitProxyEndPoint endPoint, TcpClientConnection clientConnection) { var cancellationTokenSource = new CancellationTokenSource(); var cancellationToken = cancellationTokenSource.Token; var clientStream = new CustomBufferedStream(clientConnection.GetStream(), BufferPool); var clientStreamWriter = new HttpResponseWriter(clientStream, BufferPool); Task <TcpServerConnection>?prefetchConnectionTask = null; bool closeServerConnection = false; bool calledRequestHandler = false; SslStream?sslStream = null; try { string?connectHostname = null; TunnelConnectSessionEventArgs?connectArgs = null; // Client wants to create a secure tcp tunnel (probably its a HTTPS or Websocket request) if (await HttpHelper.IsConnectMethod(clientStream, BufferPool, cancellationToken) == 1) { // read the first line HTTP command string?httpCmd = await clientStream.ReadLineAsync(cancellationToken); if (string.IsNullOrEmpty(httpCmd)) { return; } Request.ParseRequestLine(httpCmd !, out string _, out string httpUrl, out var version); var httpRemoteUri = new Uri("http://" + httpUrl); connectHostname = httpRemoteUri.Host; var connectRequest = new ConnectRequest { RequestUri = httpRemoteUri, OriginalUrl = httpUrl, HttpVersion = version }; await HeaderParser.ReadHeaders(clientStream, connectRequest.Headers, cancellationToken); connectArgs = new TunnelConnectSessionEventArgs(this, endPoint, connectRequest, cancellationTokenSource); clientStream.DataRead += (o, args) => connectArgs.OnDataSent(args.Buffer, args.Offset, args.Count); clientStream.DataWrite += (o, args) => connectArgs.OnDataReceived(args.Buffer, args.Offset, args.Count); connectArgs.ProxyClient.Connection = clientConnection; connectArgs.ProxyClient.ClientStream = clientStream; await endPoint.InvokeBeforeTunnelConnectRequest(this, connectArgs, ExceptionFunc); // filter out excluded host names bool decryptSsl = endPoint.DecryptSsl && connectArgs.DecryptSsl; if (connectArgs.DenyConnect) { if (connectArgs.HttpClient.Response.StatusCode == 0) { connectArgs.HttpClient.Response = new Response { HttpVersion = HttpHeader.Version11, StatusCode = (int)HttpStatusCode.Forbidden, StatusDescription = "Forbidden" }; } // send the response await clientStreamWriter.WriteResponseAsync(connectArgs.HttpClient.Response, cancellationToken : cancellationToken); return; } if (await checkAuthorization(connectArgs) == false) { await endPoint.InvokeBeforeTunnelConnectResponse(this, connectArgs, ExceptionFunc); // send the response await clientStreamWriter.WriteResponseAsync(connectArgs.HttpClient.Response, cancellationToken : cancellationToken); return; } // write back successful CONNECT response var response = ConnectResponse.CreateSuccessfulConnectResponse(version); // Set ContentLength explicitly to properly handle HTTP 1.0 response.ContentLength = 0; response.Headers.FixProxyHeaders(); connectArgs.HttpClient.Response = response; await clientStreamWriter.WriteResponseAsync(response, cancellationToken : cancellationToken); var clientHelloInfo = await SslTools.PeekClientHello(clientStream, BufferPool, cancellationToken); bool isClientHello = clientHelloInfo != null; if (clientHelloInfo != null) { connectRequest.TunnelType = TunnelType.Https; connectRequest.ClientHelloInfo = clientHelloInfo; } await endPoint.InvokeBeforeTunnelConnectResponse(this, connectArgs, ExceptionFunc, isClientHello); if (decryptSsl && clientHelloInfo != null) { clientConnection.SslProtocol = clientHelloInfo.SslProtocol; connectRequest.RequestUri = new Uri("https://" + httpUrl); bool http2Supported = false; var alpn = clientHelloInfo.GetAlpn(); if (alpn != null && alpn.Contains(SslApplicationProtocol.Http2)) { // test server HTTP/2 support try { // todo: this is a hack, because Titanium does not support HTTP protocol changing currently var connection = await tcpConnectionFactory.GetServerConnection(this, connectArgs, isConnect : true, applicationProtocols : SslExtensions.Http2ProtocolAsList, noCache : true, cancellationToken : cancellationToken); http2Supported = connection.NegotiatedApplicationProtocol == SslApplicationProtocol.Http2; // release connection back to pool instead of closing when connection pool is enabled. await tcpConnectionFactory.Release(connection, true); } catch (Exception) { // ignore } } if (EnableTcpServerConnectionPrefetch) { IPAddress[]? ipAddresses = null; try { // make sure the host can be resolved before creating the prefetch task ipAddresses = await Dns.GetHostAddressesAsync(connectArgs.HttpClient.Request.RequestUri.Host); } catch (SocketException) { } if (ipAddresses != null && ipAddresses.Length > 0) { // don't pass cancellation token here // it could cause floating server connections when client exits prefetchConnectionTask = tcpConnectionFactory.GetServerConnection(this, connectArgs, isConnect: true, applicationProtocols: null, noCache: false, cancellationToken: CancellationToken.None); } } X509Certificate2?certificate = null; try { sslStream = new SslStream(clientStream, false); string certName = HttpHelper.GetWildCardDomainName(connectHostname); certificate = endPoint.GenericCertificate ?? await CertificateManager.CreateServerCertificate(certName); // Successfully managed to authenticate the client using the fake certificate var options = new SslServerAuthenticationOptions(); if (EnableHttp2 && http2Supported) { options.ApplicationProtocols = clientHelloInfo.GetAlpn(); if (options.ApplicationProtocols == null || options.ApplicationProtocols.Count == 0) { options.ApplicationProtocols = SslExtensions.Http11ProtocolAsList; } } options.ServerCertificate = certificate; options.ClientCertificateRequired = false; options.EnabledSslProtocols = SupportedSslProtocols; options.CertificateRevocationCheckMode = X509RevocationMode.NoCheck; await sslStream.AuthenticateAsServerAsync(options, cancellationToken); #if NETSTANDARD2_1 clientConnection.NegotiatedApplicationProtocol = sslStream.NegotiatedApplicationProtocol; #endif // HTTPS server created - we can now decrypt the client's traffic clientStream = new CustomBufferedStream(sslStream, BufferPool); clientStream.DataRead += (o, args) => connectArgs.OnDecryptedDataSent(args.Buffer, args.Offset, args.Count); clientStream.DataWrite += (o, args) => connectArgs.OnDecryptedDataReceived(args.Buffer, args.Offset, args.Count); clientStreamWriter = new HttpResponseWriter(clientStream, BufferPool); } catch (Exception e) { var certName = certificate?.GetNameInfo(X509NameType.SimpleName, false); throw new ProxyConnectException( $"Couldn't authenticate host '{connectHostname}' with certificate '{certName}'.", e, connectArgs); } if (await HttpHelper.IsConnectMethod(clientStream, BufferPool, cancellationToken) == -1) { decryptSsl = false; } if (!decryptSsl) { await tcpConnectionFactory.Release(prefetchConnectionTask, true); prefetchConnectionTask = null; } } if (cancellationTokenSource.IsCancellationRequested) { throw new Exception("Session was terminated by user."); } // Hostname is excluded or it is not an HTTPS connect if (!decryptSsl || !isClientHello) { if (!isClientHello) { connectRequest.TunnelType = TunnelType.Websocket; } // create new connection to server. // If we detected that client tunnel CONNECTs without SSL by checking for empty client hello then // this connection should not be HTTPS. var connection = await tcpConnectionFactory.GetServerConnection(this, connectArgs, isConnect: true, applicationProtocols : SslExtensions.Http2ProtocolAsList, noCache : true, cancellationToken : cancellationToken); try { if (isClientHello) { int available = clientStream.Available; if (available > 0) { // send the buffered data var data = BufferPool.GetBuffer(); try { // clientStream.Available should be at most BufferSize because it is using the same buffer size await clientStream.ReadAsync(data, 0, available, cancellationToken); await connection.StreamWriter.WriteAsync(data, 0, available, true, cancellationToken); } finally { BufferPool.ReturnBuffer(data); } } var serverHelloInfo = await SslTools.PeekServerHello(connection.Stream, BufferPool, cancellationToken); ((ConnectResponse)connectArgs.HttpClient.Response).ServerHelloInfo = serverHelloInfo; } if (!clientStream.IsClosed && !connection.Stream.IsClosed) { await TcpHelper.SendRaw(clientStream, connection.Stream, BufferPool, null, null, connectArgs.CancellationTokenSource, ExceptionFunc); } } finally { await tcpConnectionFactory.Release(connection, true); } return; } } if (connectArgs != null && await HttpHelper.IsPriMethod(clientStream, BufferPool, cancellationToken) == 1) { // todo string?httpCmd = await clientStream.ReadLineAsync(cancellationToken); if (httpCmd == "PRI * HTTP/2.0") { connectArgs.HttpClient.ConnectRequest !.TunnelType = TunnelType.Http2; // HTTP/2 Connection Preface string?line = await clientStream.ReadLineAsync(cancellationToken); if (line != string.Empty) { throw new Exception($"HTTP/2 Protocol violation. Empty string expected, '{line}' received"); } line = await clientStream.ReadLineAsync(cancellationToken); if (line != "SM") { throw new Exception($"HTTP/2 Protocol violation. 'SM' expected, '{line}' received"); } line = await clientStream.ReadLineAsync(cancellationToken); if (line != string.Empty) { throw new Exception($"HTTP/2 Protocol violation. Empty string expected, '{line}' received"); } var connection = await tcpConnectionFactory.GetServerConnection(this, connectArgs, isConnect : true, applicationProtocols : SslExtensions.Http2ProtocolAsList, noCache : true, cancellationToken : cancellationToken); try { #if NETSTANDARD2_1 var connectionPreface = new ReadOnlyMemory <byte>(Http2Helper.ConnectionPreface); await connection.StreamWriter.WriteAsync(connectionPreface, cancellationToken); await Http2Helper.SendHttp2(clientStream, connection.Stream, () => new SessionEventArgs(this, endPoint, cancellationTokenSource) { ProxyClient = { Connection = clientConnection }, HttpClient = { ConnectRequest = connectArgs?.HttpClient.ConnectRequest }, UserData = connectArgs?.UserData }, async args => { await onBeforeRequest(args); }, async args => { await onBeforeResponse(args); }, connectArgs.CancellationTokenSource, clientConnection.Id, ExceptionFunc); #endif } finally { await tcpConnectionFactory.Release(connection, true); } } } calledRequestHandler = true; // Now create the request await handleHttpSessionRequest(endPoint, clientConnection, clientStream, clientStreamWriter, cancellationTokenSource, connectHostname, connectArgs, prefetchConnectionTask); } catch (ProxyException e) { closeServerConnection = true; onException(clientStream, e); } catch (IOException e) { closeServerConnection = true; onException(clientStream, new Exception("Connection was aborted", e)); } catch (SocketException e) { closeServerConnection = true; onException(clientStream, new Exception("Could not connect", e)); } catch (Exception e) { closeServerConnection = true; onException(clientStream, new Exception("Error occured in whilst handling the client", e)); } finally { if (!calledRequestHandler) { await tcpConnectionFactory.Release(prefetchConnectionTask, closeServerConnection); } sslStream?.Dispose(); clientStream.Dispose(); if (!cancellationTokenSource.IsCancellationRequested) { cancellationTokenSource.Cancel(); } } }
unsafe TypedIndex CopyToBuilderCache(ref Buffer <UntypedList> sourceCaches, ref Buffer <UntypedList> targetCaches, int typeId, int sourceByteIndex, BufferPool pool) { ref var sourceCache = ref sourceCaches[typeId];
public NetworkPacketWriter() { buffer = BufferPool.Take(0x8192); }
public void the_byte_array_should_be_the_same_length_as_the_pool_with_data() { BufferPool pool = new BufferPool(5, BufferManager); for (int i = 0; i < 500; i++) { pool[i] = 12; } Assert.AreEqual(500, pool.ToByteArray().Length); }
public override void Setup() { base.Setup(); m_DisposedPool = new BufferPool(10, BufferManager); m_DisposedPool.Dispose(); }
public void data_that_has_been_set_can_read() { BufferPool pool = new BufferPool(1, BufferManager); pool[3] = 5; Assert.AreEqual(5, pool[3]); }
public static void Handle(Player player, byte[] buffer) { try { fixed(byte *p = buffer) { var packet = *(MsgSyndicate *)p; BufferPool.RecycleBuffer(buffer); switch (packet.Type) { case GuildRequest.ApplyJoin: if (GameWorld.Find(packet.Param, out Player found)) { if (found.Guild != null) { player.JoinGuildRequest = found.UniqueId; packet.Param = player.UniqueId; found.Send(packet); } } break; case GuildRequest.InviteJoin: if (GameWorld.Find(packet.Param, out Player found2)) { if (found2.JoinGuildRequest == player.UniqueId) { player.Guild.Add(found2); } } break; case GuildRequest.LeaveSyn: player.Guild.Leave(player); break; case GuildRequest.KickOutMember: if (GameWorld.Find(packet.Param, out Player found3)) { found3.Guild.Leave(found3); } break; case GuildRequest.QuerySynName: if (Collections.Guilds.TryGetValue(packet.Param, out var guild)) { player.Send(MsgName.Create(packet.Param, guild.Name, (byte)MsgNameType.Syndicate)); } break; //case GuildRequest.SetAlly: // break; //case GuildRequest.ClearAlly: // break; //case GuildRequest.SetEnemy: // break; //case GuildRequest.ClearAntagonize: // break; case GuildRequest.DonateMoney: if (player.Money >= packet.Param) { player.GuildDonation += packet.Param; player.Guild.Funds += packet.Param; player.Money -= packet.Param; player.Send(packet); } break; case GuildRequest.QuerySynAttr: if (player.UniqueId == packet.Param) { if (player.Guild == null) { return; } player.Send(MsgName.Create(player.Guild.UniqueId, player.Guild.Name, (byte)MsgNameType.Syndicate)); player.Send(MsgSyndicateSpawn.Create(player)); player.Send(MsgText.Create(Constants.System, Constants.Allusers, player.Guild.Bulletin, MsgTextType.GuildBulletin)); } break; //case GuildRequest.SetSyn: // break; //case GuildRequest.UniteSubSyn: // break; //case GuildRequest.UniteSyn: // break; //case GuildRequest.SetWhiteSyn: // break; //case GuildRequest.SetBlackSyn: // break; //case GuildRequest.DestroySyn: // break; //case GuildRequest.SetMantle: // break; default: Output.WriteLine(((byte[])packet).HexDump()); break; } } } catch (Exception e) { Output.WriteLine(e); } }
public void a_smaller_length_lowers_capacity() { BufferManager manager = new BufferManager(10, 1000, 1); BufferPool pool = new BufferPool(5, manager); pool.SetLength(1); Assert.AreEqual(9, manager.AvailableBuffers); }
public unsafe void GetSelfOverlapsViaStreamingQueries <TResultList>(ref TResultList results) where TResultList : IList <Overlap> { //var startTime = Stopwatch.GetTimestamp(); var rootTarget = new StreamingTarget { LeafGroups = new QuickList <StreamingLeafGroup>(BufferPools <StreamingLeafGroup> .Locking, BufferPool <StreamingLeafGroup> .GetPoolIndex(LeafCount)) }; rootTarget.LeafGroups.Add(new StreamingLeafGroup()); for (int i = 0; i < LeafCount; ++i) { BoundingBoxWide leafWide; BoundingBoxWide.GetBoundingBox(ref Levels[leaves[i].LevelIndex].Nodes[leaves[i].NodeIndex].BoundingBoxes, leaves[i].ChildIndex, out leafWide); var leafIndexWide = new Vector <int>(i); rootTarget.Add(ref leafIndexWide, ref leafWide, singleMasks); } //var endTime = Stopwatch.GetTimestamp(); //Console.WriteLine($"Initial target construction time: {(endTime - startTime) / (double)Stopwatch.Frequency}"); QuickQueue <StreamingTarget> targets = new QuickQueue <StreamingTarget>(BufferPools <StreamingTarget> .Locking, BufferPool <StreamingLeafGroup> .GetPoolIndex(LeafCount)); targets.Enqueue(ref rootTarget); QuickList <int> fallbackResults = new QuickList <int>(BufferPools <int> .Locking); StreamingTarget target; while (targets.TryDequeueLast(out target)) { const int GroupFallbackThreshold = 2; //unfortunately, this should be as high as possible right now because the regular query is faster, period. if (target.LeafGroups.Count <= GroupFallbackThreshold) { var max = target.LastLeavesCount == Vector <int> .Count ? target.LeafGroups.Count : target.LeafGroups.Count - 1; for (int leafGroupIndex = 0; leafGroupIndex < max; ++leafGroupIndex) { for (int leafInGroupIndex = 0; leafInGroupIndex < Vector <int> .Count; ++leafInGroupIndex) { BoundingBoxWide leafWide; BoundingBoxWide.GetBoundingBox(ref target.LeafGroups.Elements[leafGroupIndex].BoundingBoxes, leafInGroupIndex, out leafWide); TestRecursive(target.LevelIndex, target.NodeIndex, ref leafWide, ref fallbackResults); for (int resultIndex = 0; resultIndex < fallbackResults.Count; ++resultIndex) { var queryLeafIndex = target.LeafGroups.Elements[leafGroupIndex].Leaves[leafInGroupIndex]; if (queryLeafIndex < fallbackResults.Elements[resultIndex]) { results.Add(new Overlap { A = queryLeafIndex, B = fallbackResults.Elements[resultIndex] }); } } fallbackResults.Count = 0; } } if (target.LastLeavesCount < Vector <int> .Count) { var leafGroupIndex = target.LeafGroups.Count - 1; for (int leafInGroupIndex = 0; leafInGroupIndex < target.LastLeavesCount; ++leafInGroupIndex) { BoundingBoxWide leafWide; BoundingBoxWide.GetBoundingBox(ref target.LeafGroups.Elements[leafGroupIndex].BoundingBoxes, leafInGroupIndex, out leafWide); TestRecursive(target.LevelIndex, target.NodeIndex, ref leafWide, ref fallbackResults); for (int resultIndex = 0; resultIndex < fallbackResults.Count; ++resultIndex) { var queryLeafIndex = target.LeafGroups.Elements[leafGroupIndex].Leaves[leafInGroupIndex]; if (queryLeafIndex < fallbackResults.Elements[resultIndex]) { results.Add(new Overlap { A = queryLeafIndex, B = fallbackResults.Elements[resultIndex] }); } } fallbackResults.Count = 0; } } } else { var node = Levels[target.LevelIndex].Nodes[target.NodeIndex]; //Test each node child against all of the leaves for this node. for (int nodeChildIndex = 0; nodeChildIndex < Vector <int> .Count; ++nodeChildIndex) { if (node.Children[nodeChildIndex] == -1) { continue; } BoundingBoxWide nodeChildWide; BoundingBoxWide.GetBoundingBox(ref node.BoundingBoxes, nodeChildIndex, out nodeChildWide); if (node.Children[nodeChildIndex] >= 0) { //Internal node. Can spawn more targets. StreamingTarget newTarget = new StreamingTarget { LevelIndex = target.LevelIndex + 1, NodeIndex = node.Children[nodeChildIndex], LeafGroups = new QuickList <StreamingLeafGroup>(BufferPools <StreamingLeafGroup> .Locking, BufferPool <StreamingLeafGroup> .GetPoolIndex(target.LeafGroups.Count)) }; newTarget.LeafGroups.Add(new StreamingLeafGroup()); for (int leafGroupIndex = 0; leafGroupIndex < target.LeafGroups.Count; ++leafGroupIndex) { Vector <int> intersectionMask; BoundingBoxWide.Intersects(ref nodeChildWide, ref target.LeafGroups.Elements[leafGroupIndex].BoundingBoxes, out intersectionMask); int leafCountInGroup = leafGroupIndex == target.LeafGroups.Count - 1 ? target.LastLeavesCount : Vector <int> .Count; for (int leafIndexInGroup = 0; leafIndexInGroup < leafCountInGroup; ++leafIndexInGroup) { if (intersectionMask[leafIndexInGroup] < 0) { newTarget.Add(ref target, leafGroupIndex, leafIndexInGroup, singleMasks); } } } targets.Enqueue(ref newTarget); } else { //Leaf node. var nodeLeafIndex = Encode(node.Children[nodeChildIndex]); for (int leafGroupIndex = 0; leafGroupIndex < target.LeafGroups.Count; ++leafGroupIndex) { Vector <int> intersectionMask; BoundingBoxWide.Intersects(ref nodeChildWide, ref target.LeafGroups.Elements[leafGroupIndex].BoundingBoxes, out intersectionMask); int leafCountInGroup = leafGroupIndex == target.LeafGroups.Count - 1 ? target.LastLeavesCount : Vector <int> .Count; for (int leafIndexInGroup = 0; leafIndexInGroup < leafCountInGroup; ++leafIndexInGroup) { if (intersectionMask[leafIndexInGroup] < 0) { var leafIndex = target.LeafGroups[leafGroupIndex].Leaves[leafIndexInGroup]; if (leafIndex < nodeLeafIndex) //The other leaf will also find a collision! { results.Add(new Overlap { A = leafIndex, B = nodeLeafIndex }); } } } } } } } target.LeafGroups.Count = 0; //Don't bother forcing a clear on these. TODO: buffer safety check disable target.LeafGroups.Dispose(); } targets.Dispose(); fallbackResults.Dispose(); //Console.WriteLine("Streaming Query based results:"); //for (int i = 0; i < results.Count; ++i) //{ // Console.WriteLine($"{results[i].A}, {results[i].B}"); //} }
static FileQueue() { bufferSize = FileOperations.BufferSize; bufferPool = new BufferPool("File Buffers", 64, bufferSize); }
internal void ConsumeServices(IServiceProvider services) { this.ServiceProvider = services; var connectionLostHandlers = services.GetServices <ConnectionToClusterLostHandler>(); foreach (var handler in connectionLostHandlers) { this.ClusterConnectionLost += handler; } var clientInvokeCallbacks = services.GetServices <ClientInvokeCallback>(); foreach (var handler in clientInvokeCallbacks) { this.ClientInvokeCallback += handler; } this.InternalGrainFactory = this.ServiceProvider.GetRequiredService <IInternalGrainFactory>(); this.ClientStatistics = this.ServiceProvider.GetRequiredService <ClientStatisticsManager>(); this.SerializationManager = this.ServiceProvider.GetRequiredService <SerializationManager>(); this.messageFactory = this.ServiceProvider.GetService <MessageFactory>(); this.config = services.GetRequiredService <ClientConfiguration>(); this.GrainReferenceRuntime = this.ServiceProvider.GetRequiredService <IGrainReferenceRuntime>(); if (!LogManager.IsInitialized) { LogManager.Initialize(config); } StatisticsCollector.Initialize(config); this.assemblyProcessor = this.ServiceProvider.GetRequiredService <AssemblyProcessor>(); this.assemblyProcessor.Initialize(); logger = LogManager.GetLogger("OutsideRuntimeClient", LoggerType.Runtime); this.AppLogger = LogManager.GetLogger("Application", LoggerType.Application); BufferPool.InitGlobalBufferPool(config); try { LoadAdditionalAssemblies(); if (!UnobservedExceptionsHandlerClass.TrySetUnobservedExceptionHandler(UnhandledException)) { logger.Warn(ErrorCode.Runtime_Error_100153, "Unable to set unobserved exception handler because it was already set."); } AppDomain.CurrentDomain.DomainUnload += CurrentDomain_DomainUnload; clientProviderRuntime = this.ServiceProvider.GetRequiredService <ClientProviderRuntime>(); statisticsProviderManager = new StatisticsProviderManager("Statistics", clientProviderRuntime); var statsProviderName = statisticsProviderManager.LoadProvider(config.ProviderConfigurations) .WaitForResultWithThrow(initTimeout); if (statsProviderName != null) { config.StatisticsProviderName = statsProviderName; } responseTimeout = Debugger.IsAttached ? Constants.DEFAULT_RESPONSE_TIMEOUT : config.ResponseTimeout; this.localAddress = ClusterConfiguration.GetLocalIPAddress(config.PreferredFamily, config.NetInterface); // Client init / sign-on message logger.Info(ErrorCode.ClientInitializing, string.Format( "{0} Initializing OutsideRuntimeClient on {1} at {2} Client Id = {3} {0}", BARS, config.DNSHostName, localAddress, handshakeClientId)); string startMsg = string.Format("{0} Starting OutsideRuntimeClient with runtime Version='{1}' in AppDomain={2}", BARS, RuntimeVersion.Current, PrintAppDomainDetails()); startMsg = string.Format("{0} Config= " + Environment.NewLine + " {1}", startMsg, config); logger.Info(ErrorCode.ClientStarting, startMsg); if (TestOnlyThrowExceptionDuringInit) { throw new InvalidOperationException("TestOnlyThrowExceptionDuringInit"); } this.gatewayListProvider = this.ServiceProvider.GetRequiredService <IGatewayListProvider>(); if (StatisticsCollector.CollectThreadTimeTrackingStats) { incomingMessagesThreadTimeTracking = new ThreadTrackingStatistic("ClientReceiver"); } } catch (Exception exc) { if (logger != null) { logger.Error(ErrorCode.Runtime_Error_100319, "OutsideRuntimeClient constructor failed.", exc); } ConstructorReset(); throw; } }
public OutsideRuntimeClient(ClientConfiguration cfg, bool secondary = false) { this.typeCache = new TypeMetadataCache(); this.assemblyProcessor = new AssemblyProcessor(this.typeCache); this.grainFactory = new GrainFactory(this, this.typeCache); if (cfg == null) { Console.WriteLine("An attempt to create an OutsideRuntimeClient with null ClientConfiguration object."); throw new ArgumentException("OutsideRuntimeClient was attempted to be created with null ClientConfiguration object.", "cfg"); } this.config = cfg; if (!LogManager.IsInitialized) { LogManager.Initialize(config); } StatisticsCollector.Initialize(config); SerializationManager.Initialize(cfg.SerializationProviders, cfg.FallbackSerializationProvider); this.assemblyProcessor.Initialize(); logger = LogManager.GetLogger("OutsideRuntimeClient", LoggerType.Runtime); appLogger = LogManager.GetLogger("Application", LoggerType.Application); BufferPool.InitGlobalBufferPool(config); this.handshakeClientId = GrainId.NewClientId(); tryResendMessage = TryResendMessage; unregisterCallback = msg => UnRegisterCallback(msg.Id); try { LoadAdditionalAssemblies(); callbacks = new ConcurrentDictionary <CorrelationId, CallbackData>(); localObjects = new ConcurrentDictionary <GuidId, LocalObjectData>(); if (!secondary) { UnobservedExceptionsHandlerClass.SetUnobservedExceptionHandler(UnhandledException); } AppDomain.CurrentDomain.DomainUnload += CurrentDomain_DomainUnload; // Ensure SerializationManager static constructor is called before AssemblyLoad event is invoked SerializationManager.GetDeserializer(typeof(String)); clientProviderRuntime = new ClientProviderRuntime(grainFactory, null); statisticsProviderManager = new StatisticsProviderManager("Statistics", clientProviderRuntime); var statsProviderName = statisticsProviderManager.LoadProvider(config.ProviderConfigurations) .WaitForResultWithThrow(initTimeout); if (statsProviderName != null) { config.StatisticsProviderName = statsProviderName; } responseTimeout = Debugger.IsAttached ? Constants.DEFAULT_RESPONSE_TIMEOUT : config.ResponseTimeout; var localAddress = ClusterConfiguration.GetLocalIPAddress(config.PreferredFamily, config.NetInterface); // Client init / sign-on message logger.Info(ErrorCode.ClientInitializing, string.Format( "{0} Initializing OutsideRuntimeClient on {1} at {2} Client Id = {3} {0}", BARS, config.DNSHostName, localAddress, handshakeClientId)); string startMsg = string.Format("{0} Starting OutsideRuntimeClient with runtime Version='{1}' in AppDomain={2}", BARS, RuntimeVersion.Current, PrintAppDomainDetails()); startMsg = string.Format("{0} Config= " + Environment.NewLine + " {1}", startMsg, config); logger.Info(ErrorCode.ClientStarting, startMsg); if (TestOnlyThrowExceptionDuringInit) { throw new InvalidOperationException("TestOnlyThrowExceptionDuringInit"); } config.CheckGatewayProviderSettings(); var generation = -SiloAddress.AllocateNewGeneration(); // Client generations are negative var gatewayListProvider = GatewayProviderFactory.CreateGatewayListProvider(config) .WithTimeout(initTimeout).Result; transport = new ProxiedMessageCenter(config, localAddress, generation, handshakeClientId, gatewayListProvider); if (StatisticsCollector.CollectThreadTimeTrackingStats) { incomingMessagesThreadTimeTracking = new ThreadTrackingStatistic("ClientReceiver"); } } catch (Exception exc) { if (logger != null) { logger.Error(ErrorCode.Runtime_Error_100319, "OutsideRuntimeClient constructor failed.", exc); } ConstructorReset(); throw; } }
public ReverseProxy(Action <ptr <http.Request> > Director = default, http.RoundTripper Transport = default, time.Duration FlushInterval = default, ref ptr <log.Logger> ErrorLog = default, BufferPool BufferPool = default, Func <ptr <http.Response>, error> ModifyResponse = default, Action <http.ResponseWriter, ptr <http.Request>, error> ErrorHandler = default) { this.Director = Director; this.Transport = Transport; this.FlushInterval = FlushInterval; this.ErrorLog = ErrorLog; this.BufferPool = BufferPool; this.ModifyResponse = ModifyResponse; this.ErrorHandler = ErrorHandler; }
public void a_smaller_length_checks_buffers_back_in_when_not_allowed() { BufferManager manager = new BufferManager(10, 1000, 1); BufferPool pool = new BufferPool(5, manager); pool.SetLength(1, false); Assert.AreEqual(5, manager.AvailableBuffers); }
private void SendThreadFunc() { try { using (WriteOnlyBufferedStream bufferedStream = new WriteOnlyBufferedStream(this.Stream, 16 * 1024)) { while (!closed && !closeSent) { //if (HTTPManager.Logger.Level <= Logger.Loglevels.All) // HTTPManager.Logger.Information("WebSocketResponse", "SendThread - Waiting..."); newFrameSignal.WaitOne(); try { //if (HTTPManager.Logger.Level <= Logger.Loglevels.All) // HTTPManager.Logger.Information("WebSocketResponse", "SendThread - Wait is over, about " + this.unsentFrames.Count.ToString() + " new frames!"); WebSocketFrame frame; while (this.unsentFrames.TryDequeue(out frame)) { if (!closeSent) { using (var rawData = frame.Get()) bufferedStream.Write(rawData.Data, 0, rawData.Length); BufferPool.Release(frame.Data); if (frame.Type == WebSocketFrameTypes.ConnectionClose) { closeSent = true; } } Interlocked.Add(ref this._bufferedAmount, -frame.DataLength); } bufferedStream.Flush(); } catch (Exception ex) { if (HTTPUpdateDelegator.IsCreated) { this.baseRequest.Exception = ex; this.baseRequest.State = HTTPRequestStates.Error; } else { this.baseRequest.State = HTTPRequestStates.Aborted; } closed = true; } } HTTPManager.Logger.Information("WebSocketResponse", string.Format("Ending Send thread. Closed: {0}, closeSent: {1}", closed, closeSent)); } } finally { Interlocked.Exchange(ref sendThreadCreated, 0); HTTPManager.Logger.Information("WebSocketResponse", "SendThread - Closed!"); if (Interlocked.Increment(ref this.closedThreads) == 2) { ProtocolEventHelper.EnqueueProtocolEvent(new ProtocolEventInfo(this)); if (newFrameSignal != null) { (newFrameSignal as IDisposable).Dispose(); } newFrameSignal = null; } } }
public void an_index_under_zero_throws_an_argument_exception() { BufferPool pool = new BufferPool(12, BufferManager); Assert.Throws<ArgumentException>(() => pool[-1] = 4); }
void DecreaseQuota(ref BufferPool bufferPool) { ChangeQuota(ref bufferPool, -1); }
public void Reset() { _messageBuffer = null; _headerBytes = 0; _packageLength = 0; }
/// <summary> /// This is called when client is aware of proxy /// So for HTTPS requests client would send CONNECT header to negotiate a secure tcp tunnel via proxy /// </summary> /// <param name="endPoint"></param> /// <param name="tcpClient"></param> /// <returns></returns> private async Task HandleClient(ExplicitProxyEndPoint endPoint, TcpClient tcpClient) { var clientStream = new CustomBufferedStream(tcpClient.GetStream(), BufferSize); var clientStreamReader = new CustomBinaryReader(clientStream, BufferSize); var clientStreamWriter = new HttpResponseWriter(clientStream, BufferSize); try { string connectHostname = null; ConnectRequest connectRequest = null; //Client wants to create a secure tcp tunnel (probably its a HTTPS or Websocket request) if (await IsConnectMethod(clientStream) == 1) { //read the first line HTTP command string httpCmd = await clientStreamReader.ReadLineAsync(); if (string.IsNullOrEmpty(httpCmd)) { return; } Request.ParseRequestLine(httpCmd, out string _, out string httpUrl, out var version); var httpRemoteUri = new Uri("http://" + httpUrl); connectHostname = httpRemoteUri.Host; //filter out excluded host names bool excluded = false; if (endPoint.ExcludedHttpsHostNameRegex != null) { excluded = endPoint.ExcludedHttpsHostNameRegexList.Any(x => x.IsMatch(connectHostname)); } if (endPoint.IncludedHttpsHostNameRegex != null) { excluded = !endPoint.IncludedHttpsHostNameRegexList.Any(x => x.IsMatch(connectHostname)); } connectRequest = new ConnectRequest { RequestUri = httpRemoteUri, OriginalUrl = httpUrl, HttpVersion = version, }; await HeaderParser.ReadHeaders(clientStreamReader, connectRequest.Headers); var connectArgs = new TunnelConnectSessionEventArgs(BufferSize, endPoint, connectRequest, ExceptionFunc); connectArgs.ProxyClient.TcpClient = tcpClient; connectArgs.ProxyClient.ClientStream = clientStream; if (TunnelConnectRequest != null) { await TunnelConnectRequest.InvokeAsync(this, connectArgs, ExceptionFunc); } if (await CheckAuthorization(clientStreamWriter, connectArgs) == false) { if (TunnelConnectResponse != null) { await TunnelConnectResponse.InvokeAsync(this, connectArgs, ExceptionFunc); } return; } //write back successfull CONNECT response var response = ConnectResponse.CreateSuccessfullConnectResponse(version); response.Headers.FixProxyHeaders(); connectArgs.WebSession.Response = response; await clientStreamWriter.WriteResponseAsync(response); var clientHelloInfo = await SslTools.PeekClientHello(clientStream); bool isClientHello = clientHelloInfo != null; if (isClientHello) { connectRequest.ClientHelloInfo = clientHelloInfo; } if (TunnelConnectResponse != null) { connectArgs.IsHttpsConnect = isClientHello; await TunnelConnectResponse.InvokeAsync(this, connectArgs, ExceptionFunc); } if (!excluded && isClientHello) { connectRequest.RequestUri = new Uri("https://" + httpUrl); SslStream sslStream = null; try { sslStream = new SslStream(clientStream); string certName = HttpHelper.GetWildCardDomainName(connectHostname); var certificate = endPoint.GenericCertificate ?? CertificateManager.CreateCertificate(certName, false); //Successfully managed to authenticate the client using the fake certificate await sslStream.AuthenticateAsServerAsync(certificate, false, SupportedSslProtocols, false); //HTTPS server created - we can now decrypt the client's traffic clientStream = new CustomBufferedStream(sslStream, BufferSize); clientStreamReader.Dispose(); clientStreamReader = new CustomBinaryReader(clientStream, BufferSize); clientStreamWriter = new HttpResponseWriter(clientStream, BufferSize); } catch { sslStream?.Dispose(); return; } if (await IsConnectMethod(clientStream) == -1) { // It can be for example some Google (Cloude Messaging for Chrome) magic excluded = true; } } //Hostname is excluded or it is not an HTTPS connect if (excluded || !isClientHello) { //create new connection using (var connection = await GetServerConnection(connectArgs, true)) { if (isClientHello) { int available = clientStream.Available; if (available > 0) { //send the buffered data var data = BufferPool.GetBuffer(BufferSize); try { // clientStream.Available sbould be at most BufferSize because it is using the same buffer size await clientStream.ReadAsync(data, 0, available); await connection.StreamWriter.WriteAsync(data, 0, available, true); } finally { BufferPool.ReturnBuffer(data); } } var serverHelloInfo = await SslTools.PeekServerHello(connection.Stream); ((ConnectResponse)connectArgs.WebSession.Response).ServerHelloInfo = serverHelloInfo; } await TcpHelper.SendRaw(clientStream, connection.Stream, BufferSize, (buffer, offset, count) => { connectArgs.OnDataSent(buffer, offset, count); }, (buffer, offset, count) => { connectArgs.OnDataReceived(buffer, offset, count); }, ExceptionFunc); } return; } } //Now create the request await HandleHttpSessionRequest(tcpClient, clientStream, clientStreamReader, clientStreamWriter, connectHostname, endPoint, connectRequest); } catch (ProxyHttpException e) { ExceptionFunc(e); } catch (IOException e) { ExceptionFunc(new Exception("Connection was aborted", e)); } catch (SocketException e) { ExceptionFunc(new Exception("Could not connect", e)); } catch (Exception e) { ExceptionFunc(new Exception("Error occured in whilst handling the client", e)); } finally { clientStreamReader.Dispose(); clientStream.Dispose(); } }
public void a_write_past_end_will_check_out_a_buffer_from_the_buffer_pool() { BufferPool pool = new BufferPool(1, BufferManager); int initial = BufferManager.AvailableBuffers; pool[pool.Capacity + 14] = 5; Assert.AreEqual(initial - 1, BufferManager.AvailableBuffers); }
public void can_write_given_a_self_offset() { BufferPool pool = new BufferPool(1, BufferManager); byte[] data = { 1, 2, 3, 4, 5 }; pool.Write(4, data, 0, 5); //start at position 4 for (byte i = 4; i < 9; i++) { Assert.AreEqual(i - 3, pool[i]); } }
public void can_write_given_a_source_offset() { BufferPool pool = new BufferPool(1, BufferManager); byte[] data = { 1, 2, 3, 4, 5 }; pool.Write(0, data, 3, 2); Assert.AreEqual(pool[0], 4); Assert.AreEqual(pool[1], 5); }
public void a_negative_length_throws_an_argumentexception() { BufferPool pool = new BufferPool(1, BufferManager); pool.SetLength(-1, false); }
public void data_is_written_to_the_internal_buffer() { BufferPool pool = new BufferPool(1, BufferManager); byte[] data = { 1, 2, 3, 4, 5 }; pool.Append(data); for (byte i = 0; i < 5; i++) { Assert.AreEqual(i + 1, pool[i]); } }
public MultithreadedIntertreeTest(BufferPool pool) { Pool = pool; }
void ChangeQuota(ref BufferPool bufferPool, int delta) { BufferPool oldBufferPool = bufferPool; int newLimit = oldBufferPool.Limit + delta; BufferPool newBufferPool = new BufferPool(oldBufferPool.BufferSize, newLimit); for (int i = 0; i < newLimit; i++) { byte[] buffer = oldBufferPool.Take(); if (buffer == null) { break; } newBufferPool.Return(buffer); newBufferPool.IncrementCount(); } this.remainingMemory -= oldBufferPool.BufferSize * delta; bufferPool = newBufferPool; }
public void pool_can_expand_capacity() { BufferPool pool = new BufferPool(1, BufferManager); int initialCapacity = pool.Capacity; byte[] data = new byte[initialCapacity + 25]; pool.Append(data); Assert.AreEqual(initialCapacity * 2, pool.Capacity); }
void IncreaseQuota(ref BufferPool bufferPool) { ChangeQuota(ref bufferPool, 1); }
public void ThreadStaticBufferVsSharedPool() { for (int r = 0; r < 10; r++) { const int count = 1000000; var sw = new Stopwatch(); sw.Restart(); var sum = 0L; for (var i = 0; i < count; i++) { using (var wrapper = BufferPool.UseTempBuffer(BufferPool.StaticBufferSize)) { wrapper.Buffer.Span[0] = 123; sum += wrapper.Buffer.Span[0] + wrapper.Buffer.Span[1]; } } Assert.IsTrue(sum > 0); sw.Stop(); Console.WriteLine($"Threadlocal {sw.ElapsedMilliseconds}"); sw.Restart(); sum = 0L; for (var i = 0; i < count; i++) { using (var wrapper = BufferPool.UseTempBuffer(BufferPool.StaticBufferSize + 1)) { wrapper.Buffer.Span[0] = 123; sum += wrapper.Buffer.Span[0] + wrapper.Buffer.Span[1]; } } Assert.IsTrue(sum > 0); sw.Stop(); Console.WriteLine($"GetBuffer via pool {sw.ElapsedMilliseconds}"); sw.Restart(); sum = 0L; for (var i = 0; i < count; i++) { var buffer = BufferPool <byte> .Rent(BufferPool.StaticBufferSize); buffer[0] = 123; sum += buffer[0] + buffer[1]; BufferPool <byte> .Return(buffer, true); } Assert.IsTrue(sum > 0); sw.Stop(); Console.WriteLine($"Direct ArrayPool with StaticBufferSize {sw.ElapsedMilliseconds}"); sw.Restart(); sum = 0L; for (var i = 0; i < count; i++) { var buffer = BufferPool <byte> .Rent(BufferPool.StaticBufferSize + 1); buffer[0] = 123; sum += buffer[0] + buffer[1]; BufferPool <byte> .Return(buffer, true); } Assert.IsTrue(sum > 0); sw.Stop(); Console.WriteLine($"Direct ArrayPool with StaticBufferSize + 1 {sw.ElapsedMilliseconds}"); sw.Restart(); sum = 0L; for (var i = 0; i < count; i++) { var buffer = new byte[BufferPool.StaticBufferSize]; buffer[0] = 123; sum += buffer[0] + buffer[1]; } Assert.IsTrue(sum > 0); sw.Stop(); Console.WriteLine($"GC StaticBufferSize {sw.ElapsedMilliseconds}"); sw.Restart(); sum = 0L; for (var i = 0; i < count; i++) { var buffer = new byte[BufferPool.StaticBufferSize + 1]; buffer[0] = 123; sum += buffer[0] + buffer[1]; } Assert.IsTrue(sum > 0); sw.Stop(); Console.WriteLine($"GC StaticBufferSize + 1 {sw.ElapsedMilliseconds}"); Console.WriteLine("---------------------"); } }