github.com/m3db/m3@v1.5.0/src/dbnode/persist/fs/msgpack/decoder.go (about)

     1  // Copyright (c) 2016 Uber Technologies, Inc
     2  //
     3  // Permission is hereby granted, free of charge, to any person obtaining a copy
     4  // of this software and associated documentation files (the "Software"), to deal
     5  // in the Software without restriction, including without limitation the rights
     6  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     7  // copies of the Software, and to permit persons to whom the Software is
     8  // furnished to do so, subject to the following conditions:
     9  //
    10  // The above copyright notice and this permission notice shall be included in
    11  // all copies or substantial portions of the Software
    12  //
    13  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    14  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    15  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    16  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    17  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    18  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    19  // THE SOFTWARE
    20  
    21  package msgpack
    22  
    23  import (
    24  	"errors"
    25  	"fmt"
    26  	"io"
    27  
    28  	"github.com/m3db/m3/src/dbnode/persist"
    29  	"github.com/m3db/m3/src/dbnode/persist/schema"
    30  	"github.com/m3db/m3/src/x/pool"
    31  
    32  	"gopkg.in/vmihailenco/msgpack.v2"
    33  )
    34  
    35  var (
    36  	emptyIndexInfo              schema.IndexInfo
    37  	emptyIndexSummariesInfo     schema.IndexSummariesInfo
    38  	emptyIndexBloomFilterInfo   schema.IndexBloomFilterInfo
    39  	emptyIndexEntry             schema.IndexEntry
    40  	emptyIndexSummary           schema.IndexSummary
    41  	emptyIndexSummaryToken      IndexSummaryToken
    42  	emptyLogInfo                schema.LogInfo
    43  	emptyLogEntry               schema.LogEntry
    44  	emptyLogMetadata            schema.LogMetadata
    45  	emptyLogEntryRemainingToken DecodeLogEntryRemainingToken
    46  
    47  	errorUnableToDetermineNumFieldsToSkip          = errors.New("unable to determine num fields to skip")
    48  	errorCalledDecodeBytesWithoutByteStreamDecoder = errors.New("called decodeBytes without byte stream decoder")
    49  	errorIndexEntryChecksumMismatch                = errors.New("decode index entry encountered checksum mismatch")
    50  )
    51  
    52  // Decoder decodes persisted msgpack-encoded data
    53  type Decoder struct {
    54  	reader DecoderStream
    55  	// Will only be set if the Decoder is Reset() with a DecoderStream
    56  	// that also implements ByteStream.
    57  	byteReader ByteStream
    58  	// Wraps original reader with reader that can calculate digest. Digest calculation must be enabled,
    59  	// otherwise it defaults to off.
    60  	readerWithDigest  *decoderStreamWithDigest
    61  	hasher            schema.IndexEntryHasher
    62  	dec               *msgpack.Decoder
    63  	err               error
    64  	allocDecodedBytes bool
    65  
    66  	legacy LegacyEncodingOptions
    67  }
    68  
    69  // NewDecoder creates a new decoder
    70  func NewDecoder(opts DecodingOptions) *Decoder {
    71  	return newDecoder(DefaultLegacyEncodingOptions, opts)
    72  }
    73  
    74  func newDecoder(legacy LegacyEncodingOptions, opts DecodingOptions) *Decoder {
    75  	if opts == nil {
    76  		opts = NewDecodingOptions()
    77  	}
    78  	reader := NewByteDecoderStream(nil)
    79  	return &Decoder{
    80  		allocDecodedBytes: opts.AllocDecodedBytes(),
    81  		reader:            reader,
    82  		dec:               msgpack.NewDecoder(reader),
    83  		legacy:            legacy,
    84  		hasher:            opts.IndexEntryHasher(),
    85  		readerWithDigest:  newDecoderStreamWithDigest(nil),
    86  	}
    87  }
    88  
    89  // Reset resets the data stream to decode from
    90  func (dec *Decoder) Reset(stream DecoderStream) {
    91  	dec.reader = stream
    92  
    93  	// Do the type assertion upfront so that we don't have to do it
    94  	// repeatedly later.
    95  	if byteStream, ok := stream.(ByteStream); ok {
    96  		dec.byteReader = byteStream
    97  	} else {
    98  		dec.byteReader = nil
    99  	}
   100  
   101  	dec.readerWithDigest.reset(dec.reader)
   102  	dec.dec.Reset(dec.readerWithDigest)
   103  	dec.err = nil
   104  }
   105  
   106  // DecodeIndexInfo decodes the index info
   107  func (dec *Decoder) DecodeIndexInfo() (schema.IndexInfo, error) {
   108  	if dec.err != nil {
   109  		return emptyIndexInfo, dec.err
   110  	}
   111  
   112  	_, numFieldsToSkip := dec.decodeRootObject(indexInfoVersion, indexInfoType)
   113  	indexInfo := dec.decodeIndexInfo()
   114  	dec.skip(numFieldsToSkip)
   115  	if dec.err != nil {
   116  		return emptyIndexInfo, dec.err
   117  	}
   118  	return indexInfo, nil
   119  }
   120  
   121  // DecodeIndexEntry decodes index entry.
   122  func (dec *Decoder) DecodeIndexEntry(bytesPool pool.BytesPool) (schema.IndexEntry, error) {
   123  	if dec.err != nil {
   124  		return emptyIndexEntry, dec.err
   125  	}
   126  	dec.readerWithDigest.setDigestReaderEnabled(true)
   127  	_, numFieldsToSkip := dec.decodeRootObject(indexEntryVersion, indexEntryType)
   128  	indexEntry := dec.decodeIndexEntry(bytesPool)
   129  	dec.readerWithDigest.setDigestReaderEnabled(false)
   130  	dec.skip(numFieldsToSkip)
   131  	if dec.err != nil {
   132  		return emptyIndexEntry, dec.err
   133  	}
   134  	return indexEntry, nil
   135  }
   136  
   137  // DecodeIndexSummary decodes index summary.
   138  func (dec *Decoder) DecodeIndexSummary() (
   139  	schema.IndexSummary, IndexSummaryToken, error) {
   140  	if dec.err != nil {
   141  		return emptyIndexSummary, emptyIndexSummaryToken, dec.err
   142  	}
   143  	_, numFieldsToSkip := dec.decodeRootObject(indexSummaryVersion, indexSummaryType)
   144  	indexSummary, indexSummaryMetadata := dec.decodeIndexSummary()
   145  	dec.skip(numFieldsToSkip)
   146  	if dec.err != nil {
   147  		return emptyIndexSummary, emptyIndexSummaryToken, dec.err
   148  	}
   149  	return indexSummary, indexSummaryMetadata, nil
   150  }
   151  
   152  // DecodeLogInfo decodes commit log info.
   153  func (dec *Decoder) DecodeLogInfo() (schema.LogInfo, error) {
   154  	if dec.err != nil {
   155  		return emptyLogInfo, dec.err
   156  	}
   157  	_, numFieldsToSkip := dec.decodeRootObject(logInfoVersion, logInfoType)
   158  	logInfo := dec.decodeLogInfo()
   159  	dec.skip(numFieldsToSkip)
   160  	if dec.err != nil {
   161  		return emptyLogInfo, dec.err
   162  	}
   163  	return logInfo, nil
   164  }
   165  
   166  // DecodeLogEntry decodes commit log entry.
   167  func (dec *Decoder) DecodeLogEntry() (schema.LogEntry, error) {
   168  	if dec.err != nil {
   169  		return emptyLogEntry, dec.err
   170  	}
   171  	_, numFieldsToSkip := dec.decodeRootObject(logEntryVersion, logEntryType)
   172  	logEntry := dec.decodeLogEntry()
   173  	dec.skip(numFieldsToSkip)
   174  	if dec.err != nil {
   175  		return emptyLogEntry, dec.err
   176  	}
   177  	return logEntry, nil
   178  }
   179  
   180  // DecodeLogEntryRemainingToken contains all the information that DecodeLogEntryRemaining
   181  // requires to continue decoding a log entry after a call to DecodeLogEntryUniqueIndex.
   182  type DecodeLogEntryRemainingToken struct {
   183  	numFieldsToSkip1 int
   184  	numFieldsToSkip2 int
   185  }
   186  
   187  // DecodeLogEntryUniqueIndex decodes a log entry as much as is required to return
   188  // the series unique index. Call DecodeLogEntryRemaining afterwards to decode the
   189  // remaining fields.
   190  func (dec *Decoder) DecodeLogEntryUniqueIndex() (DecodeLogEntryRemainingToken, uint64, error) {
   191  	if dec.err != nil {
   192  		return emptyLogEntryRemainingToken, 0, dec.err
   193  	}
   194  
   195  	_, numFieldsToSkip1 := dec.decodeRootObject(logEntryVersion, logEntryType)
   196  	numFieldsToSkip2, _, ok := dec.checkNumFieldsFor(logEntryType, checkNumFieldsOptions{})
   197  	if !ok {
   198  		return emptyLogEntryRemainingToken, 0, errorUnableToDetermineNumFieldsToSkip
   199  	}
   200  	idx := dec.decodeVarUint()
   201  
   202  	token := DecodeLogEntryRemainingToken{
   203  		numFieldsToSkip1: numFieldsToSkip1,
   204  		numFieldsToSkip2: numFieldsToSkip2,
   205  	}
   206  	return token, idx, nil
   207  }
   208  
   209  // DecodeLogEntryRemaining can only be called after DecodeLogEntryUniqueIndex,
   210  // and it returns a complete schema.LogEntry.
   211  func (dec *Decoder) DecodeLogEntryRemaining(token DecodeLogEntryRemainingToken, index uint64) (schema.LogEntry, error) {
   212  	if dec.err != nil {
   213  		return emptyLogEntry, dec.err
   214  	}
   215  
   216  	var logEntry schema.LogEntry
   217  	logEntry.Index = index
   218  	logEntry.Create = dec.decodeVarint()
   219  	logEntry.Metadata, _, _ = dec.decodeBytes()
   220  	logEntry.Timestamp = dec.decodeVarint()
   221  	logEntry.Value = dec.decodeFloat64()
   222  	logEntry.Unit = uint32(dec.decodeVarUint())
   223  	logEntry.Annotation, _, _ = dec.decodeBytes()
   224  
   225  	dec.skip(token.numFieldsToSkip1)
   226  	if dec.err != nil {
   227  		return emptyLogEntry, dec.err
   228  	}
   229  	dec.skip(token.numFieldsToSkip2)
   230  	if dec.err != nil {
   231  		return emptyLogEntry, dec.err
   232  	}
   233  
   234  	return logEntry, nil
   235  }
   236  
   237  // DecodeLogMetadata decodes commit log metadata.
   238  func (dec *Decoder) DecodeLogMetadata() (schema.LogMetadata, error) {
   239  	if dec.err != nil {
   240  		return emptyLogMetadata, dec.err
   241  	}
   242  	_, numFieldsToSkip := dec.decodeRootObject(logMetadataVersion, logMetadataType)
   243  	logMetadata := dec.decodeLogMetadata()
   244  	dec.skip(numFieldsToSkip)
   245  	if dec.err != nil {
   246  		return emptyLogMetadata, dec.err
   247  	}
   248  	return logMetadata, nil
   249  }
   250  
   251  func (dec *Decoder) decodeIndexInfo() schema.IndexInfo {
   252  	var opts checkNumFieldsOptions
   253  
   254  	// Overrides only used to test forwards compatibility.
   255  	switch dec.legacy.DecodeLegacyIndexInfoVersion {
   256  	case LegacyEncodingIndexVersionV1:
   257  		// V1 had 6 fields.
   258  		opts.override = true
   259  		opts.numExpectedMinFields = 6
   260  		opts.numExpectedCurrFields = 6
   261  	case LegacyEncodingIndexVersionV2:
   262  		// V2 had 8 fields.
   263  		opts.override = true
   264  		opts.numExpectedMinFields = 6
   265  		opts.numExpectedCurrFields = 8
   266  	case LegacyEncodingIndexVersionV3:
   267  		// V3 had 9 fields.
   268  		opts.override = true
   269  		opts.numExpectedMinFields = 6
   270  		opts.numExpectedCurrFields = 9
   271  	case LegacyEncodingIndexVersionV4:
   272  		// V4 had 10 fields.
   273  		opts.override = true
   274  		opts.numExpectedMinFields = 6
   275  		opts.numExpectedCurrFields = 10
   276  	}
   277  
   278  	numFieldsToSkip, actual, ok := dec.checkNumFieldsFor(indexInfoType, opts)
   279  	if !ok {
   280  		return emptyIndexInfo
   281  	}
   282  
   283  	var indexInfo schema.IndexInfo
   284  	indexInfo.BlockStart = dec.decodeVarint()
   285  	indexInfo.BlockSize = dec.decodeVarint()
   286  	indexInfo.Entries = dec.decodeVarint()
   287  	indexInfo.MajorVersion = dec.decodeVarint()
   288  	indexInfo.Summaries = dec.decodeIndexSummariesInfo()
   289  	indexInfo.BloomFilter = dec.decodeIndexBloomFilterInfo()
   290  
   291  	// At this point if its a V1 file we've decoded all the available fields.
   292  	if dec.legacy.DecodeLegacyIndexInfoVersion == LegacyEncodingIndexVersionV1 || actual < 8 {
   293  		dec.skip(numFieldsToSkip)
   294  		return indexInfo
   295  	}
   296  
   297  	// Decode fields added in V2.
   298  	indexInfo.SnapshotTime = dec.decodeVarint()
   299  	indexInfo.FileType = persist.FileSetType(dec.decodeVarint())
   300  
   301  	// At this point if its a V2 file we've decoded all the available fields.
   302  	if dec.legacy.DecodeLegacyIndexInfoVersion == LegacyEncodingIndexVersionV2 || actual < 9 {
   303  		dec.skip(numFieldsToSkip)
   304  		return indexInfo
   305  	}
   306  
   307  	// Decode fields added in V3.
   308  	indexInfo.SnapshotID, _, _ = dec.decodeBytes()
   309  
   310  	// At this point if its a V3 file we've decoded all the available fields.
   311  	if dec.legacy.DecodeLegacyIndexInfoVersion == LegacyEncodingIndexVersionV3 || actual < 10 {
   312  		dec.skip(numFieldsToSkip)
   313  		return indexInfo
   314  	}
   315  
   316  	// Decode fields added in V4.
   317  	indexInfo.VolumeIndex = int(dec.decodeVarint())
   318  
   319  	// At this point if its a V4 file we've decoded all the available fields.
   320  	if dec.legacy.DecodeLegacyIndexInfoVersion == LegacyEncodingIndexVersionV4 || actual < 11 {
   321  		dec.skip(numFieldsToSkip)
   322  		return indexInfo
   323  	}
   324  
   325  	// Decode fields added in V5.
   326  	indexInfo.MinorVersion = dec.decodeVarint()
   327  
   328  	dec.skip(numFieldsToSkip)
   329  	return indexInfo
   330  }
   331  
   332  func (dec *Decoder) decodeIndexSummariesInfo() schema.IndexSummariesInfo {
   333  	numFieldsToSkip, _, ok := dec.checkNumFieldsFor(indexSummariesInfoType, checkNumFieldsOptions{})
   334  	if !ok {
   335  		return emptyIndexSummariesInfo
   336  	}
   337  	var indexSummariesInfo schema.IndexSummariesInfo
   338  	indexSummariesInfo.Summaries = dec.decodeVarint()
   339  	dec.skip(numFieldsToSkip)
   340  	if dec.err != nil {
   341  		return emptyIndexSummariesInfo
   342  	}
   343  	return indexSummariesInfo
   344  }
   345  
   346  func (dec *Decoder) decodeIndexBloomFilterInfo() schema.IndexBloomFilterInfo {
   347  	numFieldsToSkip, _, ok := dec.checkNumFieldsFor(indexBloomFilterInfoType, checkNumFieldsOptions{})
   348  	if !ok {
   349  		return emptyIndexBloomFilterInfo
   350  	}
   351  	var indexBloomFilterInfo schema.IndexBloomFilterInfo
   352  	indexBloomFilterInfo.NumElementsM = dec.decodeVarint()
   353  	indexBloomFilterInfo.NumHashesK = dec.decodeVarint()
   354  	dec.skip(numFieldsToSkip)
   355  	if dec.err != nil {
   356  		return emptyIndexBloomFilterInfo
   357  	}
   358  	return indexBloomFilterInfo
   359  }
   360  
   361  func (dec *Decoder) checkNumIndexEntryFields() (int, int, bool) {
   362  	var opts checkNumFieldsOptions
   363  	switch dec.legacy.DecodeLegacyIndexEntryVersion {
   364  	case LegacyEncodingIndexEntryVersionV1:
   365  		// V1 had 5 fields.
   366  		opts.override = true
   367  		opts.numExpectedMinFields = 5
   368  		opts.numExpectedCurrFields = 5
   369  	case LegacyEncodingIndexEntryVersionV2:
   370  		// V2 had 6 fields.
   371  		opts.override = true
   372  		opts.numExpectedMinFields = 5
   373  		opts.numExpectedCurrFields = 6
   374  	case LegacyEncodingIndexEntryVersionCurrent:
   375  		// V3 is current version, no overrides needed
   376  		break
   377  	default:
   378  		dec.err = fmt.Errorf("invalid legacyEncodingIndexEntryVersion provided: %v",
   379  			dec.legacy.DecodeLegacyIndexEntryVersion)
   380  		return 0, 0, false
   381  	}
   382  
   383  	return dec.checkNumFieldsFor(indexEntryType, opts)
   384  }
   385  
   386  func (dec *Decoder) decodeIndexEntry(bytesPool pool.BytesPool) schema.IndexEntry {
   387  	numFieldsToSkip, actual, ok := dec.checkNumIndexEntryFields()
   388  	if !ok {
   389  		return emptyIndexEntry
   390  	}
   391  
   392  	var indexEntry schema.IndexEntry
   393  	indexEntry.Index = dec.decodeVarint()
   394  
   395  	if bytesPool == nil {
   396  		indexEntry.ID, _, _ = dec.decodeBytes()
   397  	} else {
   398  		indexEntry.ID = dec.decodeBytesWithPool(bytesPool)
   399  	}
   400  
   401  	indexEntry.Size = dec.decodeVarint()
   402  	indexEntry.Offset = dec.decodeVarint()
   403  	indexEntry.DataChecksum = dec.decodeVarint()
   404  
   405  	// At this point, if its a V1 file, we've decoded all the available fields.
   406  	if dec.legacy.DecodeLegacyIndexEntryVersion == LegacyEncodingIndexEntryVersionV1 || actual < 6 {
   407  		dec.skip(numFieldsToSkip)
   408  		return indexEntry
   409  	}
   410  
   411  	// Decode fields added in V2
   412  	if bytesPool == nil {
   413  		indexEntry.EncodedTags, _, _ = dec.decodeBytes()
   414  	} else {
   415  		indexEntry.EncodedTags = dec.decodeBytesWithPool(bytesPool)
   416  	}
   417  
   418  	// At this point, if its a V2 file, we've decoded all the available fields.
   419  	if dec.legacy.DecodeLegacyIndexEntryVersion == LegacyEncodingIndexEntryVersionV2 || actual < 7 {
   420  		dec.skip(numFieldsToSkip)
   421  		return indexEntry
   422  	}
   423  
   424  	// NB(nate): Any new fields should be parsed here.
   425  
   426  	// Intentionally skip any extra fields here as we've stipulated that from V3 onward, IndexEntryChecksum will be the
   427  	// final field on index entries
   428  	dec.skip(numFieldsToSkip)
   429  
   430  	// Retrieve actual checksum value here. Attempting to retrieve after decoding the upcoming expected checksum field
   431  	// would include value in actual checksum calculation which would cause a mismatch
   432  	actualChecksum := dec.readerWithDigest.digest().Sum32()
   433  
   434  	// Decode checksum field originally added in V3
   435  	indexEntry.IndexChecksum = dec.decodeVarint()
   436  	if dec.err != nil {
   437  		dec.err = fmt.Errorf("decode index entry encountered error: %s", dec.err)
   438  		return emptyIndexEntry
   439  	}
   440  
   441  	if indexEntry.IndexChecksum != int64(actualChecksum) {
   442  		dec.err = errorIndexEntryChecksumMismatch
   443  	}
   444  
   445  	return indexEntry
   446  }
   447  
   448  func (dec *Decoder) decodeIndexSummary() (schema.IndexSummary, IndexSummaryToken) {
   449  	numFieldsToSkip, _, ok := dec.checkNumFieldsFor(indexSummaryType, checkNumFieldsOptions{})
   450  	if !ok {
   451  		return emptyIndexSummary, emptyIndexSummaryToken
   452  	}
   453  	var (
   454  		indexSummary       schema.IndexSummary
   455  		idBytesStartOffset int
   456  		idBytesLength      int
   457  	)
   458  	indexSummary.Index = dec.decodeVarint()
   459  	// Keep track of the offset in the byte stream before we decode the bytes so
   460  	// that we know exactly where to jump to if we want to just grab the ID itself
   461  	indexSummary.ID, idBytesStartOffset, idBytesLength = dec.decodeBytes()
   462  	indexSummary.IndexEntryOffset = dec.decodeVarint()
   463  	dec.skip(numFieldsToSkip)
   464  	if dec.err != nil {
   465  		return emptyIndexSummary, emptyIndexSummaryToken
   466  	}
   467  
   468  	// Downscaling to uint32 is fine because summary files and ID length should
   469  	// be well below the max value of a uint32
   470  	indexSummaryToken := NewIndexSummaryToken(
   471  		uint32(idBytesStartOffset), uint32(idBytesLength),
   472  	)
   473  	return indexSummary, indexSummaryToken
   474  }
   475  
   476  func (dec *Decoder) decodeLogInfo() schema.LogInfo {
   477  	numFieldsToSkip, _, ok := dec.checkNumFieldsFor(logInfoType, checkNumFieldsOptions{})
   478  	if !ok {
   479  		return emptyLogInfo
   480  	}
   481  	var logInfo schema.LogInfo
   482  
   483  	// Deprecated, have to decode anyways for backwards compatibility, but we ignore the values.
   484  	logInfo.DeprecatedDoNotUseStart = dec.decodeVarint()
   485  	logInfo.DeprecatedDoNotUseDuration = dec.decodeVarint()
   486  
   487  	logInfo.Index = dec.decodeVarint()
   488  	dec.skip(numFieldsToSkip)
   489  	if dec.err != nil {
   490  		return emptyLogInfo
   491  	}
   492  	return logInfo
   493  }
   494  
   495  func (dec *Decoder) decodeLogEntry() schema.LogEntry {
   496  	numFieldsToSkip, _, ok := dec.checkNumFieldsFor(logEntryType, checkNumFieldsOptions{})
   497  	if !ok {
   498  		return emptyLogEntry
   499  	}
   500  	var logEntry schema.LogEntry
   501  	logEntry.Index = dec.decodeVarUint()
   502  	logEntry.Create = dec.decodeVarint()
   503  	logEntry.Metadata, _, _ = dec.decodeBytes()
   504  	logEntry.Timestamp = dec.decodeVarint()
   505  	logEntry.Value = dec.decodeFloat64()
   506  	logEntry.Unit = uint32(dec.decodeVarUint())
   507  	logEntry.Annotation, _, _ = dec.decodeBytes()
   508  	dec.skip(numFieldsToSkip)
   509  	if dec.err != nil {
   510  		return emptyLogEntry
   511  	}
   512  	return logEntry
   513  }
   514  
   515  func (dec *Decoder) decodeLogMetadata() schema.LogMetadata {
   516  	numFieldsToSkip, _, ok := dec.checkNumFieldsFor(logMetadataType, checkNumFieldsOptions{})
   517  	if !ok {
   518  		return emptyLogMetadata
   519  	}
   520  	var logMetadata schema.LogMetadata
   521  	logMetadata.ID, _, _ = dec.decodeBytes()
   522  	logMetadata.Namespace, _, _ = dec.decodeBytes()
   523  	logMetadata.Shard = uint32(dec.decodeVarUint())
   524  	logMetadata.EncodedTags, _, _ = dec.decodeBytes()
   525  	dec.skip(numFieldsToSkip)
   526  	if dec.err != nil {
   527  		return emptyLogMetadata
   528  	}
   529  	return logMetadata
   530  }
   531  
   532  func (dec *Decoder) decodeRootObject(expectedVersion int, expectedType objectType) (version int, numFieldsToSkip int) {
   533  	version = dec.checkVersion(expectedVersion)
   534  	if dec.err != nil {
   535  		return 0, 0
   536  	}
   537  	numFieldsToSkip, _, ok := dec.checkNumFieldsFor(rootObjectType, checkNumFieldsOptions{})
   538  	if !ok {
   539  		return 0, 0
   540  	}
   541  	actualType := dec.decodeObjectType()
   542  	if dec.err != nil {
   543  		return 0, 0
   544  	}
   545  	if expectedType != actualType {
   546  		dec.err = fmt.Errorf("object type mismatch: expected %v actual %v", expectedType, actualType)
   547  		return 0, 0
   548  	}
   549  	return version, numFieldsToSkip
   550  }
   551  
   552  func (dec *Decoder) checkVersion(expected int) int {
   553  	version := int(dec.decodeVarint())
   554  	if dec.err != nil {
   555  		return 0
   556  	}
   557  	if version > expected {
   558  		dec.err = fmt.Errorf("version mismatch: expected %v actual %v", expected, version)
   559  		return 0
   560  	}
   561  
   562  	return version
   563  }
   564  
   565  type checkNumFieldsOptions struct {
   566  	override              bool
   567  	numExpectedMinFields  int
   568  	numExpectedCurrFields int
   569  }
   570  
   571  func (dec *Decoder) checkNumFieldsFor(
   572  	objType objectType,
   573  	opts checkNumFieldsOptions,
   574  ) (int, int, bool) {
   575  	actual := dec.decodeNumObjectFields()
   576  	if dec.err != nil {
   577  		return 0, 0, false
   578  	}
   579  	min, curr := numFieldsForType(objType)
   580  	if opts.override {
   581  		min = opts.numExpectedMinFields
   582  		curr = opts.numExpectedCurrFields
   583  	}
   584  	if min > actual {
   585  		dec.err = fmt.Errorf("number of fields mismatch: expected minimum of %d actual %d", min, actual)
   586  		return 0, 0, false
   587  	}
   588  
   589  	numToSkip := actual - curr
   590  	if numToSkip < 0 {
   591  		numToSkip = 0
   592  	}
   593  	return numToSkip, actual, true
   594  }
   595  
   596  func (dec *Decoder) skip(numFields int) {
   597  	if dec.err != nil {
   598  		return
   599  	}
   600  	if numFields < 0 {
   601  		dec.err = fmt.Errorf("number of fields to skip is %d", numFields)
   602  		return
   603  	}
   604  	for i := 0; i < numFields; i++ {
   605  		if err := dec.dec.Skip(); err != nil {
   606  			dec.err = err
   607  			return
   608  		}
   609  	}
   610  }
   611  
   612  func (dec *Decoder) decodeNumObjectFields() int {
   613  	return dec.decodeArrayLen()
   614  }
   615  
   616  func (dec *Decoder) decodeObjectType() objectType {
   617  	return objectType(dec.decodeVarint())
   618  }
   619  
   620  func (dec *Decoder) decodeVarint() int64 {
   621  	if dec.err != nil {
   622  		return 0
   623  	}
   624  	value, err := dec.dec.DecodeInt64()
   625  	dec.err = err
   626  	return value
   627  }
   628  
   629  func (dec *Decoder) decodeVarUint() uint64 {
   630  	if dec.err != nil {
   631  		return 0
   632  	}
   633  	value, err := dec.dec.DecodeUint64()
   634  	dec.err = err
   635  	return value
   636  }
   637  
   638  func (dec *Decoder) decodeFloat64() float64 {
   639  	if dec.err != nil {
   640  		return 0.0
   641  	}
   642  	value, err := dec.dec.DecodeFloat64()
   643  	dec.err = err
   644  	return value
   645  }
   646  
   647  // Should only be called if dec.byteReader != nil.
   648  func (dec *Decoder) decodeBytes() ([]byte, int, int) {
   649  	if dec.err != nil {
   650  		return nil, -1, -1
   651  	}
   652  	// If we need to allocate new space for decoded byte slice, we delegate it to msgpack
   653  	// API which allocates a new slice under the hood, otherwise we simply locate the byte
   654  	// slice as part of the encoded byte stream and return it
   655  	var value []byte
   656  	if dec.allocDecodedBytes {
   657  		value, dec.err = dec.dec.DecodeBytes()
   658  		return value, -1, -1
   659  	}
   660  
   661  	if dec.byteReader == nil {
   662  		// If we're not allowing the msgpack library to allocate the bytes and we haven't been
   663  		// provided a byte decoder stream, then we've reached an invalid state as its not
   664  		// possible for us to decode the bytes in an alloc-less way.
   665  		dec.err = errorCalledDecodeBytesWithoutByteStreamDecoder
   666  		return nil, -1, -1
   667  	}
   668  
   669  	var (
   670  		bytesLen     = dec.decodeBytesLen()
   671  		backingBytes = dec.byteReader.Bytes()
   672  		numBytes     = len(backingBytes)
   673  		currPos      = int(int64(numBytes) - dec.byteReader.Remaining())
   674  	)
   675  
   676  	if dec.err != nil {
   677  		return nil, -1, -1
   678  	}
   679  	// NB(xichen): DecodeBytesLen() returns -1 if the byte slice is nil
   680  	if bytesLen == -1 {
   681  		return nil, -1, -1
   682  	}
   683  
   684  	targetPos := currPos + bytesLen
   685  	if bytesLen < 0 || currPos < 0 || targetPos > numBytes {
   686  		dec.err = fmt.Errorf("invalid currPos %d, bytesLen %d, numBytes %d", currPos, bytesLen, numBytes)
   687  		return nil, -1, -1
   688  	}
   689  	if err := dec.byteReader.Skip(int64(bytesLen)); err != nil {
   690  		dec.err = err
   691  		return nil, -1, -1
   692  	}
   693  	value = backingBytes[currPos:targetPos]
   694  	if err := dec.readerWithDigest.capture(value); err != nil {
   695  		dec.err = err
   696  		return nil, -1, -1
   697  	}
   698  
   699  	return value, currPos, bytesLen
   700  }
   701  
   702  func (dec *Decoder) decodeBytesWithPool(bytesPool pool.BytesPool) []byte {
   703  	if dec.err != nil {
   704  		return nil
   705  	}
   706  
   707  	bytesLen := dec.decodeBytesLen()
   708  	if dec.err != nil {
   709  		return nil
   710  	}
   711  	if bytesLen < 0 {
   712  		return nil
   713  	}
   714  
   715  	bytes := bytesPool.Get(bytesLen)[:bytesLen]
   716  	n, err := io.ReadFull(dec.readerWithDigest, bytes)
   717  	if err != nil {
   718  		dec.err = err
   719  		bytesPool.Put(bytes)
   720  		return nil
   721  	}
   722  	if n != bytesLen {
   723  		// This check is redundant because io.ReadFull will return an error if
   724  		// its not able to read the specified number of bytes, but we keep it
   725  		// in for posterity.
   726  		dec.err = fmt.Errorf(
   727  			"tried to decode checked bytes of length: %d, but read: %d",
   728  			bytesLen, n)
   729  		bytesPool.Put(bytes)
   730  		return nil
   731  	}
   732  
   733  	return bytes
   734  }
   735  
   736  func (dec *Decoder) decodeArrayLen() int {
   737  	if dec.err != nil {
   738  		return 0
   739  	}
   740  	value, err := dec.dec.DecodeArrayLen()
   741  	dec.err = err
   742  	return value
   743  }
   744  
   745  func (dec *Decoder) decodeBytesLen() int {
   746  	if dec.err != nil {
   747  		return 0
   748  	}
   749  	value, err := dec.dec.DecodeBytesLen()
   750  	dec.err = err
   751  	return value
   752  }