/// <summary> /// 队列数据 读文件 /// </summary> /// <param name="node">消息队列节点</param> /// <param name="config">队列数据 读取配置</param> /// <param name="readerIndex">读文件编号</param> internal QueueReader(QueueNode node, Config.QueueReader config, int readerIndex) { Writer = node.Writer; Node = node; this.config = config ?? defaultConfig; this.config.Format(); this.readerIndex = readerIndex; int isReader = 0; ++Writer.ReadCount; writerAppendIdentity = Writer.StatePacketIndex.Identity; try { if (checkStateFile()) { stateFileStream = new FileStream(stateFileName, FileMode.Open, FileAccess.ReadWrite, FileShare.Read, 256, FileOptions.None); stateFileStream.Seek(-stateBufferSize, SeekOrigin.End); stateFileStream.Read(bigBuffer, 0, stateBufferSize); fixed(byte *stateDataFixed = bigBuffer) Identity = *(ulong *)stateDataFixed; } else { stateFileStream = new FileStream(stateFileName, FileMode.CreateNew, FileAccess.Write, FileShare.Read, 256, FileOptions.None); } long fileIndex = 0; if (Writer.GetIndex(Identity, ref dataFileIdentity, ref fileIndex)) { writeIdentity = Identity; memoryEndIdentity = Identity + config.MemoryCacheNodeCount; messages = new MessageItem[(int)config.MemoryCacheNodeCount + QueueWriter.MaxPacketCount + 1]; if (Identity == writerAppendIdentity || loadFile(fileIndex)) { isReader = 1; } } } finally { if (isReader == 0) { Dispose(); } } }
/// <summary> /// 设置已完成消息标识 /// </summary> internal void SaveIdentity() { ulong identity = (ulong)Interlocked.Exchange(ref currentSetIdentity, 0L); if (identity > Identity && identity <= sendIdentity) { if (stateFileStream.Length >= QueueWriter.MaxStateFileSize) { stateFileStream.Dispose(); stateFileStream = null; FileInfo bakFile = new FileInfo(stateBackupFileName); if (bakFile.Exists) { bakFile.Delete(); } System.IO.File.Move(stateFileName, stateBackupFileName); stateFileStream = new FileStream(stateFileName, FileMode.CreateNew, FileAccess.Write, FileShare.Read, 256, FileOptions.None); } fixed(byte *stateDataFixed = bigBuffer) * (ulong *)stateDataFixed = identity; stateFileStream.Write(bigBuffer, 0, stateBufferSize); if (flushIdentityTime != Date.NowTime.Now) { stateFileStream.Flush(true); flushIdentityTime = Date.NowTime.Now; } if (isDisposed == 0) { int endMessageIndex = messageIndex + (int)(uint)(identity - Identity); if (endMessageIndex >= messages.Length) { endMessageIndex -= messages.Length; } do { messages[messageIndex].FreeBuffer(); if (++messageIndex == messages.Length) { messageIndex = 0; } }while (messageIndex != endMessageIndex); Identity = identity; memoryEndIdentity = identity + config.MemoryCacheNodeCount; if (writeIdentity < memoryEndIdentity && writeIdentity < writerAppendIdentity) { byte isReader = 0, isLoadFile = 0; try { if (dataFileStream != null) { if (dataFileIdentity == writeIdentity) { isLoadFile = 1; if (loadFile()) { isReader = 1; } } else { dataFileStream.Dispose(); dataFileStream = null; } } if (isLoadFile == 0) { long fileIndex = 0; if (Writer.GetIndex(writeIdentity, ref dataFileIdentity, ref fileIndex) && loadFile(fileIndex)) { isReader = 1; } } } finally { if (isReader == 0) { Dispose(); } } } if (onGetMessage != null && isDisposed == 0) { ReturnParameter returnParameter = new ReturnParameter { IsDeSerializeStream = isGetMessageStream, Type = ReturnType.Success }; ulong endIdentity = Math.Min(Identity + config.SendClientCount, writeIdentity); while (sendIdentity != endIdentity) { returnParameter.Parameter = messages[sendMessageIndex].Data; if (onGetMessage(returnParameter)) { nextSendIndex(); } else { onGetMessage = null; return; } } } } } }