Example #1
0
        void MakeWrittable()
        {
            if (_writting)
            {
                return;
            }
            if (_preapprovedWritting)
            {
                _writting            = true;
                _preapprovedWritting = false;
                _keyValueDB.WriteStartTransaction();
                return;
            }
            if (_readOnly)
            {
                throw new BTDBTransactionRetryException("Cannot write from readOnly transaction");
            }
            var oldBTreeRoot = BtreeRoot;

            _btreeRoot = _keyValueDB.MakeWrittableTransaction(this, oldBTreeRoot);
            _keyValueDB.StartedUsingBTreeRoot(_btreeRoot);
            _keyValueDB.FinishedUsingBTreeRoot(oldBTreeRoot);
            _btreeRoot.DescriptionForLeaks = _descriptionForLeaks;
            _writting = true;
            InvalidateCurrentKey();
            _keyValueDB.WriteStartTransaction();
        }
Example #2
0
 void CalculateFileUsefullness(IBTreeRootNode root)
 {
     root.Iterate((valueFileId, valueOfs, valueSize) =>
     {
         _cancellation.ThrowIfCancellationRequested();
         _fileStats.GetOrFakeValueRef(valueFileId).AddLength((uint)Math.Abs(valueSize));
     });
 }
Example #3
0
 void ForbidDeleteOfFilesUsedByStillRunningOldTransaction(IBTreeRootNode root)
 {
     root.Iterate((valueFileId, valueOfs, valueSize) =>
     {
         _cancellation.ThrowIfCancellationRequested();
         _fileStats.GetOrFakeValueRef(valueFileId).MarkForbidToDelete();
     });
 }
Example #4
0
 internal void CommitWrittingTransaction(IBTreeRootNode btreeRoot)
 {
     lock (_writeLock)
     {
         _writingTransaction = null;
         _lastCommited = btreeRoot;
         TryDequeWaiterForWrittingTransaction();
     }
 }
Example #5
0
 internal void CommitWrittingTransaction(IBTreeRootNode btreeRoot)
 {
     lock (_writeLock)
     {
         _writingTransaction = null;
         _lastCommited       = btreeRoot;
         TryDequeWaiterForWrittingTransaction();
     }
 }
 public InMemoryKeyValueDBTransaction(InMemoryKeyValueDB keyValueDB, IBTreeRootNode btreeRoot, bool writing, bool readOnly)
 {
     _preapprovedWriting = writing;
     _readOnly           = readOnly;
     _keyValueDB         = keyValueDB;
     _btreeRoot          = btreeRoot;
     _keyIndex           = -1;
     _cursorMovedCounter = 0;
 }
Example #7
0
 public KeyValueDBTransaction(KeyValueDB keyValueDB, IBTreeRootNode btreeRoot, bool writing, bool readOnly)
 {
     _preapprovedWriting = writing;
     _readOnly           = readOnly;
     _keyValueDB         = keyValueDB;
     _btreeRoot          = btreeRoot;
     _keyIndex           = -1;
     _cursorMovedCounter = 0;
     _keyValueDB.StartedUsingBTreeRoot(_btreeRoot);
 }
 public void Dispose()
 {
     if (_writting || _preapprovedWritting)
     {
         _keyValueDB.RevertWrittingTransaction();
         _writting            = false;
         _preapprovedWritting = false;
     }
     _btreeRoot = null;
 }
Example #9
0
 internal IBTreeRootNode MakeWrittableTransaction(InMemoryKeyValueDBTransaction keyValueDBTransaction, IBTreeRootNode btreeRoot)
 {
     lock (_writeLock)
     {
         if (_writingTransaction != null) throw new BTDBTransactionRetryException("Another writting transaction already running");
         if (LastCommited != btreeRoot) throw new BTDBTransactionRetryException("Another writting transaction already finished");
         _writingTransaction = keyValueDBTransaction;
         return btreeRoot.NewTransactionRoot();
     }
 }
