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); } } }
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); }
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(); } }
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(); } }
// 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); } }