internal void CloseFree() { ReceiveBuffer.Free(); ReceiveBigBuffer.TryFree(); if (CheckTimer != null) { CheckTimer.Free(this); ClientCheckTimer.FreeNotNull(CheckTimer); CheckTimer = null; } FreeReceiveDeSerializer(); if (Sender != null) { Sender.Close(); } }
/// <summary> /// 压缩数据 /// </summary> /// <param name="data"></param> /// <returns></returns> public static byte[] Compress(byte[] data) { SubBuffer.PoolBufferFull buffer = default(SubBuffer.PoolBufferFull); try { SubArray <byte> compressData = new SubArray <byte>(); if (DeflateCompressor.Get(data, 0, data.Length, ref buffer, ref compressData, sizeof(int), 0)) { compressData.MoveStart(-sizeof(int)); return(setSize(compressData.GetArray(), data.Length)); } byte[] newData = new byte[data.Length + sizeof(int)]; Buffer.BlockCopy(data, 0, newData, sizeof(int), data.Length); return(setSize(newData, data.Length)); } finally { buffer.TryFree(); } }
/// <summary> /// 加载数据文件 /// </summary> /// <returns></returns> private bool loadFile() { ulong endIdentity = Math.Min(memoryEndIdentity, writerAppendIdentity); SubBuffer.PoolBufferFull compressionBuffer = default(SubBuffer.PoolBufferFull); int dataSize; try { fixed(byte *bufferFixed = buffer) { do { switch (bufferSize) { case 0: break; case 1: *bufferFixed = *(bufferFixed + bufferIndex); break; case 2: SIZE2 : *(ushort *)bufferFixed = *(ushort *)(bufferFixed + bufferIndex); break; case 3: *(bufferFixed + sizeof(ushort)) = *(bufferFixed + (bufferIndex + sizeof(ushort))); goto SIZE2; case 4: SIZE4 : *(uint *)bufferFixed = *(uint *)(bufferFixed + bufferIndex); break; case 5: *(bufferFixed + (sizeof(uint))) = *(bufferFixed + (bufferIndex + sizeof(uint))); goto SIZE4; case 6: SIZE6 : *(ushort *)(bufferFixed + sizeof(uint)) = *(ushort *)(bufferFixed + (bufferIndex + sizeof(uint))); goto SIZE4; case 7: *(bufferFixed + (sizeof(uint) + sizeof(ushort))) = *(bufferFixed + (bufferIndex + (sizeof(uint) + sizeof(ushort)))); goto SIZE6; case 8: SIZE8 : *(ulong *)bufferFixed = *(ulong *)(bufferFixed + bufferIndex); break; case 9: *(bufferFixed + (sizeof(ulong))) = *(bufferFixed + (bufferIndex + sizeof(ulong))); goto SIZE8; case 10: SIZE10 : *(ushort *)(bufferFixed + sizeof(ulong)) = *(ushort *)(bufferFixed + (bufferIndex + sizeof(ulong))); goto SIZE8; case 11: *(bufferFixed + (sizeof(ulong) + sizeof(ushort))) = *(bufferFixed + (bufferIndex + (sizeof(ulong) + sizeof(ushort)))); goto SIZE10; default: goto NEXTDATA; } bufferIndex = 0; READFILE: if (!readFile()) { return(false); } NEXTDATA: int compressionDataSize = *(int *)(bufferFixed + bufferIndex); if (compressionDataSize < 0) { dataSize = *(int *)(bufferFixed + (bufferIndex + sizeof(int))); //dataCount = *(int*)(bufferFixed + (bufferIndex + sizeof(int) * 2)); bufferIndex += FileWriter.PacketHeaderSize + sizeof(int); bufferSize -= FileWriter.PacketHeaderSize + sizeof(int); compressionDataSize = -compressionDataSize; } else { //dataCount = *(int*)(bufferFixed + (bufferIndex + sizeof(int) * 1)); bufferIndex += FileWriter.PacketHeaderSize; bufferSize -= FileWriter.PacketHeaderSize; dataSize = compressionDataSize; } if (bufferSize < compressionDataSize) { if (compressionDataSize <= buffer.Length) { System.Buffer.BlockCopy(buffer, bufferIndex, buffer, 0, bufferSize); if ((bufferSize += dataFileStream.Read(buffer, bufferSize, buffer.Length - bufferSize)) < compressionDataSize) { return(false); } bufferIndex = 0; } else { #region 大数据块解析 if (bigBuffer.Length < compressionDataSize) { bigBuffer = new byte[Math.Max(compressionDataSize, bigBuffer.Length << 1)]; } System.Buffer.BlockCopy(buffer, bufferIndex, bigBuffer, 0, bufferSize); if (dataFileStream.Read(bigBuffer, bufferSize, bufferIndex = compressionDataSize - bufferSize) != bufferIndex) { return(false); } if (compressionDataSize == dataSize) { bufferIndex = 0; fixed(byte *bigBufferFixed = bigBuffer) { do { if (dataFileIdentity == writeIdentity) { bufferIndex += messages[writeMessageIndex].DeSerializeBuffer(bigBufferFixed + bufferIndex, bigBuffer, bufferIndex); nextWriteIndex(); } else { bufferIndex += messages[writeMessageIndex].Data.DeSerializeBuffer(bigBufferFixed + bufferIndex, bigBuffer, bufferIndex); } ++dataFileIdentity; }while (bufferIndex < dataSize); } if (bufferIndex != dataSize) { return(false); } } else { compressionBuffer.StartIndex = dataSize; AutoCSer.IO.Compression.DeflateDeCompressor.Get(bigBuffer, 0, compressionDataSize, ref compressionBuffer); if (!load(ref compressionBuffer, dataSize)) { return(false); } } bufferIndex = bufferSize = 0; if (dataFileIdentity < endIdentity) { goto READFILE; } break; #endregion } } if (compressionDataSize == dataSize) { dataSize += bufferIndex; do { if (dataFileIdentity == writeIdentity) { bufferIndex += messages[writeMessageIndex].DeSerializeBuffer(bufferFixed + bufferIndex, buffer, bufferIndex); nextWriteIndex(); } else { bufferIndex += messages[writeMessageIndex].Data.DeSerializeBuffer(bufferFixed + bufferIndex, buffer, bufferIndex); } ++dataFileIdentity; }while (bufferIndex < dataSize); if (bufferIndex != dataSize) { return(false); } } else { compressionBuffer.StartIndex = dataSize; AutoCSer.IO.Compression.DeflateDeCompressor.Get(buffer, bufferIndex, compressionDataSize, ref compressionBuffer); if (!load(ref compressionBuffer, dataSize)) { return(false); } bufferIndex += compressionDataSize; } bufferSize -= compressionDataSize; }while (dataFileIdentity < endIdentity); if (writeIdentity >= writerAppendIdentity) { dataFileStream.Dispose(); dataFileStream = null; } } } finally { compressionBuffer.TryFree(); } return(true); }
internal void Free() { CopyBuffer.TryFree(); CompressBuffer.TryFree(); }
/// <summary> /// 初始化 /// </summary> internal void Start() { int isDisposed = 1; SubBuffer.PoolBufferFull buffer = default(SubBuffer.PoolBufferFull); try { if (checkStateFile()) { byte[] stateData = new byte[stateBufferSize]; stateFileStream = new FileStream(stateFileName, FileMode.Open, FileAccess.ReadWrite, FileShare.Read, stateBufferSize, FileOptions.None); stateFileStream.Seek(-stateBufferSize, SeekOrigin.End); stateFileStream.Read(stateData, 0, stateBufferSize); fixed(byte *stateDataFixed = stateData) { identity = *(ulong *)stateDataFixed; dataFileLength = *(long *)(stateDataFixed + sizeof(ulong)); } if (((uint)identity & (DataCountPerFile - 1)) == 0) { dataFileLength = 0; } if (dataFileLength == 0) { FileInfo dataFileInfo = new FileInfo(dataFileName); if (dataFileInfo.Exists) { if (dataFileInfo.Length == 0) { dataFileInfo.Delete(); } else { AutoCSer.IO.File.MoveBak(dataFileInfo.FullName); } } dataFileStream = new FileStream(dataFileInfo.FullName, FileMode.CreateNew, FileAccess.Write, FileShare.Read, bufferPool.Size, FileOptions.None); } else { FileInfo dataFileInfo = new FileInfo(dataFileName); if (!dataFileInfo.Exists) { Node.Cache.TcpServer.Log.Add(Log.LogType.Error, "没有找到消息队列数据文件 " + dataFileInfo.FullName); return; } if (dataFileInfo.Length < dataFileLength) { Node.Cache.TcpServer.Log.Add(Log.LogType.Error, "消息队列数据文件 " + dataFileInfo.FullName + " 大小错误 " + dataFileInfo.Length.toString() + " < " + dataFileLength.toString()); return; } dataFileStream = new FileStream(dataFileInfo.FullName, FileMode.Open, FileAccess.Write, FileShare.Read, bufferPool.Size, FileOptions.None); if (dataFileStream.Length > dataFileLength) { dataFileStream.SetLength(dataFileLength); dataFileStream.Flush(true); } dataFileStream.Seek(0, SeekOrigin.End); FileInfo indexFileInfo = new FileInfo(getIndexFileName(identity)); bufferPool.Get(ref buffer); fixed(byte *bufferFixed = buffer.Buffer) { byte *bufferStart = bufferFixed + buffer.StartIndex, end = bufferStart + buffer.Length; ulong baseIdentity = this.baseIdentity; if (indexFileInfo.Exists && indexFileInfo.Length >= sizeof(int) * 2) { #region 初始化数据文件数据包索引信息 int count = (int)(indexFileInfo.Length >> 3), index = 0; long fileIndex = 0; indexs = new LeftArray <PacketIndex>(count); PacketIndex[] indexArray = indexs.Array; using (FileStream indexFileStream = new FileStream(indexFileInfo.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, bufferPool.Size, FileOptions.None)) { do { indexFileStream.Read(buffer.Buffer, buffer.StartIndex, buffer.Length); byte *read = bufferStart; do { indexArray[index].Set(baseIdentity + *(uint *)read, fileIndex += *(int *)(read + sizeof(int))); if (++index == count) { break; } }while ((read += sizeof(int) * 2) != end); }while (index != count); } while (index != 0) { if ((fileIndex = indexArray[--index].FileIndex) == dataFileLength) { if (indexArray[index].Identity == identity) { indexs.Length = index + 1; } break; } if (fileIndex < dataFileLength) { break; } } #endregion } if (indexs.Length == 0) { #region 重建数据文件数据包索引信息 if (indexs.Array == null) { indexs = new LeftArray <PacketIndex>(1 << 10); } indexs.Array[0].Set(baseIdentity); indexs.Length = 1; int bufferIndex = 0, readBufferSize = Math.Min(buffer.Length, createIndexBufferSize), bufferEndIndex, dataSize; long nextFileSize = dataFileLength, fileIndex = 0; using (FileStream fileStream = new FileStream(dataFileInfo.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, readBufferSize, FileOptions.None)) { readBufferSize -= sizeof(int); do { bufferEndIndex = fileStream.Read(buffer.Buffer, buffer.StartIndex + bufferIndex, readBufferSize - bufferIndex); nextFileSize -= bufferEndIndex; bufferEndIndex += bufferIndex - sizeof(int) * 3; bufferIndex = 0; do { byte *read = bufferStart + bufferIndex; dataSize = *(int *)read; if (dataSize < 0) { baseIdentity += *(uint *)(read + sizeof(int) * 2); bufferIndex += -dataSize + PacketHeaderSize + sizeof(int); } else { baseIdentity += *(uint *)(read + sizeof(int)); bufferIndex += dataSize + PacketHeaderSize; } indexs.PrepLength(1); indexs.Array[indexs.Length].Set(baseIdentity, fileIndex + bufferIndex); ++indexs.Length; }while (bufferIndex <= bufferEndIndex); fileIndex += bufferIndex; switch (dataSize = bufferIndex - bufferEndIndex) { case 1: case 2: case 3: *(ulong *)bufferStart = *(ulong *)(bufferStart + bufferIndex); *(uint *)(bufferStart + sizeof(ulong)) = *(uint *)(bufferStart + (bufferIndex + sizeof(ulong))); bufferIndex = sizeof(int) * 3 - dataSize; break; case 4: case 5: case 6: case 7: *(ulong *)bufferStart = *(ulong *)(bufferStart + bufferIndex); bufferIndex = sizeof(int) * 3 - dataSize; break; case 8: case 9: case 10: case 11: *(uint *)bufferStart = *(uint *)(bufferStart + bufferIndex); bufferIndex = sizeof(int) * 3 - dataSize; break; case 12: bufferIndex = 0; break; default: fileStream.Seek(dataSize -= sizeof(int) * 3, SeekOrigin.Current); nextFileSize -= dataSize; bufferIndex = 0; break; } }while (nextFileSize > 0); } #endregion } } } } else { stateFileStream = new FileStream(stateFileName, FileMode.CreateNew, FileAccess.Write, FileShare.Read, stateBufferSize, FileOptions.None); FileInfo dataFileInfo = new FileInfo(dataFileName); if (dataFileInfo.Exists) { if (dataFileInfo.Length == 0) { dataFileInfo.Delete(); } else { AutoCSer.IO.File.MoveBak(dataFileInfo.FullName); } } dataFileStream = new FileStream(dataFileName, FileMode.CreateNew, FileAccess.Write, FileShare.Read, bufferPool.Size, FileOptions.None); } if (indexs.Array == null) { indexs = new LeftArray <PacketIndex>(1 << 10); } if (indexs.Length == 0) { indexs.Array[0].Set(baseIdentity); indexs.Length = 1; } writeHandle = write; StatePacketIndex.Set(identity, dataFileLength); AutoCSer.DomainUnload.Unloader.Add(disposeHandle, DomainUnload.Type.Action); isDisposed = 0; } finally { buffer.TryFree(); if (isDisposed == 0) { Interlocked.Exchange(ref isWrite, 0); onStart(); if (!bufferQueue.IsEmpty && Interlocked.CompareExchange(ref isWrite, 1, 0) == 0) { write(); } } else { indexs.Length = 0; Dispose(); } } }
internal void Free() { Buffer.Free(); CompressionBuffer.TryFree(); }
internal void CloseFree() { ReceiveBuffer.Free(); ReceiveBigBuffer.TryFree(); FreeReceiveDeSerializer(); }