github.com/matrixorigin/matrixone@v1.2.0/pkg/objectio/metav2.go (about)

     1  // Copyright 2021 Matrix Origin
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package objectio
    16  
    17  import (
    18  	"github.com/matrixorigin/matrixone/pkg/container/types"
    19  )
    20  
    21  type DataMetaType uint16
    22  
    23  const (
    24  	SchemaData      DataMetaType = 0
    25  	SchemaTombstone DataMetaType = 1
    26  
    27  	CkpMetaStart DataMetaType = 2
    28  
    29  	// CkpMetaEnd = CkpMetaStart + `MaxIDX`
    30  	CkpMetaEnd DataMetaType = 28 + 2
    31  )
    32  
    33  const (
    34  	dataMetaCount         = 2
    35  	dataMetaOffset        = 4
    36  	tombstoneMetaCountOff = dataMetaCount + dataMetaOffset
    37  	tombstoneMetaCount    = 2
    38  	tombstoneMetaOffset   = 4
    39  	metaDummyOff          = tombstoneMetaCountOff + tombstoneMetaCount + tombstoneMetaOffset
    40  	metaDummy             = 20
    41  
    42  	metaHeaderLen = metaDummyOff + metaDummy
    43  )
    44  
    45  func ConvertToSchemaType(ckpIdx uint16) DataMetaType {
    46  	return CkpMetaStart + DataMetaType(ckpIdx)
    47  }
    48  
    49  func ConvertToCkpIdx(dataType uint16) uint16 {
    50  	return dataType - uint16(CkpMetaStart)
    51  }
    52  
    53  type objectMetaV2 []byte
    54  
    55  func (mh objectMetaV2) MustGetMeta(metaType DataMetaType) objectDataMetaV1 {
    56  	if metaType == SchemaData {
    57  		return mh.MustDataMeta()
    58  	} else if metaType == SchemaTombstone {
    59  		return mh.MustTombstoneMeta()
    60  	}
    61  	return nil
    62  }
    63  
    64  func (mh objectMetaV2) HeaderLength() uint32 {
    65  	return metaHeaderLen
    66  }
    67  
    68  func (mh objectMetaV2) DataMetaCount() uint16 {
    69  	return types.DecodeUint16(mh[:dataMetaCount])
    70  }
    71  
    72  func (mh objectMetaV2) TombstoneMetaCount() uint16 {
    73  	return types.DecodeUint16(mh[tombstoneMetaCountOff : tombstoneMetaCountOff+tombstoneMetaCount])
    74  }
    75  
    76  func (mh objectMetaV2) DataMeta() (objectDataMetaV1, bool) {
    77  	if mh.DataMetaCount() == 0 {
    78  		return nil, false
    79  	}
    80  	offset := types.DecodeUint32(mh[dataMetaCount:tombstoneMetaCountOff])
    81  	return objectDataMetaV1(mh[offset:]), true
    82  }
    83  
    84  func (mh objectMetaV2) MustDataMeta() objectDataMetaV1 {
    85  	meta, ok := mh.DataMeta()
    86  	if !ok {
    87  		panic("no data meta")
    88  	}
    89  	return meta
    90  }
    91  
    92  func (mh objectMetaV2) TombstoneMeta() (objectDataMetaV1, bool) {
    93  	if mh.TombstoneMetaCount() == 0 {
    94  		return nil, false
    95  	}
    96  	offset := types.DecodeUint32(mh[tombstoneMetaCountOff+tombstoneMetaCount : metaDummyOff])
    97  	return objectDataMetaV1(mh[offset:]), true
    98  }
    99  
   100  func (mh objectMetaV2) MustTombstoneMeta() objectDataMetaV1 {
   101  	meta, ok := mh.TombstoneMeta()
   102  	if !ok {
   103  		meta = mh.MustDataMeta()
   104  	}
   105  	return meta
   106  }
   107  
   108  func (mh objectMetaV2) SetDataMetaCount(count uint16) {
   109  	copy(mh[:dataMetaCount], types.EncodeUint16(&count))
   110  }
   111  
   112  func (mh objectMetaV2) SetDataMetaOffset(offset uint32) {
   113  	copy(mh[dataMetaCount:dataMetaCount+dataMetaOffset], types.EncodeUint32(&offset))
   114  }
   115  
   116  func (mh objectMetaV2) SetTombstoneMetaCount(count uint16) {
   117  	copy(mh[tombstoneMetaCountOff:tombstoneMetaCountOff+tombstoneMetaCount], types.EncodeUint16(&count))
   118  }
   119  
   120  func (mh objectMetaV2) SetTombstoneMetaOffset(offset uint32) {
   121  	copy(mh[tombstoneMetaCountOff+tombstoneMetaCount:tombstoneMetaCountOff+tombstoneMetaCount+tombstoneMetaOffset], types.EncodeUint32(&offset))
   122  }
   123  
   124  func (mh objectMetaV2) SubMeta(pos uint16) (objectDataMetaV1, bool) {
   125  	offStart := schemaCountLen + uint32(pos)*typePosLen + schemaType + schemaBlockCount + metaHeaderLen
   126  	offEnd := schemaCountLen + uint32(pos)*typePosLen + typePosLen + metaHeaderLen
   127  	offset := types.DecodeUint32(mh[offStart:offEnd])
   128  	return objectDataMetaV1(mh[offset:]), true
   129  }
   130  
   131  func (mh objectMetaV2) SubMetaCount() uint16 {
   132  	return types.DecodeUint16(mh[metaHeaderLen : metaHeaderLen+schemaCountLen])
   133  }
   134  
   135  func (mh objectMetaV2) SubMetaIndex() SubMetaIndex {
   136  	return SubMetaIndex(mh[metaHeaderLen:])
   137  }
   138  
   139  func (mh objectMetaV2) SubMetaTypes() []uint16 {
   140  	cnt := mh.SubMetaCount()
   141  	subMetaTypes := make([]uint16, cnt)
   142  	for i := uint16(0); i < cnt; i++ {
   143  		offStart := schemaCountLen + i*typePosLen + metaHeaderLen
   144  		offEnd := schemaCountLen + i*typePosLen + schemaType + metaHeaderLen
   145  		subMetaTypes[i] = types.DecodeUint16(mh[offStart:offEnd])
   146  	}
   147  	return subMetaTypes
   148  }
   149  
   150  const (
   151  	schemaCountLen   = 2
   152  	schemaType       = 2
   153  	schemaBlockCount = 2
   154  	schemaMetaOffset = 4
   155  	typePosLen       = schemaType + schemaBlockCount + schemaMetaOffset
   156  )
   157  
   158  type SubMetaIndex []byte
   159  
   160  func BuildSubMetaIndex(count uint16) SubMetaIndex {
   161  	length := schemaCountLen + count*typePosLen
   162  	buf := make([]byte, length)
   163  	return buf[:]
   164  }
   165  
   166  func (oh SubMetaIndex) SetSubMetaCount(cnt uint16) {
   167  	copy(oh[:schemaCountLen], types.EncodeUint16(&cnt))
   168  }
   169  
   170  func (oh SubMetaIndex) SubMetaCount() uint16 {
   171  	return types.DecodeUint16(oh[:schemaCountLen])
   172  }
   173  
   174  func (oh SubMetaIndex) SetSchemaMeta(pos uint16, st uint16, count uint16, offset uint32) {
   175  	offStart := schemaCountLen + uint32(pos)*typePosLen
   176  	offEnd := schemaCountLen + uint32(pos)*typePosLen + schemaType
   177  	copy(oh[offStart:offEnd], types.EncodeUint16(&st))
   178  	copy(oh[offStart+schemaType:offEnd+schemaBlockCount], types.EncodeUint16(&count))
   179  	copy(oh[offStart+schemaType+schemaBlockCount:offEnd+schemaBlockCount+schemaMetaOffset], types.EncodeUint32(&offset))
   180  }
   181  
   182  func (oh SubMetaIndex) Length() uint32 {
   183  	return uint32(oh.SubMetaCount()*typePosLen + schemaCountLen)
   184  }