Example #10
0
        uint CreateKeyIndexFile(IBTreeRootNode root, CancellationToken cancellation)
        {
            var start    = DateTime.UtcNow;
            var file     = FileCollection.AddFile("kvi");
            var writer   = file.GetAppenderWriter();
            var keyCount = root.CalcKeyCount();

            if (root.TrLogFileId != 0)
            {
                FileCollection.ConcurentTemporaryTruncate(root.TrLogFileId, root.TrLogOffset);
            }
            var keyIndex = new FileKeyIndex(FileCollection.NextGeneration(), FileCollection.Guid, root.TrLogFileId, root.TrLogOffset, keyCount, root.CommitUlong, KeyIndexCompression.None);

            keyIndex.WriteHeader(writer);
            if (keyCount > 0)
            {
                var stack   = new List <NodeIdxPair>();
                var prevKey = ByteBuffer.NewEmpty();
                root.FillStackByIndex(stack, 0);
                do
                {
                    cancellation.ThrowIfCancellationRequested();
                    var nodeIdxPair = stack[stack.Count - 1];
                    var memberValue = ((IBTreeLeafNode)nodeIdxPair.Node).GetMemberValue(nodeIdxPair.Idx);
                    var key         = ((IBTreeLeafNode)nodeIdxPair.Node).GetKey(nodeIdxPair.Idx);
                    var prefixLen   = 0;
                    var minLen      = Math.Min(prevKey.Length, key.Length);
                    for (int i = 0; i < minLen; i++)
                    {
                        if (prevKey[i] != key[i])
                        {
                            prefixLen = i;
                            break;
                        }
                    }
                    writer.WriteVUInt32((uint)prefixLen);
                    writer.WriteVUInt32((uint)(key.Length - prefixLen));
                    writer.WriteBlock(key.SubBuffer(prefixLen));
                    writer.WriteVUInt32(memberValue.ValueFileId);
                    writer.WriteVUInt32(memberValue.ValueOfs);
                    writer.WriteVInt32(memberValue.ValueSize);
                    prevKey = key;
                } while (root.FindNextKey(stack));
            }
            writer.FlushBuffer();
            file.HardFlush();
            writer.WriteInt32(EndOfIndexFileMarker);
            writer.FlushBuffer();
            file.HardFlush();
            file.Truncate();
            FileCollection.SetInfo(file.Index, keyIndex);
            Logger?.KeyValueIndexCreated(file.Index, keyIndex.KeyValueCount, file.GetSize(), DateTime.UtcNow - start);
            return(file.Index);
        }
 public InMemoryKeyValueDBTransaction(InMemoryKeyValueDB keyValueDB, IBTreeRootNode btreeRoot, bool writting, bool readOnly)
 {
     _preapprovedWritting = writting;
     _readOnly = readOnly;
     _keyValueDB = keyValueDB;
     _btreeRoot = btreeRoot;
     _prefix = BitArrayManipulation.EmptyByteArray;
     _prefixKeyStart = 0;
     _prefixKeyCount = -1;
     _keyIndex = -1;
 }
 public InMemoryKeyValueDBTransaction(InMemoryKeyValueDB keyValueDB, IBTreeRootNode btreeRoot, bool writting, bool readOnly)
 {
     _preapprovedWritting = writting;
     _readOnly            = readOnly;
     _keyValueDB          = keyValueDB;
     _btreeRoot           = btreeRoot;
     _prefix         = BitArrayManipulation.EmptyByteArray;
     _prefixKeyStart = 0;
     _prefixKeyCount = -1;
     _keyIndex       = -1;
 }
