Ejemplo n.º 1
0
                Buffer(uint blockMetadataSize, uint maxBlockSize, long streamLocation, long opNumber, Guid StreamId)
                {
                    this._AllocationReportedToGC = maxBlockSize + (uint)KLogicalLogInformation.FixedMetadataSize;
                    AddGCMemoryPressure(this._AllocationReportedToGC);

                    this._MetadataSize = blockMetadataSize;
                    NativeLog.CreateSimpleKIoBuffer((uint)KLogicalLogInformation.FixedMetadataSize, out this._MetadataKIoBuffer);

                    //
                    // Allocate the write KIoBuffer to be the full block size requested by the caller despite the fact that some
                    // data will live in the metadata portion. Consider the fact that when the block is completely full, there will be some
                    // amount of data in the metadata and then the data portion will be full as well except for a gap at the end of the block
                    // which is the size of the data in the metadata portion. When rounding up we will need this last block despite it not being
                    // completely full.
                    //
                    NativeLog.CreateSimpleKIoBuffer((uint)(maxBlockSize), out this._PageAlignedKIoBuffer);

                    NativeLog.CreateEmptyKIoBuffer(out this._CombinedKIoBuffer);
                    this._CombinedKIoBuffer.AddIoBufferReference(this._MetadataKIoBuffer, 0, (uint)KLogicalLogInformation.FixedMetadataSize);
                    this._CombinedKIoBuffer.AddIoBufferReference(
                        this._PageAlignedKIoBuffer,
                        0,
                        (uint)(maxBlockSize - KLogicalLogInformation.FixedMetadataSize));

                    this._CombinedBufferStream = new KIoBufferStream(this._CombinedKIoBuffer, (uint)blockMetadataSize);

                    NativeLog.CreateEmptyKIoBuffer(out this._PageAlignedKIoBufferView);

                    unsafe
                    {
                        KLogicalLogInformation.MetadataBlockHeader *mdHdr = null;

                        mdHdr = (KLogicalLogInformation.MetadataBlockHeader *) this._CombinedBufferStream.GetBufferPointer();
                        this._MetadataBlockHeader = mdHdr;
                        ReleaseAssert.AssertIfNot(
                            this._CombinedBufferStream.Skip((uint)sizeof(KLogicalLogInformation.MetadataBlockHeader)),
                            "Unexpected Skip failure");

                        this._StreamBlockHeader     = (KLogicalLogInformation.StreamBlockHeader *) this._CombinedBufferStream.GetBufferPointer();
                        mdHdr->OffsetToStreamHeader = this._CombinedBufferStream.GetPosition();

                        // Position the stream at 1st byte of user record
                        ReleaseAssert.AssertIfNot(
                            this._CombinedBufferStream.Skip((uint)sizeof(KLogicalLogInformation.StreamBlockHeader)),
                            "Unexpected Skip failure");


                        this._StreamBlockHeader->Signature           = KLogicalLogInformation.StreamBlockHeader.Sig;
                        this._StreamBlockHeader->StreamOffsetPlusOne = streamLocation + 1;
                        this._StreamBlockHeader->HighestOperationId  = opNumber;
                        this._StreamBlockHeader->StreamId            = StreamId;

                        this._StreamBlockHeader->HeaderCRC64 = 0;
                        this._StreamBlockHeader->DataCRC64   = 0;
                        this._StreamBlockHeader->DataSize    = 0;
                        this._StreamBlockHeader->Reserved    = 0;

                        this._OffsetToData = mdHdr->OffsetToStreamHeader + (uint)sizeof(KLogicalLogInformation.StreamBlockHeader);
                    }
                }
Ejemplo n.º 2
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);
                }
Ejemplo n.º 3
0
                Dispose(bool IsDisposing)
                {
                    if (IsDisposing)
                    {
                        GC.SuppressFinalize(this);
                        if (this._MetadataKIoBuffer != null)
                        {
                            this._MetadataKIoBuffer.Clear();
                        }

                        if (this._PageAlignedKIoBuffer != null)
                        {
                            this._PageAlignedKIoBuffer.Clear();
                        }

                        if (this._PageAlignedKIoBufferView != null)
                        {
                            this._PageAlignedKIoBufferView.Clear();
                        }

                        if (this._CombinedKIoBuffer != null)
                        {
                            this._CombinedKIoBuffer.Clear();
                        }

                        this._CombinedBufferStream.Reset();

                        unsafe
                        {
                            this._StreamBlockHeader   = null;
                            this._MetadataBlockHeader = null;
                        }
                    }

                    if (this._AllocationReportedToGC > 0)
                    {
                        RemoveGCMemoryPressure(this._AllocationReportedToGC);
                        this._AllocationReportedToGC = 0;
                    }
                }
