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