Наследование: IFileInfo, IFileTransactionLog
Пример #1
0
 void LoadInfoAboutFiles()
 {
     foreach (var file in _fileCollection.Enumerate())
     {
         try
         {
             var reader = file.GetExclusiveReader();
             if (reader.CheckMagic(MagicStartOfFile))
             {
                 var fileType = (KVFileType)reader.ReadUInt8();
                 IFileInfo fileInfo;
                 switch (fileType)
                 {
                     case KVFileType.TransactionLog:
                         fileInfo = new FileTransactionLog(reader);
                         break;
                     case KVFileType.KeyIndex:
                         fileInfo = new FileKeyIndex(reader);
                         break;
                     case KVFileType.PureValues:
                         fileInfo = new FilePureValues(reader);
                         break;
                     case KVFileType.PureValuesWithId:
                         fileInfo = new FilePureValuesWithId(reader);
                         break;
                     case KVFileType.HashKeyIndex:
                         fileInfo = new HashKeyIndex(reader);
                         break;
                     default:
                         fileInfo = UnknownFile.Instance;
                         break;
                 }
                 if (_fileGeneration < fileInfo.Generation) _fileGeneration = fileInfo.Generation;
                 _fileInfos.TryAdd(file.Index, fileInfo);
             }
             else
             {
                 _fileInfos.TryAdd(file.Index, UnknownFile.Instance);
             }
         }
         catch (Exception)
         {
             _fileInfos.TryAdd(file.Index, UnknownFile.Instance);
         }
     }
 }
Пример #2
0
        void WriteStartOfNewTransactionLogFile()
        {
            if (_writerWithTransactionLog != null)
            {
                _writerWithTransactionLog.WriteUInt8((byte)KVCommandType.EndOfFile);
                _writerWithTransactionLog.FlushBuffer();
                _fileWithTransactionLog.HardFlush();
                _fileWithTransactionLog.Truncate();
                _fileIdWithPreviousTransactionLog = _fileIdWithTransactionLog;
            }
            _fileWithTransactionLog   = FileCollection.AddFile("trl");
            _fileIdWithTransactionLog = _fileWithTransactionLog.Index;
            var transactionLog = new FileTransactionLog(FileCollection.NextGeneration(), FileCollection.Guid, _fileIdWithPreviousTransactionLog);

            _writerWithTransactionLog = _fileWithTransactionLog.GetAppenderWriter();
            transactionLog.WriteHeader(_writerWithTransactionLog);
            FileCollection.SetInfo(_fileIdWithTransactionLog, transactionLog);
        }
Пример #3
0
        void LoadInfoAboutFiles()
        {
            foreach (var file in _fileCollection.Enumerate())
            {
                try
                {
                    var  reader = file.GetExclusiveReader();
                    var  magic  = reader.ReadByteArrayRaw(MagicStartOfFile.Length);
                    Guid?guid   = null;
                    if (
                        BitArrayManipulation.CompareByteArray(magic, magic.Length, MagicStartOfFileWithGuid,
                                                              MagicStartOfFileWithGuid.Length) == 0)
                    {
                        guid = reader.ReadGuid();
                        if (Guid.HasValue && Guid.Value != guid)
                        {
                            _fileInfos.TryAdd(file.Index, UnknownFile.Instance);
                            continue;
                        }
                        Guid = guid;
                    }
                    else if (
                        BitArrayManipulation.CompareByteArray(magic, magic.Length, MagicStartOfFile,
                                                              MagicStartOfFile.Length) != 0)
                    {
                        _fileInfos.TryAdd(file.Index, UnknownFile.Instance);
                        continue;
                    }
                    var       fileType = (KVFileType)reader.ReadUInt8();
                    IFileInfo fileInfo;
                    switch (fileType)
                    {
                    case KVFileType.TransactionLog:
                        fileInfo = new FileTransactionLog(reader, guid);
                        break;

                    case KVFileType.KeyIndex:
                        fileInfo = new FileKeyIndex(reader, guid, false, false, false);
                        break;

                    case KVFileType.KeyIndexWithCommitUlong:
                        fileInfo = new FileKeyIndex(reader, guid, true, false, false);
                        break;

                    case KVFileType.ModernKeyIndex:
                        fileInfo = new FileKeyIndex(reader, guid, true, true, false);
                        break;

                    case KVFileType.ModernKeyIndexWithUlongs:
                        fileInfo = new FileKeyIndex(reader, guid, true, true, true);
                        break;

                    case KVFileType.PureValues:
                        fileInfo = new FilePureValues(reader, guid);
                        break;

                    case KVFileType.PureValuesWithId:
                        fileInfo = new FilePureValuesWithId(reader, guid);
                        break;

                    case KVFileType.HashKeyIndex:
                        fileInfo = new HashKeyIndex(reader, guid);
                        break;

                    default:
                        fileInfo = UnknownFile.Instance;
                        break;
                    }
                    if (_fileGeneration < fileInfo.Generation)
                    {
                        _fileGeneration = fileInfo.Generation;
                    }
                    _fileInfos.TryAdd(file.Index, fileInfo);
                }
                catch (Exception)
                {
                    _fileInfos.TryAdd(file.Index, UnknownFile.Instance);
                }
            }
            if (!Guid.HasValue)
            {
                Guid = System.Guid.NewGuid();
            }
        }
