/// <summary> /// 数据缓冲区 /// </summary> /// <param name="bufferCount">数据缓冲区计数</param> /// <param name="index">起始位置</param> /// <param name="count">字节数量</param> internal Buffer(BufferCount bufferCount, int index, int count) { referenceCount = 1; this.BufferCount = bufferCount; Array.Set(bufferCount.Buffer.Buffer, index, count); }
/// <summary> /// 查询数据 /// </summary> /// <param name="queryData">查询数据</param> /// <param name="onQuery"></param> /// <param name="isDeSerializeStream">是否反序列化网络流,否则需要 Copy 数据</param> internal void ShortPathQuery(ref SubArray <byte> queryData, AutoCSer.Net.TcpServer.ServerCallback <ReturnParameter> onQuery, bool isDeSerializeStream) { byte[] data = queryData.Array; ReturnType returnType = ReturnType.ServerDeSerializeError; try { fixed(byte *dataFixed = queryData.GetFixedBuffer()) { byte * start = dataFixed + queryData.Start; ShortPathIdentity identity = new ShortPathIdentity(start + OperationParameter.Serializer.HeaderSize); returnType = ReturnType.NotFoundShortPath; if (identity.Ticks == startTicks) { byte[] packet; Cache.Value.Node node = shortPaths[identity.Index].Get(identity.Identity, out packet); if (packet.Length == identity.PacketSize) { if (node.IsNode) { returnType = ReturnType.Unknown; if ((*(int *)start = queryData.Length + identity.PacketSize - ShortPathIdentity.SerializeSize) <= queryData.Length) { System.Buffer.BlockCopy(packet, 0, data, queryData.Start + OperationParameter.Serializer.HeaderSize, identity.PacketSize); System.Buffer.BlockCopy(data, queryData.Start + (OperationParameter.Serializer.HeaderSize + ShortPathIdentity.SerializeSize), data, queryData.Start + (OperationParameter.Serializer.HeaderSize + identity.PacketSize), queryData.Length - (OperationParameter.Serializer.HeaderSize + ShortPathIdentity.SerializeSize)); queryData.Length = *(int *)start; queryBuffer.Set(ref queryData); OperationParameter.NodeParser parser = new OperationParameter.NodeParser(this, queryBuffer, dataFixed); parser.Read += identity.PacketSize; parser.SetOnReturn(onQuery, isDeSerializeStream); onQuery = null; try { node.Query(ref parser); } finally { parser.CallOnReturn(); } } else { Buffer buffer = BufferCount.GetBuffer(*(int *)start); try { SubArray <byte> bufferSubArray = buffer.Array; byte[] bufferData = bufferSubArray.Array; fixed(byte *bufferFixed = bufferData) { *(ulong *)(bufferFixed + bufferSubArray.Start) = *(ulong *)start; System.Buffer.BlockCopy(packet, 0, bufferData, bufferSubArray.Start + OperationParameter.Serializer.HeaderSize, identity.PacketSize); System.Buffer.BlockCopy(data, queryData.Start + (OperationParameter.Serializer.HeaderSize + ShortPathIdentity.SerializeSize), bufferData, bufferSubArray.Start + (OperationParameter.Serializer.HeaderSize + identity.PacketSize), queryData.Length - (OperationParameter.Serializer.HeaderSize + ShortPathIdentity.SerializeSize)); OperationParameter.NodeParser parser = new OperationParameter.NodeParser(this, buffer, bufferFixed); parser.Read += identity.PacketSize; parser.SetOnReturn(onQuery, isDeSerializeStream); onQuery = null; try { node.Query(ref parser); } finally { parser.CallOnReturn(); } } } finally { buffer.Dispose(); } } } else { returnType = ReturnType.NotFoundShortPathNode; } } } } } finally { if (onQuery != null) { onQuery.Callback(new ReturnParameter(returnType)); } } }
/// <summary> /// 查询数据 /// </summary> /// <param name="queryData">查询数据</param> /// <returns>返回参数</returns> internal ValueData.Data ShortPathQuery(ref SubArray <byte> queryData) { byte[] data = queryData.Array; ReturnType returnType = ReturnType.NotFoundShortPath; fixed(byte *dataFixed = queryData.Array) { byte * start = dataFixed + queryData.Start; ShortPathIdentity identity = new ShortPathIdentity(start + OperationParameter.Serializer.HeaderSize); if (identity.Ticks == startTicks) { byte[] packet; Cache.Value.Node node = shortPaths[identity.Index].Get(identity.Identity, out packet); if (packet.Length == identity.PacketSize) { if (node.IsNode) { returnType = ReturnType.Unknown; if ((*(int *)start = queryData.Length + identity.PacketSize - ShortPathIdentity.SerializeSize) <= queryData.Length) { System.Buffer.BlockCopy(packet, 0, data, queryData.Start + OperationParameter.Serializer.HeaderSize, identity.PacketSize); System.Buffer.BlockCopy(data, queryData.Start + (OperationParameter.Serializer.HeaderSize + ShortPathIdentity.SerializeSize), data, queryData.Start + (OperationParameter.Serializer.HeaderSize + identity.PacketSize), queryData.Length - (OperationParameter.Serializer.HeaderSize + ShortPathIdentity.SerializeSize)); queryData.Length = *(int *)start; queryBuffer.Set(ref queryData); OperationParameter.NodeParser parser = new OperationParameter.NodeParser(this, queryBuffer, dataFixed); parser.Read += identity.PacketSize; node.Query(ref parser); return(parser.ReturnParameter); } else { Buffer buffer = BufferCount.GetBuffer(*(int *)start); try { SubArray <byte> bufferSubArray = buffer.Array; byte[] bufferData = bufferSubArray.Array; fixed(byte *bufferFixed = bufferData) { *(ulong *)(bufferFixed + bufferSubArray.Start) = *(ulong *)start; System.Buffer.BlockCopy(packet, 0, bufferData, bufferSubArray.Start + OperationParameter.Serializer.HeaderSize, identity.PacketSize); System.Buffer.BlockCopy(data, queryData.Start + (OperationParameter.Serializer.HeaderSize + ShortPathIdentity.SerializeSize), bufferData, bufferSubArray.Start + (OperationParameter.Serializer.HeaderSize + identity.PacketSize), queryData.Length - (OperationParameter.Serializer.HeaderSize + ShortPathIdentity.SerializeSize)); OperationParameter.NodeParser parser = new OperationParameter.NodeParser(this, buffer, bufferFixed); parser.Read += identity.PacketSize; node.Query(ref parser); return(parser.ReturnParameter); } } finally { buffer.Dispose(); } } } else { returnType = ReturnType.NotFoundShortPathNode; } } } } return(new ValueData.Data(returnType)); }
/// <summary> /// 获取数据缓冲区 /// </summary> /// <param name="size"></param> /// <returns></returns> internal static Buffer GetBuffer(int size) { if (size > (int)BufferSize) { return(new Buffer(size)); } Buffer buffer; while (System.Threading.Interlocked.CompareExchange(ref bufferCountLock, 1, 0) != 0) { AutoCSer.Threading.ThreadYield.Yield(AutoCSer.Threading.ThreadYield.Type.CacheServerGetBuffer); } try { buffer = bufferCount.get(size); } finally { System.Threading.Interlocked.Exchange(ref bufferCountLock, 0); } if (buffer == null) { byte step = 0xff; BufferCount newBufferCount = null, oldBufferCount; Monitor.Enter(newBufferCountLock); oldBufferCount = bufferCount; try { while (System.Threading.Interlocked.CompareExchange(ref bufferCountLock, 1, 0) != 0) { AutoCSer.Threading.ThreadYield.Yield(AutoCSer.Threading.ThreadYield.Type.CacheServerGetBuffer); } step = 0; buffer = oldBufferCount.get(size); System.Threading.Interlocked.Exchange(ref bufferCountLock, 0); step = 0xff; if (buffer == null) { newBufferCount = new BufferCount(); step = 1; buffer = newBufferCount.get(size); if (newBufferCount.Size > oldBufferCount.Size) { step = 0xff; bufferCount = newBufferCount; oldBufferCount.Free(); } } } finally { switch (step) { case 0: System.Threading.Interlocked.Exchange(ref bufferCountLock, 0); break; case 1: newBufferCount.Free(); break; } Monitor.Exit(newBufferCountLock); } } return(buffer); }