Example #13
0
 public KeyValueDBTransaction(KeyValueDB keyValueDB, IBTreeRootNode btreeRoot, bool writing, bool readOnly)
 {
     _preapprovedWriting = writing;
     _readOnly           = readOnly;
     _keyValueDB         = keyValueDB;
     _btreeRoot          = btreeRoot;
     _prefix             = Array.Empty <byte>();
     _prefixKeyStart     = 0;
     _prefixKeyCount     = -1;
     _keyIndex           = -1;
     _keyValueDB.StartedUsingBTreeRoot(_btreeRoot);
 }
Example #14
0
 void CalculateFileUsefullness(IBTreeRootNode root, bool uptodate)
 {
     root.Iterate((valueFileId, valueOfs, valueSize) =>
     {
         var id        = valueFileId;
         var fileStats = _fileStats;
         _cancellation.ThrowIfCancellationRequested();
         if (id < fileStats.Length)
         {
             fileStats[id].AddLength((uint)Math.Abs(valueSize), uptodate);
         }
     });
 }
Example #15
0
 internal void StartedUsingBTreeRoot(IBTreeRootNode btreeRoot)
 {
     lock (_usedBTreeRootNodesLock)
     {
         var uses = btreeRoot.UseCount;
         uses++;
         btreeRoot.UseCount = uses;
         if (uses == 1)
         {
             _usedBTreeRootNodes.Add(btreeRoot);
         }
     }
 }
Example #16
0
 internal long AtomicallyChangeBTree(Action <IBTreeRootNode> action)
 {
     using (var tr = StartWritingTransaction().Result)
     {
         var newRoot = (tr as KeyValueDBTransaction).BtreeRoot;
         action(newRoot);
         lock (_writeLock)
         {
             _lastCommited = newRoot;
         }
         return(newRoot.TransactionId);
     }
 }
Example #17
0
        internal void FastStartCleanUp()
        {
            if (_keyValueDB.FileCollection.GetCount() == 0)
            {
                return;
            }
            _root = _keyValueDB.LastCommited;
            var dontTouchGeneration = _keyValueDB.GetGeneration(_root.TrLogFileId);

            InitFileStats(dontTouchGeneration);
            CalculateFileUsefullness();
            MarkTotallyUselessFilesAsUnknown();
        }
Example #18
0
 internal void FinishedUsingBTreeRoot(IBTreeRootNode btreeRoot)
 {
     lock (_usedBTreeRootNodesLock)
     {
         var uses = btreeRoot.UseCount;
         uses--;
         btreeRoot.UseCount = uses;
         if (uses == 0)
         {
             _usedBTreeRootNodes.Remove(btreeRoot);
         }
     }
 }
Example #19
0
 private void ForbidDeleteOfFilesUsedByStillRunningOldTransaction(IBTreeRootNode root)
 {
     root.Iterate((valueFileId, valueOfs, valueSize) =>
     {
         var id        = valueFileId;
         var fileStats = _fileStats;
         _cancellation.ThrowIfCancellationRequested();
         if (id < fileStats.Length)
         {
             fileStats[id].MarkForbidToDelete();
         }
     });
 }
Example #20
0
        internal void FastStartCleanUp()
        {
            if (_keyValueDB.FileCollection.GetCount() == 0)
            {
                return;
            }
            _root = _keyValueDB.LastCommited;
            var dontTouchGeneration = _keyValueDB.GetGeneration(_root.TrLogFileId);

            InitFileStats(dontTouchGeneration);
            CalculateFileUsefullness(_root, false); // useless files are calculated from "old" values, but they are uptodate
            MarkTotallyUselessFilesAsUnknown();
        }
Example #21
0
 internal void FastStartCleanUp()
 {
     if (_keyValueDB.FileCollection.GetCount() == 0) return;
     _root = _keyValueDB.LastCommited;
     var dontTouchGeneration = _keyValueDB.GetGeneration(_root.TrLogFileId);
     InitFileStats(dontTouchGeneration);
     CalculateFileUsefullness();
     var toRemoveFileIds = new List<uint>();
     for (var i = 0; i < _fileStats.Length; i++)
     {
         if (_fileStats[i].Useless()) toRemoveFileIds.Add((uint) i);
     }
     _keyValueDB.MarkAsUnknown(toRemoveFileIds);
 }
