Beispiel #1
0
        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);
        }
Beispiel #2
0
 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);
     }
 }
Beispiel #3
0
        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
        }