Пример #4
0
 void LoadInfoAboutFiles()
 {
     foreach (var file in _fileCollection.Enumerate())
     {
         try
         {
             var reader = file.GetExclusiveReader();
             var magic = reader.ReadByteArrayRaw(MagicStartOfFile.Length);
             Guid? guid = null;
             if (
                 BitArrayManipulation.CompareByteArray(magic, magic.Length, MagicStartOfFileWithGuid,
                     MagicStartOfFileWithGuid.Length) == 0)
             {
                 guid = reader.ReadGuid();
                 if (Guid.HasValue && Guid.Value != guid)
                 {
                     _fileInfos.TryAdd(file.Index, UnknownFile.Instance);
                     continue;
                 }
                 Guid = guid;
             }
             else if (
                 BitArrayManipulation.CompareByteArray(magic, magic.Length, MagicStartOfFile,
                     MagicStartOfFile.Length) != 0)
             {
                 _fileInfos.TryAdd(file.Index, UnknownFile.Instance);
                 continue;
             }
             var fileType = (KVFileType)reader.ReadUInt8();
             IFileInfo fileInfo;
             switch (fileType)
             {
                 case KVFileType.TransactionLog:
                     fileInfo = new FileTransactionLog(reader, guid);
                     break;
                 case KVFileType.KeyIndex:
                     fileInfo = new FileKeyIndex(reader, guid, false);
                     break;
                 case KVFileType.KeyIndexWithCommitUlong:
                     fileInfo = new FileKeyIndex(reader, guid, true);
                     break;
                 case KVFileType.PureValues:
                     fileInfo = new FilePureValues(reader, guid);
                     break;
                 case KVFileType.PureValuesWithId:
                     fileInfo = new FilePureValuesWithId(reader, guid);
                     break;
                 case KVFileType.HashKeyIndex:
                     fileInfo = new HashKeyIndex(reader, guid);
                     break;
                 default:
                     fileInfo = UnknownFile.Instance;
                     break;
             }
             if (_fileGeneration < fileInfo.Generation) _fileGeneration = fileInfo.Generation;
             _fileInfos.TryAdd(file.Index, fileInfo);
         }
         catch (Exception)
         {
             _fileInfos.TryAdd(file.Index, UnknownFile.Instance);
         }
     }
     if (!Guid.HasValue)
     {
         Guid = System.Guid.NewGuid();
     }
 }
