github.com/matrixorigin/matrixone@v0.7.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  	"bytes"
    19  	"encoding/binary"
    20  	"github.com/matrixorigin/matrixone/pkg/common/moerr"
    21  )
    22  
    23  // Block is the organizational structure of a batch in objectio
    24  // Write one batch at a time, and batch and block correspond one-to-one
    25  type Block struct {
    26  	// id is the serial number of the block in the object
    27  	id uint32
    28  
    29  	// header is the metadata of the block, such as tableid, blockid, column count...
    30  	header BlockHeader
    31  
    32  	// columns is the vector in the batch
    33  	columns []ColumnObject
    34  
    35  	// object is a container that can store multiple blocks,
    36  	// using a fileservice file storage
    37  	object *Object
    38  
    39  	// extent is the location of the block's metadata on the fileservice
    40  	extent Extent
    41  
    42  	// name is the file name or object name of the block
    43  	name string
    44  }
    45  
    46  func NewBlock(colCnt uint16, object *Object, name string) BlockObject {
    47  	header := BlockHeader{
    48  		columnCount: colCnt,
    49  	}
    50  	block := &Block{
    51  		header:  header,
    52  		object:  object,
    53  		columns: make([]ColumnObject, colCnt),
    54  		name:    name,
    55  	}
    56  	for i := range block.columns {
    57  		block.columns[i] = NewColumnBlock(uint16(i), block.object)
    58  	}
    59  	return block
    60  }
    61  
    62  func (b *Block) GetExtent() Extent {
    63  	return b.extent
    64  }
    65  
    66  func (b *Block) GetColumn(idx uint16) (ColumnObject, error) {
    67  	if idx >= uint16(len(b.columns)) {
    68  		return nil, moerr.NewInternalErrorNoCtx("ObjectIO: bad index: %d, "+
    69  			"block: %v, column count: %d",
    70  			idx, b.name,
    71  			len(b.columns))
    72  	}
    73  	return b.columns[idx], nil
    74  }
    75  
    76  func (b *Block) GetRows() (uint32, error) {
    77  	panic(any("implement me"))
    78  }
    79  
    80  func (b *Block) GetMeta() BlockMeta {
    81  	return BlockMeta{
    82  		header: b.header,
    83  		name:   b.name,
    84  	}
    85  }
    86  
    87  func (b *Block) GetID() uint32 {
    88  	return b.id
    89  }
    90  
    91  func (b *Block) MarshalMeta() ([]byte, error) {
    92  	var (
    93  		err    error
    94  		buffer bytes.Buffer
    95  	)
    96  	// write header
    97  	if err = binary.Write(&buffer, endian, b.header.tableId); err != nil {
    98  		return nil, err
    99  	}
   100  	if err = binary.Write(&buffer, endian, b.header.segmentId); err != nil {
   101  		return nil, err
   102  	}
   103  	if err = binary.Write(&buffer, endian, b.header.blockId); err != nil {
   104  		return nil, err
   105  	}
   106  	if err = binary.Write(&buffer, endian, b.header.columnCount); err != nil {
   107  		return nil, err
   108  	}
   109  	if err = binary.Write(&buffer, endian, b.header.dummy); err != nil {
   110  		return nil, err
   111  	}
   112  	if err = binary.Write(&buffer, endian, uint32(0)); err != nil {
   113  		return nil, err
   114  	}
   115  	// write columns meta
   116  	for _, column := range b.columns {
   117  		columnMeta, err := column.(*ColumnBlock).MarshalMeta()
   118  		if err != nil {
   119  			return nil, err
   120  		}
   121  		if err = binary.Write(&buffer, endian, columnMeta); err != nil {
   122  			return nil, err
   123  		}
   124  	}
   125  	return buffer.Bytes(), nil
   126  }
   127  
   128  func (b *Block) UnMarshalMeta(data []byte) (uint32, error) {
   129  	var err error
   130  	cache := bytes.NewBuffer(data)
   131  	size := uint32(0)
   132  	b.header = BlockHeader{}
   133  	if err = binary.Read(cache, endian, &b.header.tableId); err != nil {
   134  		return 0, err
   135  	}
   136  	if err = binary.Read(cache, endian, &b.header.segmentId); err != nil {
   137  		return 0, err
   138  	}
   139  	if err = binary.Read(cache, endian, &b.header.blockId); err != nil {
   140  		return 0, err
   141  	}
   142  	if err = binary.Read(cache, endian, &b.header.columnCount); err != nil {
   143  		return 0, err
   144  	}
   145  	if err = binary.Read(cache, endian, &b.header.dummy); err != nil {
   146  		return 0, err
   147  	}
   148  	if err = binary.Read(cache, endian, &b.header.checksum); err != nil {
   149  		return 0, err
   150  	}
   151  	size += HeaderSize
   152  	b.columns = make([]ColumnObject, b.header.columnCount)
   153  	for i := range b.columns {
   154  		b.columns[i] = NewColumnBlock(uint16(i), b.object)
   155  		err = b.columns[i].(*ColumnBlock).UnMarshalMate(cache)
   156  		if err != nil {
   157  			return 0, err
   158  		}
   159  	}
   160  	size += ColumnMetaSize * uint32(b.header.columnCount)
   161  	return size, err
   162  }