github.com/matrixorigin/matrixone@v1.2.0/pkg/objectio/block.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  	"fmt"
    19  
    20  	"github.com/matrixorigin/matrixone/pkg/logutil"
    21  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/index"
    22  )
    23  
    24  type BlockObject []byte
    25  
    26  func NewBlock(seqnums *Seqnums) BlockObject {
    27  	header := BuildBlockHeader()
    28  	header.SetColumnCount(uint16(len(seqnums.Seqs)))
    29  	metaColCnt := seqnums.MetaColCnt
    30  	header.SetMetaColumnCount(metaColCnt)
    31  	header.SetMaxSeqnum(seqnums.MaxSeq)
    32  	blockMeta := BuildBlockMeta(metaColCnt)
    33  	blockMeta.SetBlockMetaHeader(header)
    34  	// create redundant columns to make reading O(1)
    35  	for i := uint16(0); i < metaColCnt; i++ {
    36  		col := BuildColumnMeta()
    37  		blockMeta.AddColumnMeta(i, col)
    38  	}
    39  
    40  	for i, seq := range seqnums.Seqs {
    41  		blockMeta.ColumnMeta(seq).setIdx(uint16(i))
    42  	}
    43  	return blockMeta
    44  }
    45  
    46  func BuildBlockMeta(count uint16) BlockObject {
    47  	length := headerLen + uint32(count)*colMetaLen
    48  	buf := make([]byte, length)
    49  	meta := BlockObject(buf)
    50  	return meta
    51  }
    52  
    53  func (bm BlockObject) BlockHeader() BlockHeader {
    54  	return BlockHeader(bm[:headerLen])
    55  }
    56  
    57  func (bm BlockObject) SetBlockMetaHeader(header BlockHeader) {
    58  	copy(bm[:headerLen], header)
    59  }
    60  
    61  // ColumnMeta is for internal use only, it didn't consider the block does not
    62  // contain the seqnum
    63  func (bm BlockObject) ColumnMeta(seqnum uint16) ColumnMeta {
    64  	return GetColumnMeta(seqnum, bm)
    65  }
    66  
    67  func (bm BlockObject) AddColumnMeta(idx uint16, col ColumnMeta) {
    68  	offset := headerLen + uint32(idx)*colMetaLen
    69  	copy(bm[offset:offset+colMetaLen], col)
    70  }
    71  
    72  func (bm BlockObject) IsEmpty() bool {
    73  	return len(bm) == 0
    74  }
    75  
    76  func (bm BlockObject) ToColumnZoneMaps(seqnums []uint16) []ZoneMap {
    77  	maxseq := bm.GetMaxSeqnum()
    78  	zms := make([]ZoneMap, len(seqnums))
    79  	for i, idx := range seqnums {
    80  		if idx >= SEQNUM_UPPER {
    81  			panic(fmt.Sprintf("do not read special %d", idx))
    82  		}
    83  		if idx > maxseq {
    84  			zms[i] = index.DecodeZM(EmptyZm[:])
    85  		}
    86  		column := bm.MustGetColumn(idx)
    87  		zms[i] = index.DecodeZM(column.ZoneMap())
    88  	}
    89  	return zms
    90  }
    91  
    92  func (bm BlockObject) GetExtent() Extent {
    93  	return bm.BlockHeader().MetaLocation()
    94  }
    95  
    96  // MustGetColumn is for general use. it return a empty ColumnMeta if the block does not
    97  // contain the seqnum
    98  func (bm BlockObject) MustGetColumn(seqnum uint16) ColumnMeta {
    99  	if seqnum >= bm.BlockHeader().MetaColumnCount() {
   100  		h := bm.BlockHeader()
   101  		logutil.Infof("ObjectIO: blk-%d genernate empty ColumnMeta for big seqnum %d, maxseq: %d, column count: %d",
   102  			h.Sequence(), seqnum, h.MaxSeqnum(), h.MetaColumnCount())
   103  		return BuildColumnMeta()
   104  	}
   105  	return bm.ColumnMeta(seqnum)
   106  }
   107  
   108  func (bm BlockObject) GetRows() uint32 {
   109  	return bm.BlockHeader().Rows()
   110  }
   111  
   112  func (bm BlockObject) GetMeta() BlockObject {
   113  	return bm
   114  }
   115  
   116  func (bm BlockObject) GetID() uint16 {
   117  	return bm.BlockHeader().Sequence()
   118  }
   119  
   120  func (bm BlockObject) GetColumnCount() uint16 {
   121  	return bm.BlockHeader().ColumnCount()
   122  }
   123  
   124  func (bm BlockObject) GetMetaColumnCount() uint16 {
   125  	return bm.BlockHeader().MetaColumnCount()
   126  }
   127  
   128  func (bm BlockObject) GetMaxSeqnum() uint16 {
   129  	return bm.BlockHeader().MaxSeqnum()
   130  }
   131  
   132  func (bm BlockObject) GetBlockID(name ObjectName) *Blockid {
   133  	segmentId := name.SegmentId()
   134  	num := name.Num()
   135  	return NewBlockid(&segmentId, num, bm.BlockHeader().Sequence())
   136  }