github.com/matrixorigin/matrixone@v0.7.0/pkg/vm/engine/tae/catalog/tablebase.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 catalog
    16  
    17  import (
    18  	"encoding/binary"
    19  	"fmt"
    20  	"io"
    21  	"sync"
    22  
    23  	"github.com/matrixorigin/matrixone/pkg/common/moerr"
    24  	"github.com/matrixorigin/matrixone/pkg/container/types"
    25  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/common"
    26  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/iface/txnif"
    27  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/txn/txnbase"
    28  )
    29  
    30  type TableBaseEntry struct {
    31  	*txnbase.MVCCChain
    32  	ID uint64
    33  }
    34  
    35  func NewReplayTableBaseEntry() *TableBaseEntry {
    36  	be := &TableBaseEntry{
    37  		MVCCChain: txnbase.NewMVCCChain(CompareTableBaseNode, NewEmptyTableMVCCNode),
    38  	}
    39  	return be
    40  }
    41  
    42  func NewTableBaseEntry(id uint64) *TableBaseEntry {
    43  	return &TableBaseEntry{
    44  		ID:        id,
    45  		MVCCChain: txnbase.NewMVCCChain(CompareTableBaseNode, NewEmptyTableMVCCNode),
    46  	}
    47  }
    48  
    49  func (be *TableBaseEntry) StringLocked() string {
    50  	return fmt.Sprintf("[%d]%s", be.ID, be.MVCCChain.StringLocked())
    51  }
    52  
    53  func (be *TableBaseEntry) String() string {
    54  	be.RLock()
    55  	defer be.RUnlock()
    56  	return be.StringLocked()
    57  }
    58  
    59  func (be *TableBaseEntry) PPString(level common.PPLevel, depth int, prefix string) string {
    60  	s := fmt.Sprintf("%s%s%s", common.RepeatStr("\t", depth), prefix, be.StringLocked())
    61  	return s
    62  }
    63  
    64  func (be *TableBaseEntry) TryGetTerminatedTS(waitIfcommitting bool) (terminated bool, TS types.TS) {
    65  	node := be.GetLatestCommittedNode()
    66  	if node == nil {
    67  		return
    68  	}
    69  	if node.(*TableMVCCNode).HasDropCommitted() {
    70  		return true, node.(*TableMVCCNode).DeletedAt
    71  	}
    72  	return
    73  }
    74  func (be *TableBaseEntry) GetID() uint64 { return be.ID }
    75  
    76  func (be *TableBaseEntry) CreateWithTS(ts types.TS) {
    77  	node := &TableMVCCNode{
    78  		EntryMVCCNode: &EntryMVCCNode{
    79  			CreatedAt: ts,
    80  		},
    81  		TxnMVCCNode: txnbase.NewTxnMVCCNodeWithTS(ts),
    82  	}
    83  	be.Insert(node)
    84  }
    85  
    86  func (be *TableBaseEntry) CreateWithTxn(txn txnif.AsyncTxn, schema *Schema) {
    87  	node := &TableMVCCNode{
    88  		EntryMVCCNode: &EntryMVCCNode{
    89  			CreatedAt: txnif.UncommitTS,
    90  		},
    91  		TxnMVCCNode:       txnbase.NewTxnMVCCNodeWithTxn(txn),
    92  		SchemaConstraints: string(schema.Constraint),
    93  	}
    94  	be.Insert(node)
    95  }
    96  
    97  func (be *TableBaseEntry) getOrSetUpdateNode(txn txnif.TxnReader) (newNode bool, node *TableMVCCNode) {
    98  	entry := be.GetLatestNodeLocked()
    99  	if entry.IsSameTxn(txn.GetStartTS()) {
   100  		return false, entry.(*TableMVCCNode)
   101  	} else {
   102  		node := entry.CloneData().(*TableMVCCNode)
   103  		node.TxnMVCCNode = txnbase.NewTxnMVCCNodeWithTxn(txn)
   104  		be.Insert(node)
   105  		return true, node
   106  	}
   107  }
   108  
   109  func (be *TableBaseEntry) DeleteLocked(txn txnif.TxnReader) (isNewNode bool, err error) {
   110  	var entry *TableMVCCNode
   111  	isNewNode, entry = be.getOrSetUpdateNode(txn)
   112  	entry.Delete()
   113  	return
   114  }
   115  
   116  func (be *TableBaseEntry) UpdateConstraint(txn txnif.TxnReader, cstr []byte) (isNewNode bool, err error) {
   117  	be.Lock()
   118  	defer be.Unlock()
   119  	needWait, txnToWait := be.NeedWaitCommitting(txn.GetStartTS())
   120  	if needWait {
   121  		be.Unlock()
   122  		txnToWait.GetTxnState(true)
   123  		be.Lock()
   124  	}
   125  	err = be.CheckConflict(txn)
   126  	if err != nil {
   127  		return
   128  	}
   129  	var entry *TableMVCCNode
   130  	isNewNode, entry = be.getOrSetUpdateNode(txn)
   131  	entry.SchemaConstraints = string(cstr)
   132  	return
   133  }
   134  
   135  func (be *TableBaseEntry) DeleteBefore(ts types.TS) bool {
   136  	createAt := be.GetDeleteAt()
   137  	if createAt.IsEmpty() {
   138  		return false
   139  	}
   140  	return createAt.Less(ts)
   141  }
   142  
   143  func (be *TableBaseEntry) NeedWaitCommitting(startTS types.TS) (bool, txnif.TxnReader) {
   144  	un := be.GetLatestNodeLocked()
   145  	if un == nil {
   146  		return false, nil
   147  	}
   148  	return un.NeedWaitCommitting(startTS)
   149  }
   150  
   151  func (be *TableBaseEntry) HasDropCommitted() bool {
   152  	be.RLock()
   153  	defer be.RUnlock()
   154  	return be.HasDropCommittedLocked()
   155  }
   156  
   157  func (be *TableBaseEntry) HasDropCommittedLocked() bool {
   158  	un := be.GetLatestCommittedNode()
   159  	if un == nil {
   160  		return false
   161  	}
   162  	return un.(*TableMVCCNode).HasDropCommitted()
   163  }
   164  
   165  func (be *TableBaseEntry) DoCompre(voe BaseEntry) int {
   166  	oe := voe.(*TableBaseEntry)
   167  	be.RLock()
   168  	defer be.RUnlock()
   169  	oe.RLock()
   170  	defer oe.RUnlock()
   171  	return CompareUint64(be.ID, oe.ID)
   172  }
   173  
   174  func (be *TableBaseEntry) ensureVisibleAndNotDropped(ts types.TS) bool {
   175  	visible, dropped := be.GetVisibilityLocked(ts)
   176  	if !visible {
   177  		return false
   178  	}
   179  	return !dropped
   180  }
   181  
   182  func (be *TableBaseEntry) GetVisibilityLocked(ts types.TS) (visible, dropped bool) {
   183  	un := be.GetVisibleNode(ts)
   184  	if un == nil {
   185  		return
   186  	}
   187  	visible = true
   188  	if un.IsSameTxn(ts) {
   189  		dropped = un.(*TableMVCCNode).HasDropIntent()
   190  	} else {
   191  		dropped = un.(*TableMVCCNode).HasDropCommitted()
   192  	}
   193  	return
   194  }
   195  
   196  func (be *TableBaseEntry) IsVisible(ts types.TS, mu *sync.RWMutex) (ok bool, err error) {
   197  	needWait, txnToWait := be.NeedWaitCommitting(ts)
   198  	if needWait {
   199  		mu.RUnlock()
   200  		txnToWait.GetTxnState(true)
   201  		mu.RLock()
   202  	}
   203  	ok = be.ensureVisibleAndNotDropped(ts)
   204  	return
   205  }
   206  
   207  func (be *TableBaseEntry) DropEntryLocked(txnCtx txnif.TxnReader) (isNewNode bool, err error) {
   208  	err = be.CheckConflict(txnCtx)
   209  	if err != nil {
   210  		return
   211  	}
   212  	if be.HasDropCommittedLocked() {
   213  		return false, moerr.GetOkExpectedEOB()
   214  	}
   215  	isNewNode, err = be.DeleteLocked(txnCtx)
   216  	return
   217  }
   218  
   219  func (be *TableBaseEntry) PrepareAdd(txn txnif.TxnReader) (err error) {
   220  	be.RLock()
   221  	defer be.RUnlock()
   222  	if txn != nil {
   223  		needWait, waitTxn := be.NeedWaitCommitting(txn.GetStartTS())
   224  		if needWait {
   225  			be.RUnlock()
   226  			waitTxn.GetTxnState(true)
   227  			be.RLock()
   228  		}
   229  		err = be.CheckConflict(txn)
   230  		if err != nil {
   231  			return
   232  		}
   233  	}
   234  	if txn == nil || be.GetTxn() != txn {
   235  		if !be.HasDropCommittedLocked() {
   236  			return moerr.GetOkExpectedDup()
   237  		}
   238  	} else {
   239  		if be.ensureVisibleAndNotDropped(txn.GetStartTS()) {
   240  			return moerr.GetOkExpectedDup()
   241  		}
   242  	}
   243  	return
   244  }
   245  
   246  func (be *TableBaseEntry) DeleteAfter(ts types.TS) bool {
   247  	un := be.GetLatestNodeLocked()
   248  	if un == nil {
   249  		return false
   250  	}
   251  	return un.(*TableMVCCNode).DeletedAt.Greater(ts)
   252  }
   253  
   254  func (be *TableBaseEntry) CloneCommittedInRange(start, end types.TS) BaseEntry {
   255  	chain := be.MVCCChain.CloneCommittedInRange(start, end)
   256  	if chain == nil {
   257  		return nil
   258  	}
   259  	return &TableBaseEntry{
   260  		MVCCChain: chain,
   261  		ID:        be.ID,
   262  	}
   263  }
   264  
   265  func (be *TableBaseEntry) GetCreatedAt() types.TS {
   266  	un := be.GetLatestNodeLocked()
   267  	if un == nil {
   268  		return types.TS{}
   269  	}
   270  	return un.(*TableMVCCNode).CreatedAt
   271  }
   272  
   273  func (be *TableBaseEntry) GetDeleteAt() types.TS {
   274  	un := be.GetLatestNodeLocked()
   275  	if un == nil {
   276  		return types.TS{}
   277  	}
   278  	return un.(*TableMVCCNode).DeletedAt
   279  }
   280  
   281  func (be *TableBaseEntry) GetVisibility(ts types.TS) (visible, dropped bool) {
   282  	be.RLock()
   283  	defer be.RUnlock()
   284  	needWait, txnToWait := be.NeedWaitCommitting(ts)
   285  	if needWait {
   286  		be.RUnlock()
   287  		txnToWait.GetTxnState(true)
   288  		be.RLock()
   289  	}
   290  	return be.GetVisibilityLocked(ts)
   291  }
   292  func (be *TableBaseEntry) WriteOneNodeTo(w io.Writer) (n int64, err error) {
   293  	if err = binary.Write(w, binary.BigEndian, be.ID); err != nil {
   294  		return
   295  	}
   296  	n += 8
   297  	var sn int64
   298  	sn, err = be.MVCCChain.WriteOneNodeTo(w)
   299  	if err != nil {
   300  		return
   301  	}
   302  	n += sn
   303  	return
   304  }
   305  func (be *TableBaseEntry) WriteAllTo(w io.Writer) (n int64, err error) {
   306  	if err = binary.Write(w, binary.BigEndian, be.ID); err != nil {
   307  		return
   308  	}
   309  	n += 8
   310  	var sn int64
   311  	sn, err = be.MVCCChain.WriteAllTo(w)
   312  	if err != nil {
   313  		return
   314  	}
   315  	n += sn
   316  	return
   317  }
   318  func (be *TableBaseEntry) ReadOneNodeFrom(r io.Reader) (n int64, err error) {
   319  	if err = binary.Read(r, binary.BigEndian, &be.ID); err != nil {
   320  		return
   321  	}
   322  	n += 8
   323  	var sn int64
   324  	sn, err = be.MVCCChain.ReadOneNodeFrom(r)
   325  	if err != nil {
   326  		return
   327  	}
   328  	n += sn
   329  	return
   330  }
   331  func (be *TableBaseEntry) ReadAllFrom(r io.Reader) (n int64, err error) {
   332  	if err = binary.Read(r, binary.BigEndian, &be.ID); err != nil {
   333  		return
   334  	}
   335  	n += 8
   336  	var sn int64
   337  	sn, err = be.MVCCChain.ReadAllFrom(r)
   338  	if err != nil {
   339  		return
   340  	}
   341  	n += sn
   342  	return
   343  }