Пример #1
0
 public void WriteAsync(IntPtr alignedSourceAddress, ulong alignedDestinationAddress, uint numBytesToWrite, IOCompletionCallback callback, IAsyncResult asyncResult)
 {
     _device.WriteAsync(
         alignedSourceAddress,
         (int)(alignedDestinationAddress >> _segmentSizeBits),
         (ulong)((long)alignedDestinationAddress & _segmentSizeMask),
         numBytesToWrite, callback, asyncResult);
 }
Пример #2
0
        private void WriteAsync <TContext>(IntPtr alignedSourceAddress, ulong alignedDestinationAddress, uint numBytesToWrite,
                                           IOCompletionCallback callback, PageAsyncFlushResult <TContext> asyncResult,
                                           IDevice device, ISegmentedDevice objlogDevice)
        {
            if (!Key.HasObjectsToSerialize() && !Value.HasObjectsToSerialize())
            {
                device.WriteAsync(alignedSourceAddress, alignedDestinationAddress,
                                  numBytesToWrite, callback, asyncResult);
                return;
            }

            // need to write both page and object cache
            asyncResult.count++;
            MemoryStream ms     = new MemoryStream();
            var          buffer = ioBufferPool.Get(PageSize);

            Buffer.MemoryCopy((void *)alignedSourceAddress, buffer.aligned_pointer, numBytesToWrite, numBytesToWrite);

            long        ptr  = (long)buffer.aligned_pointer;
            List <long> addr = new List <long>();

            asyncResult.freeBuffer1 = buffer;

            // Correct for page 0 of HLOG
            if (alignedDestinationAddress >> LogPageSizeBits == 0)
            {
                ptr += Constants.kFirstValidAddress;
            }

            while (ptr < (long)buffer.aligned_pointer + numBytesToWrite)
            {
                if (!Layout.GetInfo(ptr)->Invalid)
                {
                    long pos = ms.Position;

                    Key *key = Layout.GetKey(ptr);
                    Key.Serialize(key, ms);
                    ((AddressInfo *)key)->IsDiskAddress = true;
                    ((AddressInfo *)key)->Address       = pos;
                    ((AddressInfo *)key)->Size          = (int)(ms.Position - pos);
                    addr.Add((long)key);

                    pos = ms.Position;
                    Value *value = Layout.GetValue(ptr);
                    Value.Serialize(value, ms);
                    ((AddressInfo *)value)->IsDiskAddress = true;
                    ((AddressInfo *)value)->Address       = pos;
                    ((AddressInfo *)value)->Size          = (int)(ms.Position - pos);
                    addr.Add((long)value);
                }
                ptr += Layout.GetPhysicalSize(ptr);
            }


            var s         = ms.ToArray();
            var objBuffer = ioBufferPool.Get(s.Length);

            asyncResult.freeBuffer2 = objBuffer;

            var alignedLength = (s.Length + (sectorSize - 1)) & ~(sectorSize - 1);

            var objAddr = Interlocked.Add(ref segmentOffsets[(alignedDestinationAddress >> LogSegmentSizeBits) % SegmentBufferSize], alignedLength) - alignedLength;

            fixed(void *src = s)
            Buffer.MemoryCopy(src, objBuffer.aligned_pointer, s.Length, s.Length);

            foreach (var address in addr)
            {
                *((long *)address) += objAddr;
            }

            objlogDevice.WriteAsync(
                (IntPtr)objBuffer.aligned_pointer,
                (int)(alignedDestinationAddress >> LogSegmentSizeBits),
                (ulong)objAddr, (uint)alignedLength, callback, asyncResult);

            device.WriteAsync((IntPtr)buffer.aligned_pointer, alignedDestinationAddress,
                              numBytesToWrite, callback, asyncResult);
        }