github.com/matrixorigin/matrixone@v0.7.0/pkg/vm/engine/tae/tables/appender.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 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/common" 19 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/containers" 20 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/iface/txnif" 21 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/index" 22 ) 23 24 type blockAppender struct { 25 blk *ablock 26 placeholder uint32 27 rows uint32 28 } 29 30 func newAppender(ablk *ablock) *blockAppender { 31 appender := new(blockAppender) 32 appender.blk = ablk 33 appender.rows = uint32(ablk.Rows()) 34 return appender 35 } 36 37 func (appender *blockAppender) GetMeta() any { 38 return appender.blk.meta 39 } 40 41 func (appender *blockAppender) GetID() *common.ID { 42 return appender.blk.meta.AsCommonID() 43 } 44 45 func (appender *blockAppender) IsAppendable() bool { 46 return appender.rows+appender.placeholder < appender.blk.meta.GetSchema().BlockMaxRows 47 } 48 49 func (appender *blockAppender) Close() { 50 appender.blk.Unref() 51 } 52 func (appender *blockAppender) PrepareAppend( 53 rows uint32, 54 txn txnif.AsyncTxn) (node txnif.AppendNode, created bool, n uint32, err error) { 55 left := appender.blk.meta.GetSchema().BlockMaxRows - appender.rows - appender.placeholder 56 if left == 0 { 57 // n = rows 58 return 59 } 60 if rows > left { 61 n = left 62 } else { 63 n = rows 64 } 65 appender.placeholder += n 66 appender.blk.Lock() 67 defer appender.blk.Unlock() 68 node, created = appender.blk.mvcc.AddAppendNodeLocked( 69 txn, 70 appender.rows, 71 appender.placeholder+appender.rows) 72 return 73 } 74 func (appender *blockAppender) ReplayAppend( 75 bat *containers.Batch, 76 txn txnif.AsyncTxn) (from int, err error) { 77 if from, err = appender.ApplyAppend(bat, txn); err != nil { 78 return 79 } 80 // TODO: Remove ReplayAppend 81 appender.blk.meta.GetSegment().GetTable().AddRows(uint64(bat.Length())) 82 return 83 } 84 func (appender *blockAppender) ApplyAppend( 85 bat *containers.Batch, 86 txn txnif.AsyncTxn) (from int, err error) { 87 n := appender.blk.PinNode() 88 defer n.Unref() 89 90 node := n.MustMNode() 91 appender.blk.Lock() 92 defer appender.blk.Unlock() 93 from, err = node.ApplyAppend(bat, txn) 94 95 schema := appender.blk.meta.GetSchema() 96 keysCtx := new(index.KeysCtx) 97 keysCtx.Count = bat.Length() 98 for _, colDef := range schema.ColDefs { 99 if colDef.IsPhyAddr() { 100 continue 101 } 102 keysCtx.Keys = bat.Vecs[colDef.Idx] 103 if err = node.indexes[colDef.Idx].BatchUpsert(keysCtx, from); err != nil { 104 panic(err) 105 } 106 } 107 return 108 }