Ejemplo n.º 1
0
        void NewWrittingTransactionUnsafe(TaskCompletionSource <IKeyValueDBTransaction> tcs)
        {
            var newTransactionRoot = LastCommited.NewTransactionRoot();

            _writingTransaction = new InMemoryKeyValueDBTransaction(this, newTransactionRoot, true, false);
            tcs.TrySetResult(_writingTransaction);
        }
Ejemplo n.º 2
0
        InMemoryKeyValueDBTransaction NewWritingTransactionUnsafe()
        {
            var newTransactionRoot = LastCommited.NewTransactionRoot();
            var tr = new InMemoryKeyValueDBTransaction(this, newTransactionRoot, true, false);

            _writingTransaction = tr;
            return(tr);
        }
Ejemplo n.º 3
0
        public string CalcStats()
        {
            var sb = new StringBuilder("KeyValueCount:" + LastCommited.CalcKeyCount() + Environment.NewLine
                                       + "FileCount:" + FileCollection.GetCount() + Environment.NewLine
                                       + "FileGeneration:" + FileCollection.LastFileGeneration + Environment.NewLine);

            foreach (var file in _fileCollection.FileInfos)
            {
                sb.AppendFormat("{0} Size:{1} Type:{2} Gen:{3}{4}", file.Key, FileCollection.GetSize(file.Key),
                                file.Value.FileType, file.Value.Generation, Environment.NewLine);
            }
            return(sb.ToString());
        }
Ejemplo n.º 4
0
        void LoadInfoAboutFiles()
        {
            long latestGeneration   = -1;
            uint lastestTrLogFileId = 0;
            var  keyIndexes         = new List <KeyValuePair <uint, long> >();

            foreach (var fileInfo in _fileCollection.FileInfos)
            {
                var trLog = fileInfo.Value as IFileTransactionLog;
                if (trLog != null)
                {
                    if (trLog.Generation > latestGeneration)
                    {
                        latestGeneration   = trLog.Generation;
                        lastestTrLogFileId = fileInfo.Key;
                    }
                    continue;
                }
                var keyIndex = fileInfo.Value as IKeyIndex;
                if (keyIndex == null)
                {
                    continue;
                }
                keyIndexes.Add(new KeyValuePair <uint, long>(fileInfo.Key, keyIndex.Generation));
            }
            if (keyIndexes.Count > 1)
            {
                keyIndexes.Sort((l, r) => Comparer <long> .Default.Compare(l.Value, r.Value));
            }
            var firstTrLogId     = LinkTransactionLogFileIds(lastestTrLogFileId);
            var firstTrLogOffset = 0u;
            var hasKeyIndex      = false;

            while (keyIndexes.Count > 0)
            {
                var keyIndex = keyIndexes[keyIndexes.Count - 1];
                keyIndexes.RemoveAt(keyIndexes.Count - 1);
                var info = (IKeyIndex)_fileCollection.FileInfoByIdx(keyIndex.Key);
                _nextRoot = LastCommited.NewTransactionRoot();
                if (LoadKeyIndex(keyIndex.Key, info))
                {
                    _lastCommited    = _nextRoot;
                    _nextRoot        = null;
                    firstTrLogId     = info.TrLogFileId;
                    firstTrLogOffset = info.TrLogOffset;
                    hasKeyIndex      = true;
                    break;
                }
                _fileCollection.MakeIdxUnknown(keyIndex.Key);
            }
            while (keyIndexes.Count > 0)
            {
                var keyIndex = keyIndexes[keyIndexes.Count - 1];
                keyIndexes.RemoveAt(keyIndexes.Count - 1);
                _fileCollection.MakeIdxUnknown(keyIndex.Key);
            }
            LoadTransactionLogs(firstTrLogId, firstTrLogOffset);
            if (lastestTrLogFileId != firstTrLogId && firstTrLogId != 0 || !hasKeyIndex && _fileCollection.FileInfos.Any(p => p.Value.SubDBId == 0))
            {
                CreateIndexFile(CancellationToken.None);
            }
            new Compactor(this, CancellationToken.None).FastStartCleanUp();
            _fileCollection.DeleteAllUnknownFiles();
        }
Ejemplo n.º 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);
            }
        }