github.com/matrixorigin/matrixone@v1.2.0/pkg/vm/engine/tae/tables/obj.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  	"context"
    19  
    20  	"github.com/RoaringBitmap/roaring"
    21  	"github.com/matrixorigin/matrixone/pkg/common/moerr"
    22  	"github.com/matrixorigin/matrixone/pkg/common/mpool"
    23  	"github.com/matrixorigin/matrixone/pkg/container/nulls"
    24  	"github.com/matrixorigin/matrixone/pkg/container/types"
    25  	"github.com/matrixorigin/matrixone/pkg/logutil"
    26  	"github.com/matrixorigin/matrixone/pkg/objectio"
    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/db/dbutils"
    32  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/iface/handle"
    33  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/iface/txnif"
    34  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/index"
    35  )
    36  
    37  type object struct {
    38  	*baseObject
    39  }
    40  
    41  func newObject(
    42  	meta *catalog.ObjectEntry,
    43  	rt *dbutils.Runtime,
    44  ) *object {
    45  	obj := &object{}
    46  	obj.baseObject = newBaseObject(obj, meta, rt)
    47  	pnode := newPersistedNode(obj.baseObject)
    48  	node := NewNode(pnode)
    49  	node.Ref()
    50  	obj.node.Store(node)
    51  	return obj
    52  }
    53  
    54  func (obj *object) Init() (err error) {
    55  	return
    56  }
    57  
    58  func (obj *object) OnApplyDelete(
    59  	deleted uint64,
    60  	ts types.TS) (err error) {
    61  	obj.meta.GetTable().RemoveRows(deleted)
    62  	return
    63  }
    64  
    65  func (obj *object) PrepareCompact() bool {
    66  	return obj.meta.PrepareCompact()
    67  }
    68  
    69  func (obj *object) PrepareCompactInfo() (result bool, reason string) {
    70  	return obj.meta.PrepareCompact(), ""
    71  }
    72  
    73  func (obj *object) FreezeAppend() {}
    74  
    75  func (obj *object) Pin() *common.PinnedItem[*object] {
    76  	obj.Ref()
    77  	return &common.PinnedItem[*object]{
    78  		Val: obj,
    79  	}
    80  }
    81  
    82  func (obj *object) GetColumnDataByIds(
    83  	ctx context.Context,
    84  	txn txnif.AsyncTxn,
    85  	readSchema any,
    86  	blkID uint16,
    87  	colIdxes []int,
    88  	mp *mpool.MPool,
    89  ) (view *containers.BlockView, err error) {
    90  	node := obj.PinNode()
    91  	defer node.Unref()
    92  	schema := readSchema.(*catalog.Schema)
    93  	return obj.ResolvePersistedColumnDatas(
    94  		ctx, txn, schema, blkID, colIdxes, false, mp,
    95  	)
    96  }
    97  
    98  // GetColumnDataById Get the snapshot at txn's start timestamp of column data.
    99  // Notice that for non-appendable object, if it is visible to txn,
   100  // then all the object data pointed by meta location also be visible to txn;
   101  func (obj *object) GetColumnDataById(
   102  	ctx context.Context,
   103  	txn txnif.AsyncTxn,
   104  	readSchema any,
   105  	blkID uint16,
   106  	col int,
   107  	mp *mpool.MPool,
   108  ) (view *containers.ColumnView, err error) {
   109  	schema := readSchema.(*catalog.Schema)
   110  	return obj.ResolvePersistedColumnData(
   111  		ctx,
   112  		txn,
   113  		schema,
   114  		blkID,
   115  		col,
   116  		false,
   117  		mp,
   118  	)
   119  }
   120  func (obj *object) CoarseCheckAllRowsCommittedBefore(ts types.TS) bool {
   121  	obj.meta.RLock()
   122  	defer obj.meta.RUnlock()
   123  	creatTS := obj.meta.GetCreatedAtLocked()
   124  	return creatTS.Less(&ts)
   125  }
   126  
   127  func (obj *object) BatchDedup(
   128  	ctx context.Context,
   129  	txn txnif.AsyncTxn,
   130  	keys containers.Vector,
   131  	keysZM index.ZM,
   132  	rowmask *roaring.Bitmap,
   133  	precommit bool,
   134  	bf objectio.BloomFilter,
   135  	mp *mpool.MPool,
   136  ) (err error) {
   137  	defer func() {
   138  		if moerr.IsMoErrCode(err, moerr.ErrDuplicateEntry) {
   139  			logutil.Infof("BatchDedup %s (%v)obj-%s: %v",
   140  				obj.meta.GetTable().GetLastestSchemaLocked().Name,
   141  				obj.IsAppendable(),
   142  				obj.meta.ID.String(),
   143  				err)
   144  		}
   145  	}()
   146  	return obj.PersistedBatchDedup(
   147  		ctx,
   148  		txn,
   149  		precommit,
   150  		keys,
   151  		keysZM,
   152  		rowmask,
   153  		false,
   154  		bf,
   155  		mp,
   156  	)
   157  }
   158  
   159  func (obj *object) GetValue(
   160  	ctx context.Context,
   161  	txn txnif.AsyncTxn,
   162  	readSchema any,
   163  	blkID uint16,
   164  	row, col int,
   165  	mp *mpool.MPool,
   166  ) (v any, isNull bool, err error) {
   167  	node := obj.PinNode()
   168  	defer node.Unref()
   169  	schema := readSchema.(*catalog.Schema)
   170  	return obj.getPersistedValue(
   171  		ctx, txn, schema, blkID, row, col, false, mp,
   172  	)
   173  }
   174  
   175  func (obj *object) RunCalibration() (score int, err error) {
   176  	score, _ = obj.estimateRawScore()
   177  	return
   178  }
   179  
   180  func (obj *object) estimateRawScore() (score int, dropped bool) {
   181  	if obj.meta.HasDropCommitted() && !obj.meta.InMemoryDeletesExisted() {
   182  		dropped = true
   183  		return
   184  	}
   185  	changeCnt := uint32(0)
   186  	obj.RLock()
   187  	objectMVCC := obj.tryGetMVCC()
   188  	if objectMVCC != nil {
   189  		changeCnt = objectMVCC.GetChangeIntentionCntLocked()
   190  	}
   191  	obj.RUnlock()
   192  	if changeCnt == 0 {
   193  		// No deletes found
   194  		score = 0
   195  	} else {
   196  		// Any delete
   197  		score = 1
   198  	}
   199  
   200  	// If any delete found and the table or database of the object had
   201  	// been deleted. Force checkpoint the object
   202  	if score > 0 {
   203  		if _, terminated := obj.meta.GetTerminationTS(); terminated {
   204  			score = 100
   205  		}
   206  	}
   207  	return
   208  }
   209  
   210  func (obj *object) GetByFilter(
   211  	ctx context.Context,
   212  	txn txnif.AsyncTxn,
   213  	filter *handle.Filter,
   214  	mp *mpool.MPool,
   215  ) (blkID uint16, offset uint32, err error) {
   216  	if filter.Op != handle.FilterEq {
   217  		panic("logic error")
   218  	}
   219  	if obj.meta.GetSchema().SortKey == nil {
   220  		rid := filter.Val.(types.Rowid)
   221  		offset = rid.GetRowOffset()
   222  		return
   223  	}
   224  
   225  	node := obj.PinNode()
   226  	defer node.Unref()
   227  	return obj.getPersistedRowByFilter(ctx, node.MustPNode(), txn, filter, mp)
   228  }
   229  
   230  func (obj *object) getPersistedRowByFilter(
   231  	ctx context.Context,
   232  	pnode *persistedNode,
   233  	txn txnif.TxnReader,
   234  	filter *handle.Filter,
   235  	mp *mpool.MPool,
   236  ) (blkID uint16, offset uint32, err error) {
   237  	var sortKey containers.Vector
   238  	schema := obj.meta.GetSchema()
   239  	idx := schema.GetSingleSortKeyIdx()
   240  	objMVCC := obj.tryGetMVCC()
   241  	for blkID = uint16(0); blkID < uint16(obj.meta.BlockCnt()); blkID++ {
   242  		var ok bool
   243  		ok, err = pnode.ContainsKey(ctx, filter.Val, uint32(blkID))
   244  		if err != nil {
   245  			return
   246  		}
   247  		if !ok {
   248  			continue
   249  		}
   250  		if sortKey, err = obj.LoadPersistedColumnData(ctx, schema, idx, mp, blkID); err != nil {
   251  			continue
   252  		}
   253  		defer sortKey.Close()
   254  		off, existed := compute.GetOffsetByVal(sortKey, filter.Val, nil)
   255  		if !existed {
   256  			continue
   257  		}
   258  		offset = uint32(off)
   259  
   260  		if objMVCC == nil {
   261  			return
   262  		}
   263  		objMVCC.RLock()
   264  		defer objMVCC.RUnlock()
   265  		var deleted bool
   266  		deleted, err = objMVCC.IsDeletedLocked(offset, txn, blkID)
   267  		if err != nil {
   268  			return
   269  		}
   270  		if deleted {
   271  			continue
   272  		}
   273  		var deletes *nulls.Nulls
   274  		deletes, err = obj.persistedCollectDeleteMaskInRange(ctx, blkID, types.TS{}, txn.GetStartTS(), mp)
   275  		if err != nil {
   276  			return
   277  		}
   278  		if !deletes.Contains(uint64(offset)) {
   279  			return
   280  		}
   281  
   282  	}
   283  	err = moerr.NewNotFoundNoCtx()
   284  	return
   285  }
   286  
   287  func (obj *object) EstimateMemSize() (int, int) {
   288  	node := obj.PinNode()
   289  	defer node.Unref()
   290  	obj.RLock()
   291  	defer obj.RUnlock()
   292  	objMVCC := obj.tryGetMVCC()
   293  	if objMVCC == nil {
   294  		return 0, 0
   295  	}
   296  	dsize := objMVCC.EstimateMemSizeLocked()
   297  	return 0, dsize
   298  }
   299  
   300  func (obj *object) GetRowsOnReplay() uint64 {
   301  	fileRows := uint64(obj.meta.GetLatestCommittedNodeLocked().
   302  		BaseNode.ObjectStats.Rows())
   303  	return fileRows
   304  }