github.com/matrixorigin/matrixone@v1.2.0/pkg/vm/engine/tae/txn/txnimpl/anode.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 "context" 19 20 "github.com/matrixorigin/matrixone/pkg/common/mpool" 21 "github.com/matrixorigin/matrixone/pkg/container/nulls" 22 "github.com/matrixorigin/matrixone/pkg/objectio" 23 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/catalog" 24 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/common" 25 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/containers" 26 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/iface/txnif" 27 ) 28 29 // anode corresponds to an appendable standalone-uncommitted block 30 // which belongs to txn's workspace and can be appended data into. 31 type anode struct { 32 *baseNode 33 data *containers.Batch 34 rows uint32 35 appends []*appendInfo 36 } 37 38 // NewANode creates a InsertNode with data in memory. 39 func NewANode( 40 tbl *txnTable, 41 meta *catalog.ObjectEntry, 42 ) *anode { 43 impl := new(anode) 44 impl.baseNode = newBaseNode(tbl, meta) 45 impl.appends = make([]*appendInfo, 0) 46 return impl 47 } 48 49 func (n *anode) Rows() uint32 { 50 return n.rows 51 } 52 53 func (n *anode) GetAppends() []*appendInfo { 54 return n.appends 55 } 56 func (n *anode) AddApplyInfo(srcOff, srcLen, destOff, destLen uint32, dest *common.ID) *appendInfo { 57 seq := len(n.appends) 58 info := &appendInfo{ 59 dest: *dest, 60 destOff: destOff, 61 destLen: destLen, 62 srcOff: srcOff, 63 srcLen: srcLen, 64 seq: uint32(seq), 65 } 66 n.appends = append(n.appends, info) 67 return info 68 } 69 70 func (n *anode) IsPersisted() bool { 71 return false 72 } 73 74 func (n *anode) MakeCommand(id uint32) (cmd txnif.TxnCmd, err error) { 75 if n.data == nil { 76 return 77 } 78 composedCmd := NewAppendCmd(id, n, n.data) 79 return composedCmd, nil 80 } 81 82 func (n *anode) Close() (err error) { 83 if n.data != nil { 84 n.data.Close() 85 n.data = nil 86 } 87 return 88 } 89 90 func (n *anode) PrepareAppend(data *containers.Batch, offset uint32) uint32 { 91 return uint32(data.Length()) - offset 92 } 93 94 func (n *anode) Append(data *containers.Batch, offset uint32) (an uint32, err error) { 95 schema := n.table.GetLocalSchema() 96 if n.data == nil { 97 capacity := data.Length() - int(offset) 98 n.data = containers.BuildBatchWithPool( 99 schema.AllNames(), 100 schema.AllTypes(), 101 capacity, 102 n.table.store.rt.VectorPool.Small, 103 ) 104 105 // n.data = containers.BuildBatch( 106 // schema.AllNames(), 107 // schema.AllTypes(), 108 // containers.Options{ 109 // Capacity: capacity, 110 // }, 111 // ) 112 } 113 114 from := uint32(n.data.Length()) 115 an = n.PrepareAppend(data, offset) 116 for _, attr := range data.Attrs { 117 if attr == catalog.PhyAddrColumnName { 118 continue 119 } 120 def := schema.ColDefs[schema.GetColIdx(attr)] 121 destVec := n.data.Vecs[def.Idx] 122 // logutil.Infof("destVec: %s, %d, %d", destVec.String(), cnt, data.Length()) 123 destVec.ExtendWithOffset(data.Vecs[def.Idx], int(offset), int(an)) 124 } 125 n.rows = uint32(n.data.Length()) 126 err = n.FillPhyAddrColumn(from, an) 127 return 128 } 129 130 func (n *anode) FillPhyAddrColumn(startRow, length uint32) (err error) { 131 col := n.table.store.rt.VectorPool.Small.GetVector(&objectio.RowidType) 132 blkID := objectio.NewBlockidWithObjectID(&n.meta.ID, 0) 133 if err = objectio.ConstructRowidColumnTo( 134 col.GetDownstreamVector(), 135 blkID, startRow, length, 136 col.GetAllocator(), 137 ); err != nil { 138 col.Close() 139 return 140 } 141 err = n.data.Vecs[n.table.GetLocalSchema().PhyAddrKey.Idx].ExtendVec(col.GetDownstreamVector()) 142 col.Close() 143 return 144 } 145 146 func (n *anode) FillBlockView( 147 view *containers.BlockView, colIdxes []int, mp *mpool.MPool, 148 ) (err error) { 149 for _, colIdx := range colIdxes { 150 orig := n.data.Vecs[colIdx] 151 view.SetData(colIdx, orig.CloneWindow(0, orig.Length(), mp)) 152 } 153 view.DeleteMask = n.data.Deletes 154 return 155 } 156 func (n *anode) FillColumnView(view *containers.ColumnView, mp *mpool.MPool) (err error) { 157 orig := n.data.Vecs[view.ColIdx] 158 view.SetData(orig.CloneWindow(0, orig.Length(), mp)) 159 view.DeleteMask = n.data.Deletes 160 return 161 } 162 163 func (n *anode) Compact() { 164 if n.data == nil { 165 return 166 } 167 n.data.Compact() 168 n.rows = uint32(n.data.Length()) 169 } 170 171 func (n *anode) GetValue(col int, row uint32) (any, bool, error) { 172 vec := n.data.Vecs[col] 173 return vec.Get(int(row)), vec.IsNull(int(row)), nil 174 } 175 176 func (n *anode) RangeDelete(start, end uint32) error { 177 n.data.RangeDelete(int(start), int(end+1)) 178 return nil 179 } 180 181 func (n *anode) IsRowDeleted(row uint32) bool { 182 return n.data.IsDeleted(int(row)) 183 } 184 185 func (n *anode) PrintDeletes() string { 186 if !n.data.HasDelete() { 187 return "NoDeletes" 188 } 189 return nulls.String(n.data.Deletes) 190 } 191 192 func (n *anode) WindowColumn(start, end uint32, pos int) (vec containers.Vector, err error) { 193 data := n.data 194 deletes := data.WindowDeletes(int(start), int(end-start), false) 195 if deletes != nil { 196 vec = data.Vecs[pos].CloneWindow(int(start), int(end-start)) 197 vec.CompactByBitmap(deletes) 198 } else { 199 vec = data.Vecs[pos].Window(int(start), int(end-start)) 200 } 201 return 202 } 203 204 func (n *anode) Window(start, end uint32) (bat *containers.Batch, err error) { 205 data := n.data 206 if data.HasDelete() { 207 bat = data.CloneWindow(int(start), int(end-start)) 208 bat.Compact() 209 } else { 210 bat = data.Window(int(start), int(end-start)) 211 } 212 return 213 } 214 215 func (n *anode) GetColumnDataByIds( 216 colIdxes []int, mp *mpool.MPool, 217 ) (view *containers.BlockView, err error) { 218 view = containers.NewBlockView() 219 err = n.FillBlockView(view, colIdxes, mp) 220 return 221 } 222 223 func (n *anode) GetColumnDataById( 224 ctx context.Context, colIdx int, mp *mpool.MPool, 225 ) (view *containers.ColumnView, err error) { 226 view = containers.NewColumnView(colIdx) 227 err = n.FillColumnView(view, mp) 228 return 229 } 230 231 func (n *anode) Prefetch(idxes []uint16) error { 232 return nil 233 }