Example #1
0
        CopyFrom(
            NativeLog.IKIoBuffer IoBuffer,
            UInt32 SrcOffset,
            UInt32 Size,
            byte *ResultPtr)
        {
            // Compute current source location
            var src = new KIoBufferStream(IoBuffer, SrcOffset);

            // NOTE: ctor will fast path for single element KIoBuffers
            //       and code is inlined here

            if (src._TotalSize < (SrcOffset + Size))
            {
                return(false); // Out of range request
            }

            if (src.GetBufferPointerRange() >= Size)
            {
                // Optimize for moving totally within current element
                Memcopy(src._CurrentElementBufferBase + src._CurrentElementOffset, ResultPtr, Size);
                return(true);
            }

            // Will be crossing element boundary
            return(src.Pull(ResultPtr, Size));
        }
Example #2
0
        CopyTo(
            NativeLog.IKIoBuffer IoBuffer,
            UInt32 DestOffset,
            UInt32 Size,
            byte *SrcPtr)
        {
            // Compute current destination location
            var dest = new KIoBufferStream(IoBuffer, DestOffset);

            // NOTE: ctor will fast path for single element KIoBuffers
            //       and code is inlined here

            if (dest._TotalSize < (DestOffset + Size))
            {
                return(false); // Out of range request
            }

            if (dest.GetBufferPointerRange() >= Size)
            {
                // Optimize for moving totally within current element
                Memcopy(SrcPtr, dest._CurrentElementBufferBase + dest._CurrentElementOffset, Size);
                return(true);
            }

            // Will be crossing element boundary
            return(dest.Put(SrcPtr, Size));
        }
Example #3
0
 CreateReadBuffer(
     uint blockMetadataSize,
     long startingStreamPosition,
     NativeLog.IKIoBuffer metadataBuffer,
     NativeLog.IKIoBuffer pageAlignedKIoBuffer,
     string traceType)
 {
     return(new Buffer(blockMetadataSize, startingStreamPosition, metadataBuffer, pageAlignedKIoBuffer, traceType));
 }
Example #4
0
 WriteAsync(
     KTL_LOG_ASN Asn,
     UInt64 Version,
     UInt32 MetatdataSize,
     NativeLog.IKIoBuffer MetadataBuffer,
     NativeLog.IKIoBuffer IoPageAlignedBuffer,
     CancellationToken Token)
 {
     return(Utility.WrapNativeAsyncInvokeInMTA(
                (Callback) => this.WriteBeginWrapper(Asn, Version, MetatdataSize, MetadataBuffer, IoPageAlignedBuffer, Callback),
                (Context) => this.WriteEndWrapper(Context),
                Token,
                "NativeLog.WriteStream"));
 }
Example #5
0
        WriteBeginWrapper(
            KTL_LOG_ASN Asn,
            UInt64 Version,
            UInt32 MetatdataSize,
            NativeLog.IKIoBuffer MetadataBuffer,
            NativeLog.IKIoBuffer IoPageAlignedBuffer,
            NativeCommon.IFabricAsyncOperationCallback Callback)
        {
            NativeCommon.IFabricAsyncOperationContext context;

            // CONSIDER: Does native code need to AddRef MetadataBuffer and IoPageAlignedBuffer ?

            this._NativeStream.BeginWrite(Asn, Version, MetatdataSize, MetadataBuffer, IoPageAlignedBuffer, Callback, out context);
            return(context);
        }
Example #6
0
                Buffer(
                    uint blockMetadataSize,
                    long startingStreamPosition,
                    NativeLog.IKIoBuffer metadataBuffer,
                    NativeLog.IKIoBuffer pageAlignedKIoBuffer,
                    string traceType)
                {
                    this._MetadataSize         = blockMetadataSize;
                    this._MetadataKIoBuffer    = metadataBuffer;
                    this._PageAlignedKIoBuffer = pageAlignedKIoBuffer;
                    unsafe
                    {
                        this._StreamBlockHeader = null;
                    }
                    this._PageAlignedKIoBufferView = null;
                    this._OffsetToData             = uint.MaxValue;

                    NativeLog.CreateEmptyKIoBuffer(out this._CombinedKIoBuffer);
                    this.OpenForRead(startingStreamPosition, traceType);
                }
Example #7
0
        KIoBufferStream(NativeLog.IKIoBuffer IoBuffer = null, UInt32 InitialOffset = 0, UInt32 TotalSizeLimit = 0)
        {
            this._Buffer                   = null;
            this._ElementsDescArray        = null;
            this._ElementsDescs            = null;
            this._MoveInteratorState       = null;
            this._CurrentElementBufferBase = null;
            this._Position                 = 0;
            this._TotalSize                = 0;
            this._NumberOfElements         = 0;
            this._CurrentElement           = UInt32.MaxValue;
            this._CurrentElementOffset     = 0;
            this._CurrentElementSize       = 0;
            this._IsInitialized            = false;

            if ((IoBuffer != null) && (!this.Reuse(IoBuffer, InitialOffset, TotalSizeLimit)))
            {
                throw new ArgumentOutOfRangeException(SR.Error_InitialOffset);
            }
        }