Example #22
0
 public void Dispose()
 {
     if (_writting || _preapprovedWritting)
     {
         _keyValueDB.RevertWrittingTransaction(_preapprovedWritting);
         _writting            = false;
         _preapprovedWritting = false;
     }
     if (_btreeRoot == null)
     {
         return;
     }
     _keyValueDB.FinishedUsingBTreeRoot(_btreeRoot);
     _btreeRoot = null;
 }
Example #23
0
 void UpdateTransactionLogInBTreeRoot(IBTreeRootNode btreeRoot)
 {
     if (btreeRoot.TrLogFileId != _fileIdWithTransactionLog && btreeRoot.TrLogFileId != 0)
     {
         _compactorScheduler?.AdviceRunning();
     }
     btreeRoot.TrLogFileId = _fileIdWithTransactionLog;
     if (_writerWithTransactionLog != null)
     {
         btreeRoot.TrLogOffset = (uint)_writerWithTransactionLog.GetCurrentPosition();
     }
     else
     {
         btreeRoot.TrLogOffset = 0;
     }
 }
Example #24
0
 internal bool Run()
 {
     if (_keyValueDB.FileCollection.GetCount() == 0) return false;
     _root = _keyValueDB.LastCommited;
     var dontTouchGeneration = _keyValueDB.GetGeneration(_root.TrLogFileId);
     InitFileStats(dontTouchGeneration);
     CalculateFileUsefullness();
     var totalWaste = CalcTotalWaste();
     if (totalWaste < (ulong)_keyValueDB.MaxTrLogFileSize / 4)
     {
         if (_keyValueDB.DistanceFromLastKeyIndex(_root) < (ulong)_keyValueDB.MaxTrLogFileSize / 4) return false;
         _keyValueDB.CreateIndexFile(_cancellation);
         _keyValueDB.FileCollection.DeleteAllUnknownFiles();
         return false;
     }
     _cancellation.ThrowIfCancellationRequested();
     uint valueFileId;
     var writer = _keyValueDB.StartPureValuesFile(out valueFileId);
     _newPositionMap = new Dictionary<ulong, uint>();
     var toRemoveFileIds = new List<uint>();
     while (true)
     {
         var wastefullFileId = FindMostWastefullFile(_keyValueDB.MaxTrLogFileSize - writer.GetCurrentPosition());
         if (wastefullFileId == 0) break;
         MoveValuesContent(writer, wastefullFileId);
         _fileStats[wastefullFileId] = new FileStat(0);
         toRemoveFileIds.Add(wastefullFileId);
     }
     var valueFile = _keyValueDB.FileCollection.GetFile(valueFileId);
     valueFile.HardFlush();
     valueFile.Truncate();
     var btreesCorrectInTransactionId = _keyValueDB.AtomicallyChangeBTree(root => root.RemappingIterate((uint oldFileId, uint oldOffset, out uint newFileId, out uint newOffset) =>
         {
             newFileId = valueFileId;
             _cancellation.ThrowIfCancellationRequested();
             return _newPositionMap.TryGetValue(((ulong)oldFileId << 32) | oldOffset, out newOffset);
         }));
     _keyValueDB.CreateIndexFile(_cancellation);
     _keyValueDB.WaitForFinishingTransactionsBefore(btreesCorrectInTransactionId, _cancellation);
     if (_newPositionMap.Count == 0)
     {
         toRemoveFileIds.Add(valueFileId);
     }
     _keyValueDB.MarkAsUnknown(toRemoveFileIds);
     _keyValueDB.FileCollection.DeleteAllUnknownFiles();
     return true;
 }
 public void Commit()
 {
     if (BtreeRoot == null) throw new BTDBException("Transaction already commited or disposed");
     InvalidateCurrentKey();
     var currentBtreeRoot = _btreeRoot;
     _btreeRoot = null;
     if (_preapprovedWritting)
     {
         _preapprovedWritting = false;
         _keyValueDB.RevertWrittingTransaction();
     }
     else if (_writting)
     {
         _keyValueDB.CommitWrittingTransaction(currentBtreeRoot);
         _writting = false;
     }
 }
