github.com/matrixorigin/matrixone@v1.2.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/catalog"
    19  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/common"
    20  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/containers"
    21  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/iface/txnif"
    22  )
    23  
    24  type objectAppender struct {
    25  	obj         *aobject
    26  	placeholder uint32
    27  	rows        uint32
    28  }
    29  
    30  func newAppender(aobj *aobject) *objectAppender {
    31  	appender := new(objectAppender)
    32  	appender.obj = aobj
    33  	rows, _ := aobj.Rows()
    34  	appender.rows = uint32(rows)
    35  	return appender
    36  }
    37  
    38  func (appender *objectAppender) GetMeta() any {
    39  	return appender.obj.meta
    40  }
    41  
    42  func (appender *objectAppender) LockFreeze() {
    43  	appender.obj.freezelock.Lock()
    44  }
    45  func (appender *objectAppender) UnlockFreeze() {
    46  	appender.obj.freezelock.Unlock()
    47  }
    48  func (appender *objectAppender) CheckFreeze() bool {
    49  	return appender.obj.frozen.Load()
    50  }
    51  
    52  func (appender *objectAppender) GetID() *common.ID {
    53  	return appender.obj.meta.AsCommonID()
    54  }
    55  
    56  func (appender *objectAppender) IsAppendable() bool {
    57  	return appender.rows+appender.placeholder < appender.obj.meta.GetSchema().BlockMaxRows
    58  }
    59  
    60  func (appender *objectAppender) Close() {
    61  	appender.obj.Unref()
    62  }
    63  
    64  func (appender *objectAppender) IsSameColumns(other any) bool {
    65  	n := appender.obj.PinNode()
    66  	defer n.Unref()
    67  	return n.MustMNode().writeSchema.IsSameColumns(other.(*catalog.Schema))
    68  }
    69  
    70  func (appender *objectAppender) PrepareAppend(
    71  	rows uint32,
    72  	txn txnif.AsyncTxn) (node txnif.AppendNode, created bool, n uint32, err error) {
    73  	left := appender.obj.meta.GetSchema().BlockMaxRows - appender.rows - appender.placeholder
    74  	if left == 0 {
    75  		// n = rows
    76  		return
    77  	}
    78  	if rows > left {
    79  		n = left
    80  	} else {
    81  		n = rows
    82  	}
    83  	appender.obj.Lock()
    84  	defer appender.obj.Unlock()
    85  	node, created = appender.obj.appendMVCC.AddAppendNodeLocked(
    86  		txn,
    87  		appender.rows+appender.placeholder,
    88  		appender.placeholder+appender.rows+n)
    89  	appender.placeholder += n
    90  	return
    91  }
    92  func (appender *objectAppender) ReplayAppend(
    93  	bat *containers.Batch,
    94  	txn txnif.AsyncTxn) (from int, err error) {
    95  	if from, err = appender.ApplyAppend(bat, txn); err != nil {
    96  		return
    97  	}
    98  	// TODO: Remove ReplayAppend
    99  	appender.obj.meta.GetTable().AddRows(uint64(bat.Length()))
   100  	return
   101  }
   102  func (appender *objectAppender) ApplyAppend(
   103  	bat *containers.Batch,
   104  	txn txnif.AsyncTxn) (from int, err error) {
   105  	n := appender.obj.PinNode()
   106  	defer n.Unref()
   107  
   108  	node := n.MustMNode()
   109  	appender.obj.Lock()
   110  	defer appender.obj.Unlock()
   111  	from, err = node.ApplyAppend(bat, txn)
   112  
   113  	schema := node.writeSchema
   114  	for _, colDef := range schema.ColDefs {
   115  		if colDef.IsPhyAddr() {
   116  			continue
   117  		}
   118  		if colDef.IsRealPrimary() && !schema.IsSecondaryIndexTable() {
   119  			if err = node.pkIndex.BatchUpsert(bat.Vecs[colDef.Idx].GetDownstreamVector(), from); err != nil {
   120  				panic(err)
   121  			}
   122  		}
   123  	}
   124  	return
   125  }