Example #8
0
        Reuse(NativeLog.IKIoBuffer IoBuffer, UInt32 InitialOffset = 0, UInt32 TotalSizeLimit = 0)
        {
            this._IsInitialized = true;

            IoBuffer.GetElements(out this._NumberOfElements, out this._ElementsDescArray);
            {
                void *arrayBase;
                this._ElementsDescArray.GetArrayBase(out arrayBase);
                this._ElementsDescs = (NativeLog.KIOBUFFER_ELEMENT_DESCRIPTOR *)arrayBase;
            }

            if (this._NumberOfElements == 1)
            {
                // Optimize for single buffer case
                this._Buffer                   = IoBuffer;
                this._CurrentElement           = 0;
                this._CurrentElementOffset     = InitialOffset;
                this._CurrentElementSize       = this._ElementsDescs[0].Size;
                this._CurrentElementBufferBase = this._ElementsDescs[0].ElementBaseAddress;
                this._Position                 = InitialOffset;
                this._TotalSize                = this._CurrentElementSize;
                if (TotalSizeLimit > 0)
                {
                    this._TotalSize          = Math.Min(this._TotalSize, TotalSizeLimit);
                    this._CurrentElementSize = this._TotalSize;
                }
                return(InitialOffset < this._CurrentElementSize);
            }

            this._Buffer = IoBuffer;
            IoBuffer.QuerySize(out this._TotalSize);
            if (TotalSizeLimit > 0)
            {
                this._TotalSize = Math.Min(this._TotalSize, TotalSizeLimit);
            }
            this.InternalClear();
            return(this.PositionTo(InitialOffset));
        }
Example #9
0
                SealForWrite(
                    long currentHeadTruncationPoint,
                    bool IsBarrier,
                    out NativeLog.IKIoBuffer metadataBuffer,
                    out uint metadataSize,
                    out NativeLog.IKIoBuffer pageAlignedBuffer,
                    out long userSizeOfStreamData,
                    out long AsnOfRecord,
                    out long OpOfRecord)
                {
                    unsafe
                    {
                        uint   trimSize = 0;
                        uint   dataResidingOutsideMetadata = 0;
                        UInt64 dataCrc = 0;

                        this._MetadataBlockHeader->Flags = IsBarrier ? (uint)KLogicalLogInformation.MetadatBlockHeaderFlags.IsEndOfLogicalRecord : 0;

                        this._StreamBlockHeader->DataSize            = this._CombinedBufferStream.GetPosition() - this._OffsetToData;
                        this._StreamBlockHeader->HeadTruncationPoint = currentHeadTruncationPoint;
                        this._PageAlignedKIoBufferView.Clear();

                        // Compute CRC64 for record data
                        if ((this._OffsetToData < KLogicalLogInformation.FixedMetadataSize) &&
                            ((this._OffsetToData + this._StreamBlockHeader->DataSize) <= KLogicalLogInformation.FixedMetadataSize))
                        {
                            // no data outside the metadata buffer
                            metadataSize = this._OffsetToData + this._StreamBlockHeader->DataSize;
                        }
                        else
                        {
                            //
                            // Compute how much of the metadata is being used. It should be the entire 4K block minus the
                            // space reserved by the physical logger
                            //
                            metadataSize = (uint)KLogicalLogInformation.FixedMetadataSize - this._MetadataSize;
                            ReleaseAssert.AssertIfNot(this._CombinedBufferStream.PositionTo(this._OffsetToData), "Unexpected PositionTo failure");

                            KIoBufferStream.InterationCallback LocalHashFunc = ((
                                                                                    byte *ioBufferFragment,
                                                                                    ref UInt32 fragmentSize) =>
                            {
                                dataCrc = NativeLog.KCrc64(ioBufferFragment, fragmentSize, dataCrc);
                                return(0);
                            });

                            ReleaseAssert.AssertIfNot(
                                this._CombinedBufferStream.Iterate(LocalHashFunc, this._StreamBlockHeader->DataSize) == 0,
                                "Unexpected Iterate failure");

                            //
                            // Compute the number of data blocks that are needed to hold the data that is within the payload
                            // data buffer. This excludes the payload data in the metadata portion
                            //
                            ReleaseAssert.AssertIf(this._OffsetToData > MetadataBlockSize, "Unexpected size for _OffsetToData");
                            dataResidingOutsideMetadata = this._StreamBlockHeader->DataSize - (MetadataBlockSize - this._OffsetToData);
                            trimSize = ((((dataResidingOutsideMetadata) + (MetadataBlockSize - 1)) / MetadataBlockSize) * MetadataBlockSize);
                            this._PageAlignedKIoBufferView.AddIoBufferReference(
                                this._PageAlignedKIoBuffer,
                                0,
                                (uint)trimSize);
                        }
                        this._StreamBlockHeader->DataCRC64 = dataCrc;

                        // Now compute block header CRC
                        this._StreamBlockHeader->HeaderCRC64 = NativeLog.KCrc64(
                            this._StreamBlockHeader,
                            (uint)sizeof(KLogicalLogInformation.StreamBlockHeader),
                            0);

                        // Build results
                        metadataBuffer       = this._MetadataKIoBuffer;
                        pageAlignedBuffer    = this._PageAlignedKIoBufferView;
                        userSizeOfStreamData = this._StreamBlockHeader->DataSize;
                        AsnOfRecord          = this._StreamBlockHeader->StreamOffsetPlusOne;
                        OpOfRecord           = this._StreamBlockHeader->HighestOperationId;
                    }
                }