github.com/matrixorigin/matrixone@v0.7.0/pkg/vm/engine/tae/tables/blk.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 tables
    16  
    17  import (
    18  	"bytes"
    19  	"time"
    20  
    21  	"github.com/RoaringBitmap/roaring"
    22  	"github.com/matrixorigin/matrixone/pkg/common/moerr"
    23  	"github.com/matrixorigin/matrixone/pkg/container/types"
    24  	"github.com/matrixorigin/matrixone/pkg/logutil"
    25  	"github.com/matrixorigin/matrixone/pkg/objectio"
    26  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/buffer/base"
    27  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/catalog"
    28  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/common"
    29  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/compute"
    30  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/containers"
    31  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/iface/handle"
    32  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/iface/txnif"
    33  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/model"
    34  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/tasks"
    35  )
    36  
    37  type block struct {
    38  	*baseBlock
    39  }
    40  
    41  func newBlock(
    42  	meta *catalog.BlockEntry,
    43  	fs *objectio.ObjectFS,
    44  	bufMgr base.INodeManager,
    45  	scheduler tasks.TaskScheduler) *block {
    46  	blk := &block{}
    47  	blk.baseBlock = newBaseBlock(blk, meta, bufMgr, fs, scheduler)
    48  	blk.mvcc.SetDeletesListener(blk.OnApplyDelete)
    49  	pnode := newPersistedNode(blk.baseBlock)
    50  	node := NewNode(pnode)
    51  	node.Ref()
    52  	blk.node.Store(node)
    53  	return blk
    54  }
    55  
    56  func (blk *block) Init() (err error) {
    57  	node := blk.PinNode()
    58  	defer node.Unref()
    59  	node.MustPNode().init()
    60  	return
    61  }
    62  
    63  func (blk *block) OnApplyDelete(
    64  	deleted uint64,
    65  	gen common.RowGen,
    66  	ts types.TS) (err error) {
    67  	blk.meta.GetSegment().GetTable().RemoveRows(deleted)
    68  	return
    69  }
    70  
    71  func (blk *block) PrepareCompact() bool {
    72  	return blk.meta.PrepareCompact()
    73  }
    74  
    75  func (blk *block) Pin() *common.PinnedItem[*block] {
    76  	blk.Ref()
    77  	return &common.PinnedItem[*block]{
    78  		Val: blk,
    79  	}
    80  }
    81  
    82  func (blk *block) GetColumnDataByNames(
    83  	txn txnif.AsyncTxn,
    84  	attrs []string,
    85  	buffers []*bytes.Buffer) (view *model.BlockView, err error) {
    86  	colIdxes := make([]int, len(attrs))
    87  	schema := blk.meta.GetSchema()
    88  	for i, attr := range attrs {
    89  		colIdxes[i] = schema.GetColIdx(attr)
    90  	}
    91  	return blk.GetColumnDataByIds(txn, colIdxes, buffers)
    92  }
    93  
    94  func (blk *block) GetColumnDataByName(
    95  	txn txnif.AsyncTxn,
    96  	attr string,
    97  	buffer *bytes.Buffer) (view *model.ColumnView, err error) {
    98  	colIdx := blk.meta.GetSchema().GetColIdx(attr)
    99  	return blk.GetColumnDataById(txn, colIdx, buffer)
   100  }
   101  
   102  func (blk *block) GetColumnDataByIds(
   103  	txn txnif.AsyncTxn,
   104  	colIdxes []int,
   105  	buffers []*bytes.Buffer) (view *model.BlockView, err error) {
   106  	node := blk.PinNode()
   107  	defer node.Unref()
   108  	return blk.ResolvePersistedColumnDatas(
   109  		node.MustPNode(),
   110  		txn.GetStartTS(),
   111  		colIdxes,
   112  		buffers,
   113  		false)
   114  }
   115  
   116  // GetColumnDataById Get the snapshot at txn's start timestamp of column data.
   117  // Notice that for non-appendable block, if it is visible to txn,
   118  // then all the block data pointed by meta location also be visible to txn;
   119  func (blk *block) GetColumnDataById(
   120  	txn txnif.AsyncTxn,
   121  	colIdx int,
   122  	buffer *bytes.Buffer) (view *model.ColumnView, err error) {
   123  	node := blk.PinNode()
   124  	defer node.Unref()
   125  	return blk.ResolvePersistedColumnData(
   126  		node.MustPNode(),
   127  		txn.GetStartTS(),
   128  		colIdx,
   129  		buffer,
   130  		false)
   131  }
   132  
   133  func (blk *block) BatchDedup(
   134  	txn txnif.AsyncTxn,
   135  	keys containers.Vector,
   136  	rowmask *roaring.Bitmap,
   137  	precommit bool) (err error) {
   138  	defer func() {
   139  		if moerr.IsMoErrCode(err, moerr.ErrDuplicateEntry) {
   140  			logutil.Infof("BatchDedup BLK-%d: %v", blk.meta.ID, err)
   141  		}
   142  	}()
   143  	ts := txn.GetStartTS()
   144  	if precommit {
   145  		//ts is assigned to maximum value of TS.
   146  		ts = txn.GetPrepareTS()
   147  	}
   148  	node := blk.PinNode()
   149  	defer node.Unref()
   150  	return blk.PersistedBatchDedup(
   151  		node.MustPNode(),
   152  		ts,
   153  		keys,
   154  		rowmask,
   155  		blk.dedupClosure)
   156  }
   157  
   158  func (blk *block) dedupClosure(
   159  	vec containers.Vector,
   160  	ts types.TS,
   161  	mask *roaring.Bitmap,
   162  	def *catalog.ColDef) func(any, int) error {
   163  	return func(v any, _ int) (err error) {
   164  		if _, existed := compute.GetOffsetByVal(vec, v, mask); existed {
   165  			entry := common.TypeStringValue(vec.GetType(), v)
   166  			return moerr.NewDuplicateEntryNoCtx(entry, def.Name)
   167  		}
   168  		return nil
   169  	}
   170  }
   171  
   172  func (blk *block) GetValue(
   173  	txn txnif.AsyncTxn,
   174  	row, col int) (v any, err error) {
   175  	ts := txn.GetStartTS()
   176  	node := blk.PinNode()
   177  	defer node.Unref()
   178  	return blk.getPersistedValue(
   179  		node.MustPNode(),
   180  		ts,
   181  		row,
   182  		col,
   183  		false)
   184  }
   185  
   186  func (blk *block) RunCalibration() (score int) {
   187  	score, _ = blk.estimateRawScore()
   188  	return
   189  }
   190  
   191  func (blk *block) estimateRawScore() (score int, dropped bool) {
   192  	if blk.meta.HasDropCommitted() {
   193  		dropped = true
   194  		return
   195  	}
   196  	if blk.mvcc.GetChangeNodeCnt() == 0 {
   197  		// No deletes found
   198  		score = 0
   199  	} else {
   200  		// Any delete
   201  		score = 1
   202  	}
   203  
   204  	// If any delete found and the table or database of the block had
   205  	// been deleted. Force checkpoint the block
   206  	if score > 0 {
   207  		if _, terminated := blk.meta.GetTerminationTS(); terminated {
   208  			score = 100
   209  		}
   210  	}
   211  	return
   212  }
   213  
   214  func (blk *block) EstimateScore(ttl time.Duration, force bool) int {
   215  	return blk.adjustScore(blk.estimateRawScore, ttl, force)
   216  }
   217  
   218  func (blk *block) GetByFilter(
   219  	txn txnif.AsyncTxn,
   220  	filter *handle.Filter) (offset uint32, err error) {
   221  	if filter.Op != handle.FilterEq {
   222  		panic("logic error")
   223  	}
   224  	if blk.meta.GetSchema().SortKey == nil {
   225  		_, _, offset = model.DecodePhyAddrKeyFromValue(filter.Val)
   226  		return
   227  	}
   228  	ts := txn.GetStartTS()
   229  
   230  	node := blk.PinNode()
   231  	defer node.Unref()
   232  	return blk.getPersistedRowByFilter(node.MustPNode(), ts, filter)
   233  }
   234  
   235  func (blk *block) getPersistedRowByFilter(
   236  	pnode *persistedNode,
   237  	ts types.TS,
   238  	filter *handle.Filter) (offset uint32, err error) {
   239  	ok, err := pnode.ContainsKey(filter.Val)
   240  	if err != nil {
   241  		return
   242  	}
   243  	if !ok {
   244  		err = moerr.NewNotFoundNoCtx()
   245  		return
   246  	}
   247  	var sortKey containers.Vector
   248  	if sortKey, err = blk.LoadPersistedColumnData(
   249  		blk.meta.GetSchema().GetSingleSortKeyIdx(),
   250  		nil); err != nil {
   251  		return
   252  	}
   253  	defer sortKey.Close()
   254  	off, existed := compute.GetOffsetByVal(sortKey, filter.Val, nil)
   255  	if !existed {
   256  		err = moerr.NewNotFoundNoCtx()
   257  		return
   258  	}
   259  	offset = uint32(off)
   260  
   261  	blk.mvcc.RLock()
   262  	defer blk.mvcc.RUnlock()
   263  	deleted, err := blk.mvcc.IsDeletedLocked(offset, ts, blk.mvcc.RWMutex)
   264  	if err != nil {
   265  		return
   266  	}
   267  	if deleted {
   268  		err = moerr.NewNotFoundNoCtx()
   269  	}
   270  	return
   271  }