/// <summary> /// 加载操作数据 /// </summary> /// <param name="loadData">加载数据</param> /// <returns>是否加载成功</returns> internal bool Load(ref LoadData loadData) { OperationParameter.NodeParser parser = new OperationParameter.NodeParser(this, ref loadData); do { if (parser.Load(ref loadData)) { switch (parser.OperationType) { case OperationParameter.OperationType.LoadArraySize: int size = parser.ReadInt(); if (parser.IsEnd) { Array = new DataStructureItem[size]; isRebuild = true; break; } return(false); case OperationParameter.OperationType.GetOrCreateDataStructure: if (loadDataStructure(loadData.Buffer)) { break; } return(false); case OperationParameter.OperationType.RemoveDataStructure: if (loadRemoveDataStructure(loadData.Buffer)) { break; } return(false); case OperationParameter.OperationType.LoadIndexIdentity: if (loadIndexIdentity(ref parser)) { break; } return(false); default: ServerDataStructure dataStructure = parser.Get(Array); if (dataStructure != null) { dataStructure.Node.Operation(ref parser); } break; } } else { return(false); } }while (loadData.IsNext); return(true); }
/// <summary> /// 操作数据 /// </summary> /// <param name="buffer">数据缓冲区</param> /// <param name="onOperation"></param> internal void Operation(Buffer buffer, Func <AutoCSer.Net.TcpServer.ReturnValue <ReturnParameter>, bool> onOperation) { int isReturn = 0; try { if (CanWrite) { fixed(byte *dataFixed = buffer.Array.Array) { OperationParameter.NodeParser parser = new OperationParameter.NodeParser(this, buffer, dataFixed); ServerDataStructure dataStructure = parser.Get(Array); if (dataStructure != null) { parser.OnReturn = onOperation; try { dataStructure.Node.Operation(ref parser); } finally { if (parser.OnReturn == null) { isReturn = 1; } } if (parser.IsOperation) { this.onOperation(buffer); } else { buffer.FreeReference(); } return; } } buffer.FreeReference(); isReturn = 1; onOperation(new ReturnParameter(ReturnType.DataStructureIdentityError)); return; } buffer.FreeReference(); } finally { if (isReturn == 0) { onOperation(new ReturnParameter(ReturnType.CanNotWrite)); } } }
/// <summary> /// 创建短路径 /// </summary> /// <param name="node"></param> /// <param name="parser"></param> internal void CreateShortPath(Cache.Value.Node node, ref OperationParameter.NodeParser parser) { byte[] packet = parser.CreateReadPacket(OperationParameter.Serializer.HeaderSize); ulong identity = shortPaths[shortPathIndex].Set(node, packet); parser.ReturnParameter.ReturnParameterSetBinary(new ShortPathIdentity { Index = shortPathIndex, Identity = identity, Ticks = startTicks, PacketSize = packet.Length }); if (++shortPathIndex == shortPaths.Length) { shortPathIndex = 0; } }
/// <summary> /// 查询数据 /// </summary> /// <param name="queryData">查询数据</param> /// <returns>返回参数</returns> internal ValueData.Data Query(ref SubArray <byte> queryData) { queryBuffer.Set(ref queryData); fixed(byte *dataFixed = queryData.Array) { OperationParameter.NodeParser parser = new OperationParameter.NodeParser(this, queryBuffer, dataFixed); ServerDataStructure dataStructure = parser.Get(Array); if (dataStructure != null) { dataStructure.Node.Query(ref parser); return(parser.ReturnParameter); } } return(new ValueData.Data(ReturnType.DataStructureIdentityError)); }
/// <summary> /// 操作数据 /// </summary> /// <param name="parameter">短路径操作参数</param> /// <returns>返回参数</returns> internal ValueData.Data Operation(ref OperationParameter.ShortPathOperationNode parameter) { if (CanWrite) { if (parameter.Buffer != null) { if (parameter.Identity.Ticks == startTicks) { byte[] packet; Cache.Value.Node node = shortPaths[parameter.Identity.Index].Get(parameter.Identity.Identity, out packet); if (packet.Length == parameter.Identity.PacketSize) { if (node.IsNode) { byte[] bufferData = parameter.Buffer.Array.Array; System.Buffer.BlockCopy(packet, 0, bufferData, parameter.Buffer.Array.Start + OperationParameter.Serializer.HeaderSize, parameter.Identity.PacketSize); fixed(byte *bufferFixed = bufferData) { OperationParameter.NodeParser parser = new OperationParameter.NodeParser(this, parameter.Buffer, bufferFixed); parser.Read += parameter.Identity.PacketSize; node.Operation(ref parser); if (parser.IsOperation) { onOperation(parameter.Buffer); } else { parameter.Buffer.FreeReference(); } return(parser.ReturnParameter); } } return(new ValueData.Data(ReturnType.NotFoundShortPathNode)); } } return(new ValueData.Data(ReturnType.NotFoundShortPath)); } return(new ValueData.Data(ReturnType.ServerDeSerializeError)); } return(new ValueData.Data(ReturnType.CanNotWrite)); }
/// <summary> /// 加载数据结构索引标识 /// </summary> /// <param name="parser"></param> /// <returns></returns> private bool loadIndexIdentity(ref OperationParameter.NodeParser parser) { if (parser.ReadInt() == Array.Length) { FreeIndexs.PrepLength(Array.Length); ServerDataStructure dataStructure; for (int index = Array.Length; index != 0;) { if (!Array[--index].Load((ulong)parser.ReadLong(), out dataStructure)) { return(false); } if (dataStructure == null) { FreeIndexs.UnsafeAdd(index); } } isRebuild = false; return(true); } return(false); }
/// <summary> /// 服务端数据结构定义信息 /// </summary> /// <param name="cache">缓存管理</param> /// <param name="buffer">数据缓冲区</param> /// <param name="dataStructureBuffer">服务端数据结构定义数据</param> internal unsafe ServerDataStructure(CacheManager cache, Buffer buffer, ref DataStructureBuffer dataStructureBuffer) : base(dataStructureBuffer.CacheName, dataStructureBuffer.Identity, dataStructureBuffer.Data) { ReturnType = ReturnType.ServerDataStructureCreateError; fixed(byte *dataFixed = NodeData.Array) { byte *start = dataFixed + NodeData.Start; DataStructureParser nodeParser = new DataStructureParser(start, start + NodeData.Length); Type nodeType = nodeParser.Parse(); if (nodeType != null) { Cache.NodeInfo nodeInfo = (Cache.NodeInfo)nodeType.GetField(Cache.Node.NodeInfoFieldName, BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy).GetValue(null); if (nodeInfo != null) { if (cache.IsFile || !nodeInfo.IsCacheFile || cache.SlaveServer != null) { OperationParameter.NodeParser nodeParameter = new OperationParameter.NodeParser(cache, buffer, dataFixed); nodeParameter.Read += IndexIdentity.SerializeSize; Node = nodeInfo.CallConstructor(ref nodeParameter); NodeData.Length = (int)(nodeParser.Read - start); byte[] data = NodeData.GetArray(); NodeData.Set(data, 0, data.Length); } else { ReturnType = ReturnType.CacheNodeNeedFile; } } else { ReturnType = ReturnType.NotFoundCacheNodeInfo; } } else { ReturnType = ReturnType.CacheNodeParseError; } } }
/// <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="parameter">短路径操作参数</param> /// <param name="onOperation"></param> internal void Operation(ref OperationParameter.ShortPathOperationNode parameter, Func <AutoCSer.Net.TcpServer.ReturnValue <ReturnParameter>, bool> onOperation) { ReturnType returnType = ReturnType.CanNotWrite; try { if (CanWrite) { if (parameter.Buffer != null) { returnType = ReturnType.NotFoundShortPath; if (parameter.Identity.Ticks == startTicks) { byte[] packet; Cache.Value.Node node = shortPaths[parameter.Identity.Index].Get(parameter.Identity.Identity, out packet); if (packet.Length == parameter.Identity.PacketSize) { if (node.IsNode) { returnType = ReturnType.Unknown; byte[] bufferData = parameter.Buffer.Array.Array; System.Buffer.BlockCopy(packet, 0, bufferData, parameter.Buffer.Array.Start + OperationParameter.Serializer.HeaderSize, parameter.Identity.PacketSize); fixed(byte *bufferFixed = bufferData) { OperationParameter.NodeParser parser = new OperationParameter.NodeParser(this, parameter.Buffer, bufferFixed); parser.Read += parameter.Identity.PacketSize; parser.OnReturn = onOperation; try { node.Operation(ref parser); } finally { if (parser.OnReturn == null) { returnType = ReturnType.Success; } } if (parser.IsOperation) { this.onOperation(parameter.Buffer); } else { parameter.Buffer.FreeReference(); } return; } } else { returnType = ReturnType.NotFoundShortPathNode; } } } } else { returnType = ReturnType.ServerDeSerializeError; } } parameter.Buffer.FreeReference(); } finally { if (returnType != ReturnType.Success) { onOperation(new ReturnParameter(returnType)); } } }
/// <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)); } } }