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  }