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 }