Example #26
0
        internal ulong DistanceFromLastKeyIndex(IBTreeRootNode root)
        {
            var keyIndex = FileCollection.FileInfos.Where(p => p.Value.FileType == KVFileType.KeyIndex).Select(p => (IKeyIndex)p.Value).FirstOrDefault();

            if (keyIndex == null)
            {
                if (FileCollection.FileInfos.Count(p => p.Value.SubDBId == 0) > 1)
                {
                    return(ulong.MaxValue);
                }
                return(root.TrLogOffset);
            }
            if (root.TrLogFileId != keyIndex.TrLogFileId)
            {
                return(ulong.MaxValue);
            }
            return(root.TrLogOffset - keyIndex.TrLogOffset);
        }
        public void Commit()
        {
            if (BtreeRoot == null)
            {
                throw new BTDBException("Transaction already commited or disposed");
            }
            InvalidateCurrentKey();
            var currentBtreeRoot = _btreeRoot;

            _btreeRoot = null;
            if (_preapprovedWritting)
            {
                _preapprovedWritting = false;
                _keyValueDB.RevertWrittingTransaction();
            }
            else if (_writting)
            {
                _keyValueDB.CommitWrittingTransaction(currentBtreeRoot);
                _writting = false;
            }
        }
Example #28
0
        void MakeWrittable()
        {
            if (_writting)
            {
                return;
            }
            if (_preapprovedWritting)
            {
                _writting            = true;
                _preapprovedWritting = false;
                return;
            }
            if (_readOnly)
            {
                throw new BTDBTransactionRetryException("Cannot write from readOnly transaction");
            }
            var oldBTreeRoot = BtreeRoot;

            _btreeRoot = _keyValueDB.MakeWrittableTransaction(this, oldBTreeRoot);
            _writting  = true;
            InvalidateCurrentKey();
        }
Example #29
0
        internal void CommitWrittingTransaction(IBTreeRootNode btreeRoot, bool temporaryCloseTransactionLog)
        {
            var deltaUlong = unchecked (btreeRoot.CommitUlong - _lastCommited.CommitUlong);

            if (deltaUlong != 0)
            {
                _writerWithTransactionLog.WriteUInt8((byte)KVCommandType.CommitWithDeltaUlong);
                _writerWithTransactionLog.WriteVUInt64(deltaUlong);
            }
            else
            {
                _writerWithTransactionLog.WriteUInt8((byte)KVCommandType.Commit);
            }
            if (DurableTransactions || !temporaryCloseTransactionLog)
            {
                _writerWithTransactionLog.FlushBuffer();
            }
            UpdateTransactionLogInBTreeRoot(btreeRoot);
            if (DurableTransactions)
            {
                _fileWithTransactionLog.HardFlush();
            }
            if (temporaryCloseTransactionLog)
            {
                _writerWithTransactionLog.WriteUInt8((byte)KVCommandType.TemporaryEndOfFile);
                _writerWithTransactionLog.FlushBuffer();
                if (DurableTransactions)
                {
                    _fileWithTransactionLog.HardFlush();
                }
                _fileWithTransactionLog.Truncate();
            }
            lock (_writeLock)
            {
                _writingTransaction = null;
                _lastCommited       = btreeRoot;
                TryDequeWaiterForWrittingTransaction();
            }
        }
