public static PropertyChunkMetadata Read(InMemoryBinaryReader reader)
        {
            reader.ThrowIfNotAligned();

            var currentBlockSize = reader.ReadInt32();

            reader.ReadPaddingUntilAligned(true);

            reader.ThrowIfNotAligned();

            return(new PropertyChunkMetadata(currentBlockSize));
        }
        /// <summary>
        /// Read key from file for merge.
        /// </summary>
        /// <remarks>
        /// The data is written is 8 bytes aligned.
        ///
        /// Name                    Type        Size
        ///
        /// KeySize                 int         4
        /// Kind                    byte        1
        /// RESERVED                            3
        /// VersionSequenceNumber   long        8
        ///
        /// (DeletedVersion)
        /// TimeStamp               long        8
        ///
        /// (Inserted || Updated)
        /// Offset                  long        8
        /// ValueChecksum           ulong       8
        /// ValueSize               int         4
        /// RESERVED                            4
        ///
        /// Key                     TKey        N
        /// PADDING                             (N % 8 ==0) ? 0 : 8 - (N % 8)
        ///
        /// RESERVED: Fixed padding that is usable to add fields in future.
        /// PADDING:  Due to dynamic size, cannot be used for adding fields.
        ///
        /// Note: Larges Key size supported is int.MaxValue in bytes.
        /// </remarks>
        public KeyData <TKey, TValue> ReadKey <TKey, TValue>(InMemoryBinaryReader memoryBuffer, IStateSerializer <TKey> keySerializer)
        {
            memoryBuffer.ThrowIfNotAligned();

            // This mirrors WriteKey().
            var keySize = memoryBuffer.ReadInt32();
            var kind    = (RecordKind)memoryBuffer.ReadByte();

            memoryBuffer.ReadPaddingUntilAligned(true);

            var lsn = memoryBuffer.ReadInt64();

            long  valueOffset   = 0;
            var   valueSize     = 0;
            ulong valueChecksum = 0;
            long  TimeStamp     = 0;

            if (kind == RecordKind.DeletedVersion)
            {
                TimeStamp = memoryBuffer.ReadInt64();
            }
            else
            {
                valueOffset   = memoryBuffer.ReadInt64();
                valueChecksum = memoryBuffer.ReadUInt64();
                valueSize     = memoryBuffer.ReadInt32();
                memoryBuffer.ReadPaddingUntilAligned(true);
            }

            // Protection in case the user's key serializer doesn't leave the stream at the correct end point.
            var keyPosition = memoryBuffer.BaseStream.Position;
            var key         = keySerializer.Read(memoryBuffer);

            memoryBuffer.BaseStream.Position = keyPosition + keySize;
            memoryBuffer.ReadPaddingUntilAligned(false);

            TVersionedItem <TValue> value = null;

            switch (kind)
            {
            case RecordKind.DeletedVersion:
                value = new TDeletedItem <TValue>(lsn, this.FileId);
                break;

            case RecordKind.InsertedVersion:
                value = new TInsertedItem <TValue>(lsn, this.FileId, valueOffset, valueSize, valueChecksum);
                break;

            case RecordKind.UpdatedVersion:
                value = new TUpdatedItem <TValue>(lsn, this.FileId, valueOffset, valueSize, valueChecksum);
                break;

            default:
                throw new InvalidDataException(string.Format(CultureInfo.CurrentCulture, SR.Error_KeyCheckpointFile_RecordKind, (byte)kind));
            }

            return(new KeyData <TKey, TValue>(key, value, TimeStamp));
        }