github.com/matrixorigin/matrixone@v0.7.0/pkg/vm/engine/tae/txn/txnimpl/basenode.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 txnimpl 16 17 import ( 18 "bytes" 19 "encoding/binary" 20 "fmt" 21 "github.com/RoaringBitmap/roaring" 22 "github.com/matrixorigin/matrixone/pkg/common/moerr" 23 "github.com/matrixorigin/matrixone/pkg/objectio" 24 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/buffer/base" 25 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/catalog" 26 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/common" 27 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/containers" 28 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/iface/txnif" 29 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/model" 30 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/tables" 31 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/tables/indexwrapper" 32 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/tasks" 33 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/txn/txnbase" 34 "io" 35 ) 36 37 const ( 38 NTInsert txnbase.NodeType = iota 39 NTUpdate 40 NTDelete 41 NTCreateTable 42 NTDropTable 43 NTCreateDB 44 NTDropDB 45 ) 46 47 type InsertNode interface { 48 Close() error 49 Append(data *containers.Batch, offset uint32) (appended uint32, err error) 50 RangeDelete(start, end uint32) error 51 IsRowDeleted(row uint32) bool 52 IsPersisted() bool 53 PrintDeletes() string 54 GetColumnDataByIds([]int, []*bytes.Buffer) (*model.BlockView, error) 55 GetColumnDataById(int, *bytes.Buffer) (*model.ColumnView, error) 56 FillBlockView(view *model.BlockView, buffers []*bytes.Buffer, colIdxes []int) (err error) 57 FillColumnView(*model.ColumnView, *bytes.Buffer) error 58 Window(start, end uint32) (*containers.Batch, error) 59 GetSpace() uint32 60 Rows() uint32 61 GetValue(col int, row uint32) (any, error) 62 MakeCommand(uint32) (txnif.TxnCmd, error) 63 AddApplyInfo(srcOff, srcLen, destOff, destLen uint32, dbid uint64, dest *common.ID) *appendInfo 64 RowsWithoutDeletes() uint32 65 LengthWithDeletes(appended, toAppend uint32) uint32 66 OffsetWithDeletes(count uint32) uint32 67 GetAppends() []*appendInfo 68 GetTxn() txnif.AsyncTxn 69 GetPersistedLoc() (string, string) 70 } 71 72 type appendInfo struct { 73 seq uint32 74 srcOff, srcLen uint32 75 dbid uint64 76 dest *common.ID 77 destOff, destLen uint32 78 } 79 80 func (info *appendInfo) GetDest() *common.ID { 81 return info.dest 82 } 83 func (info *appendInfo) GetDBID() uint64 { 84 return info.dbid 85 } 86 func (info *appendInfo) GetSrcOff() uint32 { 87 return info.srcOff 88 } 89 func (info *appendInfo) GetSrcLen() uint32 { 90 return info.srcLen 91 } 92 func (info *appendInfo) GetDestOff() uint32 { 93 return info.destOff 94 } 95 func (info *appendInfo) GetDestLen() uint32 { 96 return info.destLen 97 } 98 func (info *appendInfo) Desc() string { 99 return info.dest.BlockString() 100 } 101 func (info *appendInfo) String() string { 102 s := fmt.Sprintf("[From=[%d:%d];To=%s[%d:%d]]", 103 info.srcOff, info.srcLen+info.srcOff, info.dest.BlockString(), info.destOff, info.destLen+info.destOff) 104 return s 105 } 106 func (info *appendInfo) WriteTo(w io.Writer) (n int64, err error) { 107 if err = binary.Write(w, binary.BigEndian, info.seq); err != nil { 108 return 109 } 110 if err = binary.Write(w, binary.BigEndian, info.srcOff); err != nil { 111 return 112 } 113 if err = binary.Write(w, binary.BigEndian, info.srcLen); err != nil { 114 return 115 } 116 if err = binary.Write(w, binary.BigEndian, info.dbid); err != nil { 117 return 118 } 119 if err = binary.Write(w, binary.BigEndian, info.dest.TableID); err != nil { 120 return 121 } 122 if err = binary.Write(w, binary.BigEndian, info.dest.SegmentID); err != nil { 123 return 124 } 125 if err = binary.Write(w, binary.BigEndian, info.dest.BlockID); err != nil { 126 return 127 } 128 if err = binary.Write(w, binary.BigEndian, info.destOff); err != nil { 129 return 130 } 131 if err = binary.Write(w, binary.BigEndian, info.destLen); err != nil { 132 return 133 } 134 n = 4 + 4 + 4 + 8 + 8 + 8 + 4 + 4 135 return 136 } 137 func (info *appendInfo) ReadFrom(r io.Reader) (n int64, err error) { 138 if err = binary.Read(r, binary.BigEndian, &info.seq); err != nil { 139 return 140 } 141 if err = binary.Read(r, binary.BigEndian, &info.srcOff); err != nil { 142 return 143 } 144 if err = binary.Read(r, binary.BigEndian, &info.srcLen); err != nil { 145 return 146 } 147 if err = binary.Read(r, binary.BigEndian, &info.dbid); err != nil { 148 return 149 } 150 info.dest = &common.ID{} 151 if err = binary.Read(r, binary.BigEndian, &info.dest.TableID); err != nil { 152 return 153 } 154 if err = binary.Read(r, binary.BigEndian, &info.dest.SegmentID); err != nil { 155 return 156 } 157 if err = binary.Read(r, binary.BigEndian, &info.dest.BlockID); err != nil { 158 return 159 } 160 if err = binary.Read(r, binary.BigEndian, &info.destOff); err != nil { 161 return 162 } 163 if err = binary.Read(r, binary.BigEndian, &info.destLen); err != nil { 164 return 165 } 166 n = 4 + 4 + 4 + 8 + 8 + 8 + 4 + 4 167 return 168 } 169 170 type memoryNode struct { 171 common.RefHelper 172 bnode *baseNode 173 //data resides in. 174 data *containers.Batch 175 rows uint32 176 appends []*appendInfo 177 } 178 179 func newMemoryNode(node *baseNode) *memoryNode { 180 return &memoryNode{ 181 bnode: node, 182 appends: make([]*appendInfo, 0), 183 } 184 } 185 186 func (n *memoryNode) GetSpace() uint32 { 187 return txnbase.MaxNodeRows - n.rows 188 } 189 190 func (n *memoryNode) PrepareAppend(data *containers.Batch, offset uint32) uint32 { 191 left := uint32(data.Length()) - offset 192 nodeLeft := txnbase.MaxNodeRows - n.rows 193 if left <= nodeLeft { 194 return left 195 } 196 return nodeLeft 197 } 198 199 func (n *memoryNode) Append(data *containers.Batch, offset uint32) (an uint32, err error) { 200 schema := n.bnode.table.entry.GetSchema() 201 if n.data == nil { 202 opts := containers.Options{} 203 opts.Capacity = data.Length() - int(offset) 204 if opts.Capacity > int(txnbase.MaxNodeRows) { 205 opts.Capacity = int(txnbase.MaxNodeRows) 206 } 207 n.data = containers.BuildBatch( 208 schema.AllNames(), 209 schema.AllTypes(), 210 schema.AllNullables(), 211 opts) 212 } 213 214 from := uint32(n.data.Length()) 215 an = n.PrepareAppend(data, offset) 216 for _, attr := range data.Attrs { 217 if attr == catalog.PhyAddrColumnName { 218 continue 219 } 220 def := schema.ColDefs[schema.GetColIdx(attr)] 221 destVec := n.data.Vecs[def.Idx] 222 // logutil.Infof("destVec: %s, %d, %d", destVec.String(), cnt, data.Length()) 223 destVec.ExtendWithOffset(data.Vecs[def.Idx], int(offset), int(an)) 224 } 225 n.rows = uint32(n.data.Length()) 226 err = n.FillPhyAddrColumn(from, an) 227 return 228 } 229 230 func (n *memoryNode) FillPhyAddrColumn(startRow, length uint32) (err error) { 231 col, err := model.PreparePhyAddrData(catalog.PhyAddrColumnType, n.bnode.meta.MakeKey(), startRow, length) 232 if err != nil { 233 return 234 } 235 defer col.Close() 236 vec := n.data.Vecs[n.bnode.table.entry.GetSchema().PhyAddrKey.Idx] 237 vec.Extend(col) 238 return 239 } 240 241 type persistedNode struct { 242 common.RefHelper 243 bnode *baseNode 244 rows uint32 245 deletes *roaring.Bitmap 246 //ZM and BF index for primary key 247 pkIndex indexwrapper.Index 248 //ZM and BF index for all columns 249 indexes map[int]indexwrapper.Index 250 } 251 252 func newPersistedNode(bnode *baseNode) *persistedNode { 253 node := &persistedNode{ 254 bnode: bnode, 255 } 256 node.OnZeroCB = node.close 257 if bnode.meta.HasPersistedData() { 258 node.init() 259 } 260 return node 261 } 262 263 func (n *persistedNode) close() { 264 for i, index := range n.indexes { 265 index.Close() 266 n.indexes[i] = nil 267 } 268 n.indexes = nil 269 } 270 271 func (n *persistedNode) init() { 272 n.indexes = make(map[int]indexwrapper.Index) 273 schema := n.bnode.meta.GetSchema() 274 pkIdx := -1 275 if schema.HasPK() { 276 pkIdx = schema.GetSingleSortKeyIdx() 277 } 278 for i := range schema.ColDefs { 279 index := indexwrapper.NewImmutableIndex() 280 if err := index.ReadFrom( 281 n.bnode.bufMgr, 282 n.bnode.fs, 283 n.bnode.meta.AsCommonID(), 284 n.bnode.meta.GetMetaLoc(), 285 schema.ColDefs[i]); err != nil { 286 panic(err) 287 } 288 n.indexes[i] = index 289 if i == pkIdx { 290 n.pkIndex = index 291 } 292 } 293 location := n.bnode.meta.GetMetaLoc() 294 n.rows = uint32(tables.ReadPersistedBlockRow(location)) 295 296 } 297 298 func (n *persistedNode) Rows() uint32 { 299 return n.rows 300 } 301 302 type baseNode struct { 303 bufMgr base.INodeManager 304 fs *objectio.ObjectFS 305 //scheduler is used to flush insertNode into S3/FS. 306 scheduler tasks.TaskScheduler 307 //meta for this uncommitted standalone block. 308 meta *catalog.BlockEntry 309 table *txnTable 310 storage struct { 311 mnode *memoryNode 312 pnode *persistedNode 313 } 314 } 315 316 func newBaseNode( 317 tbl *txnTable, 318 fs *objectio.ObjectFS, 319 mgr base.INodeManager, 320 sched tasks.TaskScheduler, 321 meta *catalog.BlockEntry, 322 ) *baseNode { 323 return &baseNode{ 324 bufMgr: mgr, 325 fs: fs, 326 scheduler: sched, 327 meta: meta, 328 table: tbl, 329 } 330 } 331 332 func (n *baseNode) IsPersisted() bool { 333 return n.meta.HasPersistedData() 334 } 335 336 func (n *baseNode) GetTxn() txnif.AsyncTxn { 337 return n.table.store.txn 338 } 339 340 func (n *baseNode) GetPersistedLoc() (string, string) { 341 return n.meta.GetMetaLoc(), n.meta.GetDeltaLoc() 342 } 343 344 func (n *baseNode) Rows() uint32 { 345 if n.storage.mnode != nil { 346 return n.storage.mnode.rows 347 } else if n.storage.pnode != nil { 348 return n.storage.pnode.Rows() 349 } 350 panic(moerr.NewInternalErrorNoCtx( 351 fmt.Sprintf("bad insertNode %s", n.meta.String()))) 352 } 353 354 func (n *baseNode) TryUpgrade() (err error) { 355 //TODO::update metaloc and deltaloc 356 if n.storage.mnode != nil { 357 n.storage.mnode = nil 358 } 359 if n.storage.pnode == nil { 360 n.storage.pnode = newPersistedNode(n) 361 n.storage.pnode.Ref() 362 } 363 return 364 }