github.com/matrixorigin/matrixone@v0.7.0/pkg/vm/engine/tae/tables/mnode.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  	"bytes"
    19  
    20  	"github.com/RoaringBitmap/roaring"
    21  	"github.com/matrixorigin/matrixone/pkg/common/moerr"
    22  	"github.com/matrixorigin/matrixone/pkg/logutil"
    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  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/model"
    28  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/tables/indexwrapper"
    29  )
    30  
    31  var _ NodeT = (*memoryNode)(nil)
    32  
    33  type memoryNode struct {
    34  	common.RefHelper
    35  	block  *baseBlock
    36  	data   *containers.Batch
    37  	prefix []byte
    38  
    39  	//index for primary key : Art tree + ZoneMap.
    40  	pkIndex indexwrapper.Index
    41  	//index for non-primary key : ZoneMap.
    42  	indexes map[int]indexwrapper.Index
    43  }
    44  
    45  func newMemoryNode(block *baseBlock) *memoryNode {
    46  	impl := new(memoryNode)
    47  	impl.block = block
    48  	impl.prefix = block.meta.MakeKey()
    49  
    50  	schema := block.meta.GetSchema()
    51  	opts := containers.Options{}
    52  	opts.Allocator = common.MutMemAllocator
    53  	impl.data = containers.BuildBatch(
    54  		schema.AllNames(),
    55  		schema.AllTypes(),
    56  		schema.AllNullables(),
    57  		opts)
    58  	impl.initIndexes(schema)
    59  	impl.OnZeroCB = impl.close
    60  	return impl
    61  }
    62  
    63  func (node *memoryNode) initIndexes(schema *catalog.Schema) {
    64  	node.indexes = make(map[int]indexwrapper.Index)
    65  	for _, def := range schema.ColDefs {
    66  		if def.IsPhyAddr() {
    67  			continue
    68  		}
    69  		if def.IsPrimary() {
    70  			node.indexes[def.Idx] = indexwrapper.NewPkMutableIndex(def.Type)
    71  			node.pkIndex = node.indexes[def.Idx]
    72  		} else {
    73  			node.indexes[def.Idx] = indexwrapper.NewMutableIndex(def.Type)
    74  		}
    75  	}
    76  }
    77  
    78  func (node *memoryNode) close() {
    79  	logutil.Infof("Releasing Memorynode BLK-%d", node.block.meta.ID)
    80  	node.data.Close()
    81  	node.data = nil
    82  	for i, index := range node.indexes {
    83  		index.Close()
    84  		node.indexes[i] = nil
    85  	}
    86  	node.indexes = nil
    87  	node.pkIndex = nil
    88  	node.block = nil
    89  }
    90  
    91  func (node *memoryNode) IsPersisted() bool { return false }
    92  
    93  func (node *memoryNode) BatchDedup(
    94  	keys containers.Vector,
    95  	skipFn func(row uint32) error) (sels *roaring.Bitmap, err error) {
    96  	return node.pkIndex.BatchDedup(keys, skipFn)
    97  }
    98  
    99  func (node *memoryNode) ContainsKey(key any) (ok bool, err error) {
   100  	if err = node.pkIndex.Dedup(key, nil); err != nil {
   101  		return
   102  	}
   103  	if !moerr.IsMoErrCode(err, moerr.OkExpectedPossibleDup) {
   104  		return
   105  	}
   106  	ok = true
   107  	err = nil
   108  	return
   109  }
   110  
   111  func (node *memoryNode) GetValueByRow(row, col int) (v any) {
   112  	return node.data.Vecs[col].Get(row)
   113  }
   114  
   115  func (node *memoryNode) GetRowsByKey(key any) (rows []uint32, err error) {
   116  	return node.pkIndex.GetActiveRow(key)
   117  }
   118  
   119  func (node *memoryNode) Rows() uint32 {
   120  	return uint32(node.data.Length())
   121  }
   122  
   123  func (node *memoryNode) GetColumnDataWindow(
   124  	from uint32,
   125  	to uint32,
   126  	colIdx int,
   127  	buffer *bytes.Buffer,
   128  ) (vec containers.Vector, err error) {
   129  	data := node.data.Vecs[colIdx]
   130  	if buffer != nil {
   131  		data = data.Window(int(from), int(to-from))
   132  		vec = containers.CloneWithBuffer(data, buffer, common.DefaultAllocator)
   133  	} else {
   134  		vec = data.CloneWindow(int(from), int(to-from), common.DefaultAllocator)
   135  	}
   136  	return
   137  }
   138  
   139  func (node *memoryNode) GetDataWindow(
   140  	from, to uint32) (bat *containers.Batch, err error) {
   141  	bat = node.data.CloneWindow(
   142  		int(from),
   143  		int(to-from),
   144  		common.DefaultAllocator)
   145  	return
   146  }
   147  
   148  func (node *memoryNode) PrepareAppend(rows uint32) (n uint32, err error) {
   149  	left := node.block.meta.GetSchema().BlockMaxRows - uint32(node.data.Length())
   150  	if left == 0 {
   151  		err = moerr.NewInternalErrorNoCtx("not appendable")
   152  		return
   153  	}
   154  	if rows > left {
   155  		n = left
   156  	} else {
   157  		n = rows
   158  	}
   159  	return
   160  }
   161  
   162  func (node *memoryNode) FillPhyAddrColumn(startRow, length uint32) (err error) {
   163  	col, err := model.PreparePhyAddrData(
   164  		catalog.PhyAddrColumnType,
   165  		node.prefix,
   166  		startRow,
   167  		length)
   168  	if err != nil {
   169  		return
   170  	}
   171  	defer col.Close()
   172  	vec := node.data.Vecs[node.block.meta.GetSchema().PhyAddrKey.Idx]
   173  	vec.Extend(col)
   174  	return
   175  }
   176  
   177  func (node *memoryNode) ApplyAppend(
   178  	bat *containers.Batch,
   179  	txn txnif.AsyncTxn) (from int, err error) {
   180  	schema := node.block.meta.GetSchema()
   181  	from = int(node.data.Length())
   182  	for srcPos, attr := range bat.Attrs {
   183  		def := schema.ColDefs[schema.GetColIdx(attr)]
   184  		if def.IsPhyAddr() {
   185  			continue
   186  		}
   187  		destVec := node.data.Vecs[def.Idx]
   188  		destVec.Extend(bat.Vecs[srcPos])
   189  	}
   190  	if err = node.FillPhyAddrColumn(
   191  		uint32(from),
   192  		uint32(bat.Length())); err != nil {
   193  		return
   194  	}
   195  	return
   196  }