private EncryptionBuffer GetBufferAndAddToTxState(long pageNumber, CryptoTransactionState state, int size) { var ptr = _encryptionBuffersPool.Get(size, out var thread); var buffer = new EncryptionBuffer { Size = size, Pointer = ptr, AllocatingThread = thread }; state.LoadedBuffers[pageNumber] = buffer; return(buffer); }
private void ReturnBuffer(EncryptionBuffer buffer) { if (buffer.OriginalSize != null && buffer.OriginalSize != 0) { // First page of a separated section, returned with its original size. _encryptionBuffersPool.Return(buffer.Pointer, (int)buffer.OriginalSize, buffer.AllocatingThread); _encryptionBuffersPool.Return(buffer.Hash, EncryptionBuffer.HashSizeInt, buffer.AllocatingThread); } else { // Normal buffers _encryptionBuffersPool.Return(buffer.Pointer, buffer.Size, buffer.AllocatingThread); _encryptionBuffersPool.Return(buffer.Hash, EncryptionBuffer.HashSizeInt, buffer.AllocatingThread); } }
public override void BreakLargeAllocationToSeparatePages(IPagerLevelTransactionState tx, long pageNumber) { if (tx == null) { throw new NotSupportedException("Cannot use crypto pager without a transaction"); } var state = GetTransactionState(tx); if (state.LoadedBuffers.TryGetValue(pageNumber, out var encBuffer) == false) { throw new InvalidOperationException("Tried to break buffer that wasn't allocated in this tx"); } for (int i = 1; i < encBuffer.Size / Constants.Storage.PageSize; i++) { var buffer = new EncryptionBuffer { Pointer = encBuffer.Pointer + i * Constants.Storage.PageSize, Size = Constants.Storage.PageSize, OriginalSize = 0, }; buffer.Hash = _encryptionBuffersPool.Get(EncryptionBuffer.HashSizeInt, out var thread); buffer.AllocatingThread = thread; // here we _intentionally_ copy the old hash from the large page, so when we commit // the tx, the pager will realize that we need to write this page Memory.Copy(buffer.Hash, encBuffer.Hash, EncryptionBuffer.HashSizeInt); state.LoadedBuffers[pageNumber + i] = buffer; } encBuffer.OriginalSize = encBuffer.Size; encBuffer.Size = Constants.Storage.PageSize; // here we _intentionally_ don't modify the hash of the page, even though its size was // changed, because we need the pager to recognize that it was modified on tx commit // encBuffer.Hash = remains the same }