Пример #5
0
        // Return true if it is suitable for continuing writing new transactions
        bool LoadTransactionLog(uint fileId, uint logOffset)
        {
            var inlineValueBuf = new byte[MaxValueSizeInlineInMemory];
            var stack          = new List <NodeIdxPair>();
            var collectionFile = FileCollection.GetFile(fileId);
            var reader         = collectionFile.GetExclusiveReader();

            try
            {
                if (logOffset == 0)
                {
                    FileTransactionLog.SkipHeader(reader);
                }
                else
                {
                    reader.SkipBlock(logOffset);
                }
                if (reader.Eof)
                {
                    return(true);
                }
                var afterTemporaryEnd = false;
                while (!reader.Eof)
                {
                    var command = (KVCommandType)reader.ReadUInt8();
                    if (command == 0 && afterTemporaryEnd)
                    {
                        collectionFile.SetSize(reader.GetCurrentPosition() - 1);
                        return(true);
                    }
                    afterTemporaryEnd = false;
                    switch (command & KVCommandType.CommandMask)
                    {
                    case KVCommandType.CreateOrUpdateDeprecated:
                    case KVCommandType.CreateOrUpdate:
                    {
                        if (_nextRoot == null)
                        {
                            return(false);
                        }
                        var keyLen   = reader.ReadVInt32();
                        var valueLen = reader.ReadVInt32();
                        var key      = new byte[keyLen];
                        reader.ReadBlock(key);
                        var keyBuf = ByteBuffer.NewAsync(key);
                        if ((command & KVCommandType.FirstParamCompressed) != 0)
                        {
                            _compression.DecompressKey(ref keyBuf);
                        }
                        var ctx = new CreateOrUpdateCtx
                        {
                            KeyPrefix   = BitArrayManipulation.EmptyByteArray,
                            Key         = keyBuf,
                            ValueFileId = fileId,
                            ValueOfs    = (uint)reader.GetCurrentPosition(),
                            ValueSize   = (command & KVCommandType.SecondParamCompressed) != 0 ? -valueLen : valueLen
                        };
                        if (valueLen <= MaxValueSizeInlineInMemory && (command & KVCommandType.SecondParamCompressed) == 0)
                        {
                            reader.ReadBlock(inlineValueBuf, 0, valueLen);
                            StoreValueInlineInMemory(ByteBuffer.NewSync(inlineValueBuf, 0, valueLen), out ctx.ValueOfs, out ctx.ValueSize);
                            ctx.ValueFileId = 0;
                        }
                        else
                        {
                            reader.SkipBlock(valueLen);
                        }
                        _nextRoot.CreateOrUpdate(ctx);
                    }
                    break;

                    case KVCommandType.EraseOne:
                    {
                        if (_nextRoot == null)
                        {
                            return(false);
                        }
                        var keyLen = reader.ReadVInt32();
                        var key    = new byte[keyLen];
                        reader.ReadBlock(key);
                        var keyBuf = ByteBuffer.NewAsync(key);
                        if ((command & KVCommandType.FirstParamCompressed) != 0)
                        {
                            _compression.DecompressKey(ref keyBuf);
                        }
                        long keyIndex;
                        var  findResult = _nextRoot.FindKey(stack, out keyIndex, BitArrayManipulation.EmptyByteArray, keyBuf);
                        if (findResult == FindResult.Exact)
                        {
                            _nextRoot.EraseRange(keyIndex, keyIndex);
                        }
                    }
                    break;

                    case KVCommandType.EraseRange:
                    {
                        if (_nextRoot == null)
                        {
                            return(false);
                        }
                        var keyLen1 = reader.ReadVInt32();
                        var keyLen2 = reader.ReadVInt32();
                        var key     = new byte[keyLen1];
                        reader.ReadBlock(key);
                        var keyBuf = ByteBuffer.NewAsync(key);
                        if ((command & KVCommandType.FirstParamCompressed) != 0)
                        {
                            _compression.DecompressKey(ref keyBuf);
                        }
                        long keyIndex1;
                        var  findResult = _nextRoot.FindKey(stack, out keyIndex1, BitArrayManipulation.EmptyByteArray, keyBuf);
                        if (findResult == FindResult.Previous)
                        {
                            keyIndex1++;
                        }
                        key = new byte[keyLen2];
                        reader.ReadBlock(key);
                        keyBuf = ByteBuffer.NewAsync(key);
                        if ((command & KVCommandType.SecondParamCompressed) != 0)
                        {
                            _compression.DecompressKey(ref keyBuf);
                        }
                        long keyIndex2;
                        findResult = _nextRoot.FindKey(stack, out keyIndex2, BitArrayManipulation.EmptyByteArray, keyBuf);
                        if (findResult == FindResult.Next)
                        {
                            keyIndex2--;
                        }
                        _nextRoot.EraseRange(keyIndex1, keyIndex2);
                    }
                    break;

                    case KVCommandType.TransactionStart:
                        if (!reader.CheckMagic(MagicStartOfTransaction))
                        {
                            return(false);
                        }
                        _nextRoot = LastCommited.NewTransactionRoot();
                        break;

                    case KVCommandType.CommitWithDeltaUlong:
                        unchecked     // overflow is expected in case commitUlong is decreasing but that should be rare
                        {
                            _nextRoot.CommitUlong += reader.ReadVUInt64();
                        }
                        goto case KVCommandType.Commit;

                    case KVCommandType.Commit:
                        _nextRoot.TrLogFileId = fileId;
                        _nextRoot.TrLogOffset = (uint)reader.GetCurrentPosition();
                        _lastCommited         = _nextRoot;
                        _nextRoot             = null;
                        break;

                    case KVCommandType.Rollback:
                        _nextRoot = null;
                        break;

                    case KVCommandType.EndOfFile:
                        return(false);

                    case KVCommandType.TemporaryEndOfFile:
                        _lastCommited.TrLogFileId = fileId;
                        _lastCommited.TrLogOffset = (uint)reader.GetCurrentPosition();
                        afterTemporaryEnd         = true;
                        break;

                    default:
                        _nextRoot = null;
                        return(false);
                    }
                }
                return(afterTemporaryEnd);
            }
            catch (EndOfStreamException)
            {
                _nextRoot = null;
                return(false);
            }
        }