github.com/matrixorigin/matrixone@v0.7.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 "bytes" 19 "github.com/matrixorigin/matrixone/pkg/objectio" 20 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/buffer/base" 21 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/catalog" 22 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/common" 23 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/containers" 24 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/iface/txnif" 25 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/model" 26 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/tasks" 27 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/txn/txnbase" 28 ) 29 30 // anode corresponds to an appendable standalone-uncommitted block 31 // which belongs to txn's workspace and can be appended data into. 32 type anode struct { 33 *baseNode 34 } 35 36 // NewANode creates a InsertNode with data in memory. 37 func NewANode( 38 tbl *txnTable, 39 fs *objectio.ObjectFS, 40 mgr base.INodeManager, 41 sched tasks.TaskScheduler, 42 meta *catalog.BlockEntry, 43 ) *anode { 44 impl := new(anode) 45 impl.baseNode = newBaseNode(tbl, fs, mgr, sched, meta) 46 impl.storage.mnode = newMemoryNode(impl.baseNode) 47 impl.storage.mnode.Ref() 48 return impl 49 } 50 51 func (n *anode) GetAppends() []*appendInfo { 52 return n.storage.mnode.appends 53 } 54 func (n *anode) AddApplyInfo(srcOff, srcLen, destOff, destLen uint32, dbid uint64, dest *common.ID) *appendInfo { 55 seq := len(n.storage.mnode.appends) 56 info := &appendInfo{ 57 dest: dest, 58 destOff: destOff, 59 destLen: destLen, 60 dbid: dbid, 61 srcOff: srcOff, 62 srcLen: srcLen, 63 seq: uint32(seq), 64 } 65 n.storage.mnode.appends = append(n.storage.mnode.appends, info) 66 return info 67 } 68 69 func (n *anode) MakeCommand(id uint32) (cmd txnif.TxnCmd, err error) { 70 if n.IsPersisted() { 71 return nil, nil 72 } 73 if n.storage.mnode.data == nil { 74 return 75 } 76 composedCmd := NewAppendCmd(id, n) 77 batCmd := txnbase.NewBatchCmd(n.storage.mnode.data) 78 composedCmd.AddCmd(batCmd) 79 return composedCmd, nil 80 } 81 82 func (n *anode) Close() (err error) { 83 if n.storage.mnode.data != nil { 84 n.storage.mnode.data.Close() 85 } 86 return 87 } 88 89 func (n *anode) Append(data *containers.Batch, offset uint32) (an uint32, err error) { 90 schema := n.table.entry.GetSchema() 91 if n.storage.mnode.data == nil { 92 opts := containers.Options{} 93 opts.Capacity = data.Length() - int(offset) 94 if opts.Capacity > int(txnbase.MaxNodeRows) { 95 opts.Capacity = int(txnbase.MaxNodeRows) 96 } 97 n.storage.mnode.data = containers.BuildBatch( 98 schema.AllNames(), 99 schema.AllTypes(), 100 schema.AllNullables(), 101 opts) 102 } 103 104 from := uint32(n.storage.mnode.data.Length()) 105 an = n.storage.mnode.PrepareAppend(data, offset) 106 for _, attr := range data.Attrs { 107 if attr == catalog.PhyAddrColumnName { 108 continue 109 } 110 def := schema.ColDefs[schema.GetColIdx(attr)] 111 destVec := n.storage.mnode.data.Vecs[def.Idx] 112 // logutil.Infof("destVec: %s, %d, %d", destVec.String(), cnt, data.Length()) 113 destVec.ExtendWithOffset(data.Vecs[def.Idx], int(offset), int(an)) 114 } 115 n.storage.mnode.rows = uint32(n.storage.mnode.data.Length()) 116 err = n.storage.mnode.FillPhyAddrColumn(from, an) 117 return 118 } 119 120 func (n *anode) FillBlockView(view *model.BlockView, buffers []*bytes.Buffer, colIdxes []int) (err error) { 121 for i, colIdx := range colIdxes { 122 orig := n.storage.mnode.data.Vecs[colIdx] 123 if buffers[i] != nil { 124 buffers[i].Reset() 125 view.SetData(colIdx, containers.CloneWithBuffer(orig, buffers[i])) 126 } else { 127 view.SetData(colIdx, orig.CloneWindow(0, orig.Length())) 128 } 129 130 } 131 view.DeleteMask = n.storage.mnode.data.Deletes 132 return 133 } 134 func (n *anode) FillColumnView(view *model.ColumnView, buffer *bytes.Buffer) (err error) { 135 orig := n.storage.mnode.data.Vecs[view.ColIdx] 136 if buffer != nil { 137 buffer.Reset() 138 view.SetData(containers.CloneWithBuffer(orig, buffer)) 139 } else { 140 view.SetData(orig.CloneWindow(0, orig.Length())) 141 } 142 view.DeleteMask = n.storage.mnode.data.Deletes 143 return 144 } 145 146 func (n *anode) GetSpace() uint32 { 147 return txnbase.MaxNodeRows - n.storage.mnode.rows 148 } 149 150 func (n *anode) RowsWithoutDeletes() uint32 { 151 deletes := uint32(0) 152 if n.storage.mnode.data != nil && n.storage.mnode.data.Deletes != nil { 153 deletes = uint32(n.storage.mnode.data.DeleteCnt()) 154 } 155 return n.storage.mnode.rows - deletes 156 } 157 158 func (n *anode) LengthWithDeletes(appended, toAppend uint32) uint32 { 159 if !n.storage.mnode.data.HasDelete() { 160 return toAppend 161 } 162 appendedOffset := n.OffsetWithDeletes(appended) 163 toAppendOffset := n.OffsetWithDeletes(toAppend + appended) 164 // logutil.Infof("appened:%d, toAppend:%d, off1=%d, off2=%d", appended, toAppend, appendedOffset, toAppendOffset) 165 return toAppendOffset - appendedOffset 166 } 167 168 func (n *anode) OffsetWithDeletes(count uint32) uint32 { 169 if !n.storage.mnode.data.HasDelete() { 170 return count 171 } 172 offset := count 173 for offset < n.storage.mnode.rows { 174 deletes := n.storage.mnode.data.Deletes.Rank(offset) 175 if offset == count+uint32(deletes) { 176 break 177 } 178 offset = count + uint32(deletes) 179 } 180 return offset 181 } 182 183 func (n *anode) GetValue(col int, row uint32) (any, error) { 184 if !n.IsPersisted() { 185 return n.storage.mnode.data.Vecs[col].Get(int(row)), nil 186 } 187 //TODO:: get value from S3/FS 188 panic("not implemented yet :GetValue from FS/S3 ") 189 } 190 191 func (n *anode) RangeDelete(start, end uint32) error { 192 n.storage.mnode.data.RangeDelete(int(start), int(end+1)) 193 return nil 194 } 195 196 func (n *anode) IsRowDeleted(row uint32) bool { 197 return n.storage.mnode.data.IsDeleted(int(row)) 198 } 199 200 func (n *anode) PrintDeletes() string { 201 if !n.storage.mnode.data.HasDelete() { 202 return "NoDeletes" 203 } 204 return n.storage.mnode.data.Deletes.String() 205 } 206 207 func (n *anode) Window(start, end uint32) (bat *containers.Batch, err error) { 208 bat = n.storage.mnode.data.CloneWindow(int(start), int(end-start)) 209 bat.Compact() 210 return 211 } 212 213 func (n *anode) GetColumnDataByIds( 214 colIdxes []int, 215 buffers []*bytes.Buffer, 216 ) (view *model.BlockView, err error) { 217 if !n.IsPersisted() { 218 view = model.NewBlockView(n.table.store.txn.GetStartTS()) 219 err = n.FillBlockView(view, buffers, colIdxes) 220 return 221 } 222 panic("Not Implemented yet : GetColumnDataByIds from S3/FS ") 223 } 224 225 func (n *anode) GetColumnDataById(colIdx int, buffer *bytes.Buffer) (view *model.ColumnView, err error) { 226 if !n.IsPersisted() { 227 view = model.NewColumnView(n.table.store.txn.GetStartTS(), colIdx) 228 err = n.FillColumnView(view, buffer) 229 return 230 } 231 panic("Not Implemented yet : GetColumnDataByIds from S3/FS ") 232 }