Example #30
0
        internal void FastStartCleanUp()
        {
            if (_keyValueDB.FileCollection.GetCount() == 0)
            {
                return;
            }
            _root = _keyValueDB.LastCommited;
            var dontTouchGeneration = _keyValueDB.GetGeneration(_root.TrLogFileId);

            InitFileStats(dontTouchGeneration);
            CalculateFileUsefullness();
            var toRemoveFileIds = new List <uint>();

            for (var i = 0; i < _fileStats.Length; i++)
            {
                if (_fileStats[i].Useless())
                {
                    toRemoveFileIds.Add((uint)i);
                }
            }
            _keyValueDB.MarkAsUnknown(toRemoveFileIds);
        }
Example #31
0
 internal void RevertWrittingTransaction(bool nothingWrittenToTransactionLog)
 {
     if (!nothingWrittenToTransactionLog)
     {
         _writerWithTransactionLog.WriteUInt8((byte)KVCommandType.Rollback);
         var newRoot = _lastCommited.CloneRoot();
         UpdateTransactionLogInBTreeRoot(newRoot);
         lock (_writeLock)
         {
             _writingTransaction = null;
             _lastCommited       = newRoot;
             TryDequeWaiterForWrittingTransaction();
         }
     }
     else
     {
         lock (_writeLock)
         {
             _writingTransaction = null;
             TryDequeWaiterForWrittingTransaction();
         }
     }
 }
Example #32
0
        public void Commit()
        {
            if (BtreeRoot == null)
            {
                throw new BTDBException("Transaction already commited or disposed");
            }
            InvalidateCurrentKey();
            var currentBtreeRoot = _btreeRoot;

            _keyValueDB.FinishedUsingBTreeRoot(_btreeRoot);
            _btreeRoot = null;
            GC.SuppressFinalize(this);
            if (_preapprovedWritting)
            {
                _preapprovedWritting = false;
                _keyValueDB.RevertWrittingTransaction(true);
            }
            else if (_writting)
            {
                _keyValueDB.CommitWrittingTransaction(currentBtreeRoot, _temporaryCloseTransactionLog);
                _writting = false;
            }
        }
Example #33
0
 public KeyValueDB(IFileCollection fileCollection, ICompressionStrategy compression, uint fileSplitSize, ICompactorScheduler compactorScheduler)
 {
     if (fileCollection == null)
     {
         throw new ArgumentNullException(nameof(fileCollection));
     }
     if (compression == null)
     {
         throw new ArgumentNullException(nameof(compression));
     }
     if (fileSplitSize < 1024 || fileSplitSize > int.MaxValue)
     {
         throw new ArgumentOutOfRangeException(nameof(fileSplitSize), "Allowed range 1024 - 2G");
     }
     _compactorScheduler = compactorScheduler;
     MaxTrLogFileSize    = fileSplitSize;
     _compression        = compression;
     DurableTransactions = false;
     _fileCollection     = new FileCollectionWithFileInfos(fileCollection);
     _lastCommited       = new BTreeRoot(0);
     LoadInfoAboutFiles();
     _compactFunc = _compactorScheduler?.AddCompactAction(Compact);
     _compactorScheduler?.AdviceRunning();
 }
Example #34
0
 internal IBTreeRootNode MakeWrittableTransaction(InMemoryKeyValueDBTransaction keyValueDBTransaction, IBTreeRootNode btreeRoot)
 {
     lock (_writeLock)
     {
         if (_writingTransaction != null)
         {
             throw new BTDBTransactionRetryException("Another writting transaction already running");
         }
         if (LastCommited != btreeRoot)
         {
             throw new BTDBTransactionRetryException("Another writting transaction already finished");
         }
         _writingTransaction = keyValueDBTransaction;
         return(btreeRoot.NewTransactionRoot());
     }
 }
Example #35
0
 public InMemoryKeyValueDB()
 {
     _lastCommited = new BTreeRoot(0);
 }
Example #36
0
 public InMemoryKeyValueDB()
 {
     _lastCommited = new BTreeRoot(0);
 }
