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 }