internal void UpgradeTransactionToWriteOne(KeyValueDBTransaction transaction, ReadTrLink link) { lock (_readLinkLock) { if (link == null && _writeTrInCreation) { _writeTrInCreation = false; } else { if (_writeTr != null || _writeTrInCreation) throw new BTDBTransactionRetryException("Write transaction already running"); if (link.TransactionNumber != _currentState.TransactionCounter) throw new BTDBTransactionRetryException("Newer write transaction already finished"); } _writeTr = transaction; _currentTrCommited = false; _commitNeeded = false; _newState.TransactionCounter++; _unallocatedCounter = 0; Debug.Assert(_unallocatedSectorHeadLink == null); Debug.Assert(_unallocatedSectorTailLink == null); Debug.Assert(_dirtySectorHeadLink == null); Debug.Assert(_dirtySectorTailLink == null); Debug.Assert(_inTransactionSectorHeadLink == null); Debug.Assert(_inTransactionSectorTailLink == null); Debug.Assert(_spaceAllocatedInTransaction.Empty); Debug.Assert(_spaceDeallocatedInTransaction.Empty); } }
internal void DisposeReadTransaction(ReadTrLink link) { DereferenceReadLink(link); }
public IKeyValueDBTransaction StartTransaction() { ReadTrLink link; lock (_readLinkLock) { if (_readTrLinkHead == null || _readTrLinkHead.TransactionNumber != _currentState.TransactionCounter) { link = new ReadTrLink { TransactionNumber = _currentState.TransactionCounter, ReadTrRunningCount = 1, RootBTree = _currentState.RootBTree, KeyValuePairCount = _currentState.KeyValuePairCount, UsedSize = _currentState.UsedSize, WantedDatabaseLength = _currentState.WantedDatabaseLength }; if (_readTrLinkHead != null) { _readTrLinkHead.Next = link; } else { _readTrLinkTail = link; } _readTrLinkHead = link; } else { link = _readTrLinkHead; link.ReadTrRunningCount++; } } try { return new KeyValueDBTransaction(this, link); } catch (Exception) { DereferenceReadLink(link); throw; } }
internal KeyValueDBStats CalculateStats(ReadTrLink readLink) { var result = new KeyValueDBStats { DatabaseStreamSize = _positionLessStream.GetSize(), TotalBytesRead = (ulong)_totalBytesRead, TotalBytesWritten = _totalBytesWritten }; if (readLink != null) { result.TransactionNumber = readLink.TransactionNumber; result.KeyValuePairCount = readLink.KeyValuePairCount; result.ReallyUsedSize = readLink.UsedSize; result.WastedSize = readLink.WantedDatabaseLength - readLink.UsedSize; } else { result.TransactionNumber = _newState.TransactionCounter; result.KeyValuePairCount = _newState.KeyValuePairCount; result.ReallyUsedSize = _newState.UsedSize; result.WastedSize = _newState.WantedDatabaseLength - _newState.UsedSize; } return result; }
private void DereferenceReadLink(ReadTrLink link) { lock (_readLinkLock) { link.ReadTrRunningCount--; if (link != _readTrLinkTail) return; while (true) { if (link.ReadTrRunningCount > 0) return; if (link.SpaceToReuse != null) { lock (_spaceSoonReusableLock) { if (_spaceSoonReusable == null) _spaceSoonReusable = link.SpaceToReuse; else { _spaceSoonReusable.MergeInPlace(link.SpaceToReuse); } } } _readTrLinkTail = link.Next; if (_readTrLinkHead == link) { _readTrLinkHead = null; return; } link = _readTrLinkTail; } } }