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