Exemplo n.º 1
0
        /// <summary>
        /// 写缓存数据
        /// </summary>
        private void writeCache()
        {
            bool        isError = true;
            FileBuffers buffer  = default(FileBuffers);

            try
            {
                bufferPool.Get(ref buffer.Buffer);
                fixed(byte *bufferFixed = buffer.Buffer.Buffer)
                {
                    byte *bufferStart = bufferFixed + buffer.Buffer.StartIndex;
                    int   index = sizeof(int), snapshotSize;
                    long  writeLength = 0;

                    while ((snapshotSize = snapshot.NextSize()) != 0)
                    {
CHECK:
                        if (snapshotSize + index <= buffer.Buffer.Length)
                        {
                            snapshot.CopyTo(bufferStart + index);
                            index += snapshotSize;
                        }
                        else if (index == sizeof(int))
                        {
                            if (bigBuffer.Length < (index = snapshotSize + sizeof(int)))
                                bigBuffer = new byte[Math.Max(index, bigBuffer.Length << 1)];
                            fixed(byte *bigBufferFixed = bigBuffer)
                            {
                                snapshot.CopyTo(bigBufferFixed + sizeof(int));
                                if (snapshotSize >= Config.MinCompressSize)
                                {
                                    if (AutoCSer.IO.Compression.DeflateCompressor.Get(bigBuffer, sizeof(int), snapshotSize, ref buffer.CompressionBuffer, ref buffer.CompressionData, sizeof(int) * 2, sizeof(int) * 2))
                                    {
                                        writeCompression(ref buffer.CompressionData, snapshotSize);
                                        buffer.CompressionBuffer.TryFree();
                                        writeLength += buffer.CompressionData.Length;
                                        index        = sizeof(int);
                                        continue;
                                    }
                                    buffer.CompressionBuffer.TryFree();
                                }
                                *(int *)bigBufferFixed = snapshotSize;
                            }
                            fileStream.Write(bigBuffer, 0, index);
                            writeLength += index;
                            index        = sizeof(int);
                        }
                        else
                        {
                            if (index > Config.MinCompressSize)
                            {
                                if (AutoCSer.IO.Compression.DeflateCompressor.Get(buffer.Buffer.Buffer, buffer.Buffer.StartIndex + sizeof(int), index - sizeof(int), ref buffer.CompressionBuffer, ref buffer.CompressionData, sizeof(int) * 2, sizeof(int) * 2))
                                {
                                    writeCompression(ref buffer.CompressionData, index - sizeof(int));
                                    buffer.CompressionBuffer.TryFree();
                                    writeLength += buffer.CompressionData.Length;
                                    index        = sizeof(int);
                                    goto CHECK;
                                }
                                buffer.CompressionBuffer.TryFree();
                            }
                            *(int *)bufferStart = index - sizeof(int);
                            fileStream.Write(buffer.Buffer.Buffer, buffer.Buffer.StartIndex, index);
                            writeLength += index;
                            index        = sizeof(int);
                            goto CHECK;
                        }
                    }
                    if (index != sizeof(int))
                    {
                        if (index > Config.MinCompressSize)
                        {
                            if (AutoCSer.IO.Compression.DeflateCompressor.Get(buffer.Buffer.Buffer, buffer.Buffer.StartIndex + sizeof(int), index - sizeof(int), ref buffer.CompressionBuffer, ref buffer.CompressionData, sizeof(int) * 2, sizeof(int) * 2))
                            {
                                writeCompression(ref buffer.CompressionData, index - sizeof(int));
                                buffer.CompressionBuffer.TryFree();
                                writeLength += buffer.CompressionData.Length;
                                goto FLUSH;
                            }
                            buffer.CompressionBuffer.TryFree();
                        }
                        *(int *)bufferStart = index - sizeof(int);
                        fileStream.Write(buffer.Buffer.Buffer, buffer.Buffer.StartIndex, index);
                        writeLength += index;
                    }
FLUSH:
                    fileStream.Flush(true);
                    FileLength += writeLength;
                    isError     = false;
                }
            }
            finally
            {
                buffer.Free();
                snapshot = null;
                if (isError)
                {
                    cache.TcpServer.CallQueue.Add(new ServerCall.CacheManager(cache, ServerCall.CacheManagerServerCallType.CreateNewFileStreamError));
                    if (fileStream != null)
                    {
                        fileStream.Dispose();
                    }
                }
            }
            if (!isError)
            {
                writeQueue();
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// 文件流写入器
        /// </summary>
        /// <param name="cache"></param>
        /// <param name="config"></param>
        internal FileStreamWriter(CacheManager cache, MasterServerConfig config)
        {
            this.cache = cache;
            Config     = config;
            bufferPool = SubBuffer.Pool.GetPool(config.BufferSize);
            FileInfo file = new FileInfo(config.GetFileName);

            FileName   = file.FullName;
            IsDisposed = 1;
            FileMode    createMode = FileMode.CreateNew;
            FileBuffers buffer     = default(FileBuffers);

            try
            {
                if (file.Exists)
                {
                    if (file.Length == 0)
                    {
                        createMode = FileMode.Create;
                    }
                    else
                    {
                        fileStream = new FileStream(FileName, FileMode.Open, FileAccess.ReadWrite, FileShare.Read, bufferPool.Size, FileOptions.None);
                        bufferPool.Get(ref buffer.Buffer);
                        if (fileStream.Read(buffer.Buffer.Buffer, buffer.Buffer.StartIndex, fileHeaderSize) == fileHeaderSize)
                        {
                            fixed(byte *bufferFixed = buffer.Buffer.Buffer)
                            {
                                byte *bufferStart = bufferFixed + buffer.Buffer.StartIndex;

                                if (*(int *)bufferStart == FileHeader)
                                {
                                    Version = *(ulong *)(bufferStart + sizeof(int) * 2);
                                    FileInfo switchFile = new FileInfo(config.GetSwitchFileName);
                                    if (switchFile.Exists)
                                    {
                                        FileStream switchFileStream = new FileStream(switchFile.FullName, FileMode.Open, FileAccess.ReadWrite, FileShare.Read, bufferPool.Size, FileOptions.None);
                                        if (switchFileStream.Read(buffer.Buffer.Buffer, buffer.Buffer.StartIndex, fileHeaderSize) == fileHeaderSize && *(int *)bufferStart == FileHeader &&
                                            *(ulong *)(bufferStart + sizeof(int) * 2) > Version)
                                        {
                                            fileStream.Dispose();
                                            Version      = *(ulong *)(bufferStart + sizeof(int) * 2);
                                            fileStream   = switchFileStream;
                                            FileName     = switchFile.FullName;
                                            isSwitchFile = true;
                                        }
                                    }
                                    if (Version > 0)
                                    {
                                        LoadData loadData = new LoadData {
                                            Buffer = BufferLink.Head
                                        };
                                        int  count = fileStream.Read(buffer.Buffer.Buffer, buffer.Buffer.StartIndex, buffer.Buffer.Length), index = 0, compressionDataSize;
                                        long nextLength = (FileLength = fileStream.Length) - fileHeaderSize - count;
                                        do
                                        {
                                            while (count >= sizeof(int) * 2)
                                            {
                                                byte *read = bufferStart + index;
                                                if ((compressionDataSize = *(int *)read) < 0)
                                                {
                                                    if (count >= (compressionDataSize = -compressionDataSize) + sizeof(int) * 2)
                                                    {
                                                        buffer.CompressionBuffer.StartIndex = *(int *)(read + sizeof(int));
                                                        AutoCSer.IO.Compression.DeflateDeCompressor.Get(buffer.Buffer.Buffer, buffer.Buffer.StartIndex + (index += sizeof(int) * 2), compressionDataSize, ref buffer.CompressionBuffer);
                                                        if (buffer.CompressionBuffer.Buffer != null)
                                                        {
                                                            fixed(byte *dataFixed = buffer.CompressionBuffer.Buffer)
                                                            {
                                                                loadData.Set(buffer.CompressionBuffer.Buffer, buffer.CompressionBuffer.StartIndex, *(int *)(read + sizeof(int)), dataFixed);
                                                                if (!cache.Load(ref loadData))
                                                                {
                                                                    throw new InvalidDataException();
                                                                }
                                                            }
                                                            index += compressionDataSize;
                                                            count -= compressionDataSize + sizeof(int) * 2;
                                                            buffer.CompressionBuffer.Free();
                                                        }
                                                        else
                                                        {
                                                            throw new InvalidDataException();
                                                        }
                                                    }
                                                    else if (count + nextLength >= compressionDataSize + sizeof(int) * 2)
                                                    {
                                                        if (compressionDataSize + sizeof(int) * 2 <= buffer.Buffer.StartIndex)
                                                        {
                                                            break;
                                                        }
                                                        if (bigBuffer.Length < compressionDataSize)
                                                        {
                                                            bigBuffer = new byte[Math.Max(compressionDataSize, bigBuffer.Length << 1)];
                                                        }
                                                        System.Buffer.BlockCopy(buffer.Buffer.Buffer, buffer.Buffer.StartIndex + (index + sizeof(int) * 2), bigBuffer, 0, count -= sizeof(int) * 2);
                                                        do
                                                        {
                                                            index       = fileStream.Read(bigBuffer, count, compressionDataSize - count);
                                                            nextLength -= index;
                                                            count      += index;
                                                        }while (count != compressionDataSize);
                                                        buffer.CompressionBuffer.StartIndex = *(int *)(read + sizeof(int));
                                                        AutoCSer.IO.Compression.DeflateDeCompressor.Get(bigBuffer, 0, compressionDataSize, ref buffer.CompressionBuffer);
                                                        if (buffer.CompressionBuffer.Buffer != null)
                                                        {
                                                            fixed(byte *dataFixed = buffer.CompressionBuffer.Buffer)
                                                            {
                                                                loadData.Set(buffer.CompressionBuffer.Buffer, buffer.CompressionBuffer.StartIndex, *(int *)(read + sizeof(int)), dataFixed);
                                                                if (!cache.Load(ref loadData))
                                                                {
                                                                    throw new InvalidDataException();
                                                                }
                                                            }
                                                            index = count = 0;
                                                            buffer.CompressionBuffer.Free();
                                                        }
                                                        else
                                                        {
                                                            throw new InvalidDataException();
                                                        }
                                                    }
                                                    else
                                                    {
                                                        endError(ref buffer.Buffer, nextLength, index, count);
                                                        return;
                                                    }
                                                }
                                                else if (count >= compressionDataSize + sizeof(int))
                                                {
                                                    loadData.Set(buffer.Buffer.Buffer, buffer.Buffer.StartIndex + (index += sizeof(int)), compressionDataSize, bufferFixed);
                                                    if (!cache.Load(ref loadData))
                                                    {
                                                        throw new InvalidDataException();
                                                    }
                                                    index += compressionDataSize;
                                                    count -= compressionDataSize + sizeof(int);
                                                }
                                                else if (count + nextLength >= compressionDataSize + sizeof(int))
                                                {
                                                    if (compressionDataSize + sizeof(int) <= buffer.Buffer.StartIndex)
                                                    {
                                                        break;
                                                    }
                                                    if (bigBuffer.Length < compressionDataSize)
                                                    {
                                                        bigBuffer = new byte[Math.Max(compressionDataSize, bigBuffer.Length << 1)];
                                                    }
                                                    System.Buffer.BlockCopy(buffer.Buffer.Buffer, buffer.Buffer.StartIndex + (index + sizeof(int)), bigBuffer, 0, count -= sizeof(int));
                                                    do
                                                    {
                                                        index       = fileStream.Read(bigBuffer, count, compressionDataSize - count);
                                                        nextLength -= index;
                                                        count      += index;
                                                    }while (count != compressionDataSize);
                                                    fixed(byte *dataFixed = bigBuffer)
                                                    {
                                                        loadData.Set(bigBuffer, 0, compressionDataSize, dataFixed);
                                                        if (!cache.Load(ref loadData))
                                                        {
                                                            throw new InvalidDataException();
                                                        }
                                                    }
                                                    index = count = 0;
                                                }
                                                else
                                                {
                                                    endError(ref buffer.Buffer, nextLength, index, count);
                                                    return;
                                                }
                                            }
                                            if (nextLength == 0)
                                            {
                                                if (count == 0)
                                                {
                                                    fileStream.Seek(0, SeekOrigin.End);
                                                    IsDisposed = 0;
                                                }
                                                else
                                                {
                                                    endError(ref buffer.Buffer, nextLength, index, count);
                                                }
                                                return;
                                            }
                                            if (count != 0)
                                            {
                                                System.Buffer.BlockCopy(buffer.Buffer.Buffer, buffer.Buffer.StartIndex + index, buffer.Buffer.Buffer, buffer.Buffer.StartIndex, count);
                                            }
                                            index       = fileStream.Read(buffer.Buffer.Buffer, buffer.Buffer.StartIndex + count, buffer.Buffer.Length - count);
                                            nextLength -= index;
                                            count      += index;
                                            index       = 0;
                                        }while (true);
                                    }
                                }
                            }
                        }
                        if (!config.IsMoveBakUnknownFile)
                        {
                            throw new InvalidDataException();
                        }
                        fileStream.Dispose();
                        AutoCSer.IO.File.MoveBak(FileName);
                    }
                }
                fileStream = new FileStream(FileName, createMode, FileAccess.Write, FileShare.Read, bufferPool.Size, FileOptions.None);
                create(ref buffer.Buffer, Version);
            }
            finally
            {
                buffer.Free();
                BufferLink.Head.Array.SetNull();
                if (IsDisposed == 0)
                {
                    fileFlushSeconds = config.FileFlushSeconds;
                    Writers.PushNotNull(this);
                    OnTime.Set(Date.NowTime.OnTimeFlag.CacheFile);
                }
                else if (fileStream != null)
                {
                    fileStream.Dispose();
                }
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// 写入数据
        /// </summary>
        /// <returns></returns>
        private bool write()
        {
            Buffer data = BufferLink.GetClear();

            if (data != null)
            {
                FileBuffers buffer = default(FileBuffers);
                bufferPool.Get(ref buffer.Buffer);
                long writeLength = 0;
                try
                {
                    fixed(byte *bufferFixed = buffer.Buffer.Buffer)
                    {
                        byte *bufferStart = bufferFixed + buffer.Buffer.StartIndex;
                        int   index = sizeof(int), bigBufferSize;

START:
                        if (data.Array.Length + index <= buffer.Buffer.Length)
                        {
                            if ((data = data.Copy(ref buffer.Buffer, ref index) ?? BufferLink.GetClear()) != null)
                            {
                                goto START;
                            }
                        }
                        else if (index == sizeof(int))
                        {
                            if (bigBuffer.Length < (bigBufferSize = data.Array.Length + sizeof(int)))
                            {
                                bigBuffer = new byte[Math.Max(bigBufferSize, bigBuffer.Length << 1)];
                                fixed(byte *bigBufferFixed = bigBuffer)
                                {
                                    data = data.Copy(bigBuffer);
                                    if (bigBufferSize > Config.MinCompressSize)
                                    {
                                        if (AutoCSer.IO.Compression.DeflateCompressor.Get(bigBuffer, sizeof(int), bigBufferSize - sizeof(int), ref buffer.CompressionBuffer, ref buffer.CompressionData, sizeof(int) * 2, sizeof(int) * 2))
                                        {
                                            writeCompression(ref buffer.CompressionData, bigBufferSize - sizeof(int));
                                            buffer.CompressionBuffer.TryFree();
                                            writeLength += buffer.CompressionData.Length;
                                            if (data == null && (data = BufferLink.GetClear()) == null)
                                            {
                                                return(true);
                                            }
                                            index = sizeof(int);
                                            goto START;
                                        }
                                        buffer.CompressionBuffer.TryFree();
                                    }
                                    *(int *)bigBufferFixed = bigBufferSize - sizeof(int);
                                }
                                fileStream.Write(bigBuffer, 0, bigBufferSize);
                                writeLength += bigBufferSize;
                                if (data == null && (data = BufferLink.GetClear()) == null)
                                    return(true); }
                                index = sizeof(int);
                                goto START;
                        }
                        if (index > Config.MinCompressSize)
                        {
                            if (AutoCSer.IO.Compression.DeflateCompressor.Get(buffer.Buffer.Buffer, buffer.Buffer.StartIndex + sizeof(int), index - sizeof(int), ref buffer.CompressionBuffer, ref buffer.CompressionData, sizeof(int) * 2, sizeof(int) * 2))
                            {
                                writeCompression(ref buffer.CompressionData, index - sizeof(int));
                                buffer.CompressionBuffer.TryFree();
                                writeLength += buffer.CompressionData.Length;
                                if (data == null && (data = BufferLink.GetClear()) == null)
                                {
                                    return(true);
                                }
                                index = sizeof(int);
                                goto START;
                            }
                            buffer.CompressionBuffer.TryFree();
                        }
                        *(int *)bufferStart = index - sizeof(int);
                        fileStream.Write(buffer.Buffer.Buffer, buffer.Buffer.StartIndex, index);
                        writeLength += index;
                        if (data == null && (data = BufferLink.GetClear()) == null)
                        {
                            return(true);
                        }
                        index = sizeof(int);
                        goto START;
                    }
                }
                catch (Exception error)
                {
                    writeLength = 0;
                    AutoCSer.Log.Pub.Log.Add(Log.LogType.Fatal, error);
                    fileStream.Dispose();
                    return(false);
                }
                finally
                {
                    buffer.Free();
                    if (writeLength != 0)
                    {
                        fileStream.Flush(true);
                        FileLength += writeLength;
                        for (FileReader reader = Readers.End; reader != null; reader = reader.DoubleLinkPrevious)
                        {
                            isTryRead |= reader.TryRead();
                        }
                    }
                }
            }
            return(true);
        }