Ejemplo n.º 4
0
                OpenForRead(long streamPosition, string traceType)
                {
                    // Combine the metadata and page-align IoBuffers
                    uint mdBufferSize;
                    uint paBufferSize;

                    this._MetadataKIoBuffer.QuerySize(out mdBufferSize);
                    this._PageAlignedKIoBuffer.QuerySize(out paBufferSize);

                    this._AllocationReportedToGC = mdBufferSize + paBufferSize;
                    AddGCMemoryPressure(this._AllocationReportedToGC);

                    this._CombinedKIoBuffer.Clear();
                    this._CombinedKIoBuffer.AddIoBufferReference(this._MetadataKIoBuffer, 0, mdBufferSize);
                    this._CombinedKIoBuffer.AddIoBufferReference(this._PageAlignedKIoBuffer, 0, paBufferSize);

                    this._CombinedBufferStream.Reuse(this._CombinedKIoBuffer, this._MetadataSize);

                    // Parse the log stream physical record
                    unsafe
                    {
                        KLogicalLogInformation.MetadataBlockHeader *mdHdr = null;

                        mdHdr = (KLogicalLogInformation.MetadataBlockHeader *) this._CombinedBufferStream.GetBufferPointer();

                        ReleaseAssert.AssertIfNot(
                            this._CombinedBufferStream.PositionTo(mdHdr->OffsetToStreamHeader),
                            "Unexpected PositionTo failure");

                        this._StreamBlockHeader = (KLogicalLogInformation.StreamBlockHeader *) this._CombinedBufferStream.GetBufferPointer();

                        // Position the stream at 1st byte of user record
                        ReleaseAssert.AssertIfNot(
                            this._CombinedBufferStream.Skip((uint)sizeof(KLogicalLogInformation.StreamBlockHeader)),
                            "Unexpected Skip failure");

                        this._OffsetToData = mdHdr->OffsetToStreamHeader + (uint)sizeof(KLogicalLogInformation.StreamBlockHeader);

#if false
                        // TODO: Start: DebugOnly
                        UInt64 savedCrc = _StreamBlockHeader->HeaderCRC64;
                        _StreamBlockHeader->HeaderCRC64 = 0;
                        if (NativeLog.KCrc64(_StreamBlockHeader, (uint)sizeof(KLogicalLogInformation.StreamBlockHeader), 0) != savedCrc)
                        {
                            throw new InvalidDataException();
                        }

                        _StreamBlockHeader->HeaderCRC64 = 0;    // NOTE: Leave HeaderCRC64 0 - this is the unsealed condition

                        if ((_OffsetToData + _StreamBlockHeader->DataSize) > mdBufferSize)
                        {
                            savedCrc = 0;
                            KIoBufferStream.InterationCallback LocalHashFunc = ((
                                                                                    byte *ioBufferFragment,
                                                                                    ref UInt32 fragmentSize) =>
                            {
                                savedCrc = NativeLog.KCrc64(ioBufferFragment, fragmentSize, savedCrc);
                                return(0);
                            });

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

                            if (_StreamBlockHeader->DataCRC64 != savedCrc)
                            {
                                throw new InvalidDataException();
                            }
                        }
                        // TODO: END: DebugOnly
#endif

                        // Compute position and limits of the KIoBufferStream
                        System.Diagnostics.Debug.Assert(this._StreamBlockHeader->StreamOffsetPlusOne > 0);
                        var recordOffsetToDesiredPosition = streamPosition - (this._StreamBlockHeader->StreamOffsetPlusOne - 1);

                        if ((recordOffsetToDesiredPosition < 0) || (recordOffsetToDesiredPosition >= this._StreamBlockHeader->DataSize))
                        {
                            var s =
                                string.Format(
                                    CultureInfo.InvariantCulture,
                                    "OpenForRead: streamPosition {0}, StreamOffsetPlusOne {1}, DataSize {2}, recordOffsetToDesiredPosition {3}, HeadTruncationPoint {4}, HighestOperationId {5} ",
                                    streamPosition,
                                    this._StreamBlockHeader->StreamOffsetPlusOne,
                                    this._StreamBlockHeader->DataSize,
                                    recordOffsetToDesiredPosition,
                                    this._StreamBlockHeader->HeadTruncationPoint,
                                    this._StreamBlockHeader->HighestOperationId);

                            AppTrace.TraceSource.WriteInfo(
                                traceType,
                                s
                                );
                        }

                        System.Diagnostics.Debug.Assert(recordOffsetToDesiredPosition <= uint.MaxValue);
                        this._CombinedBufferStream.Reuse(
                            this._CombinedKIoBuffer,
                            (uint)recordOffsetToDesiredPosition + this._OffsetToData,
                            this._OffsetToData + this._StreamBlockHeader->DataSize);
                    }
                }