Example #37
0
 public void Dispose()
 {
     if (_writting || _preapprovedWritting)
     {
         _keyValueDB.RevertWrittingTransaction(_preapprovedWritting);
         _writting = false;
         _preapprovedWritting = false;
     }
     if (_btreeRoot == null) return;
     _keyValueDB.FinishedUsingBTreeRoot(_btreeRoot);
     _btreeRoot = null;
 }
Example #38
0
        internal bool Run()
        {
            if (_keyValueDB.FileCollection.GetCount() == 0)
            {
                return(false);
            }
            _root = _keyValueDB.OldestRoot;
            var dontTouchGeneration = _keyValueDB.GetGeneration(_root.TrLogFileId);

            InitFileStats(dontTouchGeneration);
            CalculateFileUsefullness();
            MarkTotallyUselessFilesAsUnknown();
            var totalWaste = CalcTotalWaste();

            _keyValueDB.Logger?.CompactionStart(totalWaste);
            if (IsWasteSmall(totalWaste))
            {
                if (_keyValueDB.DistanceFromLastKeyIndex(_root) > (ulong)(_keyValueDB.MaxTrLogFileSize / 4))
                {
                    _keyValueDB.CreateIndexFile(_cancellation);
                }
                _keyValueDB.FileCollection.DeleteAllUnknownFiles();
                return(false);
            }
            _cancellation.ThrowIfCancellationRequested();
            uint valueFileId;
            var  writer          = _keyValueDB.StartPureValuesFile(out valueFileId);
            var  toRemoveFileIds = new List <uint>();

            _newPositionMap = new Dictionary <ulong, uint>();
            while (true)
            {
                var wastefullFileId = FindMostWastefullFile(_keyValueDB.MaxTrLogFileSize - writer.GetCurrentPosition());
                if (wastefullFileId == 0)
                {
                    break;
                }
                MoveValuesContent(writer, wastefullFileId);
                _fileStats[wastefullFileId] = new FileStat(0);
                toRemoveFileIds.Add(wastefullFileId);
            }
            var valueFile = _keyValueDB.FileCollection.GetFile(valueFileId);

            valueFile.HardFlush();
            valueFile.Truncate();
            _keyValueDB.Logger?.CompactionCreatedPureValueFile(valueFileId, valueFile.GetSize());
            var btreesCorrectInTransactionId = _keyValueDB.AtomicallyChangeBTree(root => root.RemappingIterate((uint oldFileId, uint oldOffset, out uint newFileId, out uint newOffset) =>
            {
                newFileId = valueFileId;
                _cancellation.ThrowIfCancellationRequested();
                return(_newPositionMap.TryGetValue(((ulong)oldFileId << 32) | oldOffset, out newOffset));
            }));

            _keyValueDB.CreateIndexFile(_cancellation);
            if (_newPositionMap.Count == 0)
            {
                toRemoveFileIds.Add(valueFileId);
            }
            if (_keyValueDB.AreAllTransactionsBeforeFinished(btreesCorrectInTransactionId))
            {
                _keyValueDB.MarkAsUnknown(toRemoveFileIds);
            }
            _keyValueDB.FileCollection.DeleteAllUnknownFiles();
            return(true);
        }
 void MakeWrittable()
 {
     if (_writting) return;
     if (_preapprovedWritting)
     {
         _writting = true;
         _preapprovedWritting = false;
         return;
     }
     if (_readOnly)
     {
         throw new BTDBTransactionRetryException("Cannot write from readOnly transaction");
     }
     var oldBTreeRoot = BtreeRoot;
     _btreeRoot = _keyValueDB.MakeWrittableTransaction(this, oldBTreeRoot);
     _writting = true;
     InvalidateCurrentKey();
 }
 public void Dispose()
 {
     if (_writting || _preapprovedWritting)
     {
         _keyValueDB.RevertWrittingTransaction();
         _writting = false;
         _preapprovedWritting = false;
     }
     _btreeRoot = null;
 }