github.com/matrixorigin/matrixone@v1.2.0/pkg/vm/engine/tae/catalog/command.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  	"bytes"
    19  	"fmt"
    20  	"io"
    21  
    22  	"github.com/matrixorigin/matrixone/pkg/container/types"
    23  	"github.com/matrixorigin/matrixone/pkg/objectio"
    24  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/common"
    25  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/iface/txnif"
    26  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/txn/txnbase"
    27  )
    28  
    29  const (
    30  	IOET_WALTxnCommand_Database uint16 = 3009
    31  	IOET_WALTxnCommand_Table    uint16 = 3010
    32  	IOET_WALTxnCommand_Segment  uint16 = 3011
    33  	IOET_WALTxnCommand_Block    uint16 = 3012
    34  	IOET_WALTxnCommand_Object   uint16 = 3015
    35  
    36  	IOET_WALTxnCommand_Database_V1 uint16 = 1
    37  	IOET_WALTxnCommand_Table_V1    uint16 = 1
    38  	IOET_WALTxnCommand_Table_V2    uint16 = 2
    39  	IOET_WALTxnCommand_Table_V3    uint16 = 3
    40  	IOET_WALTxnCommand_Segment_V1  uint16 = 1
    41  	IOET_WALTxnCommand_Block_V1    uint16 = 1
    42  	IOET_WALTxnCommand_Object_V1   uint16 = 1
    43  
    44  	IOET_WALTxnCommand_Database_CurrVer = IOET_WALTxnCommand_Database_V1
    45  	IOET_WALTxnCommand_Table_CurrVer    = IOET_WALTxnCommand_Table_V3
    46  	IOET_WALTxnCommand_Segment_CurrVer  = IOET_WALTxnCommand_Segment_V1
    47  	IOET_WALTxnCommand_Block_CurrVer    = IOET_WALTxnCommand_Block_V1
    48  	IOET_WALTxnCommand_Object_CurrVer   = IOET_WALTxnCommand_Object_V1
    49  )
    50  
    51  var cmdNames = map[uint16]string{
    52  	IOET_WALTxnCommand_Database: "UDB",
    53  	IOET_WALTxnCommand_Table:    "UTBL",
    54  	IOET_WALTxnCommand_Segment:  "USEG",
    55  	IOET_WALTxnCommand_Block:    "UBLK",
    56  	IOET_WALTxnCommand_Object:   "UOBJ",
    57  }
    58  
    59  func CmdName(t uint16) string {
    60  	return cmdNames[t]
    61  }
    62  
    63  func init() {
    64  	objectio.RegisterIOEnrtyCodec(
    65  		objectio.IOEntryHeader{
    66  			Type:    IOET_WALTxnCommand_Database,
    67  			Version: IOET_WALTxnCommand_Database_V1,
    68  		}, nil,
    69  		func(b []byte) (any, error) {
    70  			cmd := newEmptyEntryCmd(IOET_WALTxnCommand_Database,
    71  				NewEmptyMVCCNodeFactory(NewEmptyEmptyMVCCNode),
    72  				func() *DBNode { return &DBNode{} },
    73  				IOET_WALTxnCommand_Database_V1)
    74  			err := cmd.UnmarshalBinary(b)
    75  			return cmd, err
    76  		},
    77  	)
    78  	objectio.RegisterIOEnrtyCodec(
    79  		objectio.IOEntryHeader{
    80  			Type:    IOET_WALTxnCommand_Table,
    81  			Version: IOET_WALTxnCommand_Table_V1,
    82  		}, nil,
    83  		func(b []byte) (any, error) {
    84  			cmd := newEmptyEntryCmd(IOET_WALTxnCommand_Table,
    85  				NewEmptyMVCCNodeFactory(NewEmptyTableMVCCNode),
    86  				func() *TableNode { return &TableNode{} },
    87  				IOET_WALTxnCommand_Table_V1)
    88  			err := cmd.UnmarshalBinary(b)
    89  			return cmd, err
    90  		},
    91  	)
    92  	objectio.RegisterIOEnrtyCodec(
    93  		objectio.IOEntryHeader{
    94  			Type:    IOET_WALTxnCommand_Table,
    95  			Version: IOET_WALTxnCommand_Table_V2,
    96  		}, nil,
    97  		func(b []byte) (any, error) {
    98  			cmd := newEmptyEntryCmd(IOET_WALTxnCommand_Table,
    99  				NewEmptyMVCCNodeFactory(NewEmptyTableMVCCNode),
   100  				func() *TableNode { return &TableNode{} },
   101  				IOET_WALTxnCommand_Table_V2)
   102  			err := cmd.UnmarshalBinary(b)
   103  			return cmd, err
   104  		},
   105  	)
   106  	objectio.RegisterIOEnrtyCodec(
   107  		objectio.IOEntryHeader{
   108  			Type:    IOET_WALTxnCommand_Table,
   109  			Version: IOET_WALTxnCommand_Table_V3,
   110  		}, nil,
   111  		func(b []byte) (any, error) {
   112  			cmd := newEmptyEntryCmd(IOET_WALTxnCommand_Table,
   113  				NewEmptyMVCCNodeFactory(NewEmptyTableMVCCNode),
   114  				func() *TableNode { return &TableNode{} },
   115  				IOET_WALTxnCommand_Table_V3)
   116  			err := cmd.UnmarshalBinary(b)
   117  			return cmd, err
   118  		},
   119  	)
   120  	objectio.RegisterIOEnrtyCodec(
   121  		objectio.IOEntryHeader{
   122  			Type:    IOET_WALTxnCommand_Segment,
   123  			Version: IOET_WALTxnCommand_Segment_V1,
   124  		}, nil,
   125  		func(b []byte) (any, error) {
   126  			cmd := newEmptyEntryCmd(IOET_WALTxnCommand_Segment,
   127  				NewEmptyMVCCNodeFactory(NewEmptyMetadataMVCCNode),
   128  				func() *ObjectNode { return &ObjectNode{} },
   129  				IOET_WALTxnCommand_Segment_V1)
   130  			err := cmd.UnmarshalBinary(b)
   131  			return cmd, err
   132  		},
   133  	)
   134  	objectio.RegisterIOEnrtyCodec(
   135  		objectio.IOEntryHeader{
   136  			Type:    IOET_WALTxnCommand_Block,
   137  			Version: IOET_WALTxnCommand_Block_V1,
   138  		}, nil,
   139  		func(b []byte) (any, error) {
   140  			cmd := newEmptyEntryCmd(IOET_WALTxnCommand_Block,
   141  				NewEmptyMVCCNodeFactory(NewEmptyMetadataMVCCNode),
   142  				func() *BlockNode { return &BlockNode{} },
   143  				IOET_WALTxnCommand_Block_V1)
   144  			err := cmd.UnmarshalBinary(b)
   145  			return cmd, err
   146  		},
   147  	)
   148  	objectio.RegisterIOEnrtyCodec(
   149  		objectio.IOEntryHeader{
   150  			Type:    IOET_WALTxnCommand_Object,
   151  			Version: IOET_WALTxnCommand_Object_V1,
   152  		}, nil,
   153  		func(b []byte) (any, error) {
   154  			cmd := newEmptyEntryCmd(IOET_WALTxnCommand_Object,
   155  				NewEmptyMVCCNodeFactory(NewEmptyObjectMVCCNode),
   156  				func() *ObjectNode { return &ObjectNode{} },
   157  				IOET_WALTxnCommand_Object_V1)
   158  			err := cmd.UnmarshalBinary(b)
   159  			return cmd, err
   160  		},
   161  	)
   162  }
   163  
   164  type Node interface {
   165  	WriteTo(w io.Writer) (n int64, err error)
   166  	ReadFrom(r io.Reader) (n int64, err error)
   167  }
   168  
   169  type EntryCommand[T BaseNode[T], N Node] struct {
   170  	*txnbase.BaseCustomizedCmd
   171  	cmdType  uint16
   172  	version  uint16
   173  	ID       *common.ID
   174  	mvccNode *MVCCNode[T]
   175  	node     N
   176  }
   177  
   178  func newEmptyEntryCmd[T BaseNode[T], N Node](cmdType uint16, mvccNodeFactory func() *MVCCNode[T], nodeFactory func() N, ver uint16) *EntryCommand[T, N] {
   179  	impl := &EntryCommand[T, N]{
   180  		cmdType:  cmdType,
   181  		ID:       &common.ID{},
   182  		mvccNode: mvccNodeFactory(),
   183  		node:     nodeFactory(),
   184  		version:  ver,
   185  	}
   186  	impl.BaseCustomizedCmd = txnbase.NewBaseCustomizedCmd(0, impl)
   187  	return impl
   188  }
   189  
   190  func NewDeltalocCmd(id uint32, cmdType uint16, commonID *common.ID, baseEntry *BaseEntryImpl[*MetadataMVCCNode]) *EntryCommand[*MetadataMVCCNode, *BlockNode] {
   191  	impl := &EntryCommand[*MetadataMVCCNode, *BlockNode]{
   192  		ID:       commonID,
   193  		cmdType:  cmdType,
   194  		mvccNode: baseEntry.GetLatestNodeLocked(),
   195  		node:     &BlockNode{},
   196  	}
   197  	impl.BaseCustomizedCmd = txnbase.NewBaseCustomizedCmd(id, impl)
   198  	return impl
   199  }
   200  
   201  func newObjectCmd(id uint32, cmdType uint16, entry *ObjectEntry) *EntryCommand[*ObjectMVCCNode, *ObjectNode] {
   202  	impl := &EntryCommand[*ObjectMVCCNode, *ObjectNode]{
   203  		ID:       entry.AsCommonID(),
   204  		cmdType:  cmdType,
   205  		mvccNode: entry.BaseEntryImpl.GetLatestNodeLocked(),
   206  		node:     entry.ObjectNode,
   207  	}
   208  	impl.BaseCustomizedCmd = txnbase.NewBaseCustomizedCmd(id, impl)
   209  	return impl
   210  }
   211  
   212  func newTableCmd(id uint32, cmdType uint16, entry *TableEntry) *EntryCommand[*TableMVCCNode, *TableNode] {
   213  	impl := &EntryCommand[*TableMVCCNode, *TableNode]{
   214  		ID:       entry.AsCommonID(),
   215  		cmdType:  cmdType,
   216  		mvccNode: entry.BaseEntryImpl.GetLatestNodeLocked(),
   217  		node:     entry.TableNode,
   218  	}
   219  	impl.BaseCustomizedCmd = txnbase.NewBaseCustomizedCmd(id, impl)
   220  	return impl
   221  }
   222  
   223  func newDBCmd(id uint32, cmdType uint16, entry *DBEntry) *EntryCommand[*EmptyMVCCNode, *DBNode] {
   224  	impl := &EntryCommand[*EmptyMVCCNode, *DBNode]{
   225  		ID:       entry.AsCommonID(),
   226  		cmdType:  cmdType,
   227  		node:     entry.DBNode,
   228  		mvccNode: entry.GetLatestNodeLocked(),
   229  	}
   230  	// if entry != nil {
   231  	// 	impl.mvccNode = entry.BaseEntryImpl.GetLatestNodeLocked().(*MVCCNode[*DBMVCCNode])
   232  	// }
   233  	impl.BaseCustomizedCmd = txnbase.NewBaseCustomizedCmd(id, impl)
   234  	return impl
   235  }
   236  
   237  func (cmd *EntryCommand[T, N]) Desc() string {
   238  	s := fmt.Sprintf("CmdName=%s;%s;TS=%s;CSN=%d", CmdName(cmd.cmdType), cmd.IDString(), cmd.GetTs().ToString(), cmd.ID)
   239  	return s
   240  }
   241  
   242  func (cmd *EntryCommand[T, N]) SetReplayTxn(txn txnif.AsyncTxn) {
   243  	cmd.mvccNode.Txn = txn
   244  }
   245  
   246  func (cmd *EntryCommand[T, N]) ApplyCommit() {
   247  	if cmd.mvccNode.Is1PC() {
   248  		return
   249  	}
   250  	if err := cmd.mvccNode.ApplyCommit(); err != nil {
   251  		panic(err)
   252  	}
   253  }
   254  
   255  func (cmd *EntryCommand[T, N]) ApplyRollback() {
   256  	if cmd.mvccNode.Is1PC() {
   257  		return
   258  	}
   259  	cmd.mvccNode.ApplyRollback()
   260  }
   261  
   262  func (cmd *EntryCommand[T, N]) GetTs() types.TS {
   263  	ts := cmd.mvccNode.GetPrepare()
   264  	return ts
   265  }
   266  
   267  func (cmd *EntryCommand[T, N]) IDString() string {
   268  	s := ""
   269  	id := cmd.GetID()
   270  	switch cmd.cmdType {
   271  	case IOET_WALTxnCommand_Database:
   272  		s = fmt.Sprintf("%sCommonID=%s", s, id.DBString())
   273  	case IOET_WALTxnCommand_Table:
   274  		s = fmt.Sprintf("%sCommonID=%s", s, id.TableString())
   275  	case IOET_WALTxnCommand_Segment:
   276  		s = fmt.Sprintf("%sCommonID=%s", s, id.ObjectString())
   277  	case IOET_WALTxnCommand_Object:
   278  		s = fmt.Sprintf("%sCommonID=%s", s, id.ObjectString())
   279  	case IOET_WALTxnCommand_Block:
   280  		s = fmt.Sprintf("%sCommonID=%s", s, id.BlockString())
   281  	}
   282  	return s
   283  }
   284  func (cmd *EntryCommand[T, N]) GetID() *common.ID {
   285  	return cmd.ID
   286  }
   287  
   288  func (cmd *EntryCommand[T, N]) String() string {
   289  	s := fmt.Sprintf("CmdName=%s;%s;TS=%s;CSN=%d;BaseEntry=%s", CmdName(cmd.cmdType), cmd.IDString(), cmd.GetTs().ToString(), cmd.ID, cmd.mvccNode.String())
   290  	return s
   291  }
   292  
   293  func (cmd *EntryCommand[T, N]) VerboseString() string {
   294  	s := fmt.Sprintf("CmdName=%s;%s;TS=%s;CSN=%d;BaseEntry=%s", CmdName(cmd.cmdType), cmd.IDString(), cmd.GetTs().ToString(), cmd.ID, cmd.mvccNode.String())
   295  	return s
   296  }
   297  func (cmd *EntryCommand[T, N]) GetType() uint16 { return cmd.cmdType }
   298  func (cmd *EntryCommand[T, N]) GetCurrVersion() uint16 {
   299  	switch cmd.cmdType {
   300  	case IOET_WALTxnCommand_Database:
   301  		return IOET_WALTxnCommand_Database_CurrVer
   302  	case IOET_WALTxnCommand_Table:
   303  		return IOET_WALTxnCommand_Table_CurrVer
   304  	case IOET_WALTxnCommand_Object:
   305  		return IOET_WALTxnCommand_Object_CurrVer
   306  	case IOET_WALTxnCommand_Segment:
   307  		return IOET_WALTxnCommand_Segment_CurrVer
   308  	case IOET_WALTxnCommand_Block:
   309  		return IOET_WALTxnCommand_Block_CurrVer
   310  	default:
   311  		panic(fmt.Sprintf("not support type %d", cmd.cmdType))
   312  	}
   313  }
   314  
   315  func (cmd *EntryCommand[T, N]) WriteTo(w io.Writer) (n int64, err error) {
   316  	t := cmd.GetType()
   317  	if _, err = w.Write(types.EncodeUint16(&t)); err != nil {
   318  		return
   319  	}
   320  	n += 2
   321  	ver := cmd.GetCurrVersion()
   322  	if _, err = w.Write(types.EncodeUint16(&ver)); err != nil {
   323  		return
   324  	}
   325  	n += 2
   326  	var sn2 int
   327  	if sn2, err = w.Write(common.EncodeID(cmd.ID)); err != nil {
   328  		return
   329  	}
   330  	n += int64(sn2)
   331  	var sn int64
   332  	if sn, err = cmd.mvccNode.WriteTo(w); err != nil {
   333  		return
   334  	}
   335  	n += sn
   336  	if sn, err = cmd.node.WriteTo(w); err != nil {
   337  		return
   338  	}
   339  	n += sn
   340  	return
   341  }
   342  func (cmd *EntryCommand[T, N]) MarshalBinary() (buf []byte, err error) {
   343  	var bbuf bytes.Buffer
   344  	if _, err = cmd.WriteTo(&bbuf); err != nil {
   345  		return
   346  	}
   347  	buf = bbuf.Bytes()
   348  	return
   349  }
   350  func (cmd *EntryCommand[T, N]) ReadFrom(r io.Reader) (n int64, err error) {
   351  	var sn2 int
   352  	if sn2, err = r.Read(common.EncodeID(cmd.ID)); err != nil {
   353  		return
   354  	}
   355  	n += int64(sn2)
   356  	var sn int64
   357  	if sn, err = cmd.mvccNode.ReadFromWithVersion(r, cmd.version); err != nil {
   358  		return
   359  	}
   360  	n += sn
   361  	if sn, err = cmd.node.ReadFrom(r); err != nil {
   362  		return
   363  	}
   364  	n += sn
   365  	return
   366  }
   367  
   368  func (cmd *EntryCommand[T, N]) UnmarshalBinary(buf []byte) (err error) {
   369  	bbuf := bytes.NewBuffer(buf)
   370  	_, err = cmd.ReadFrom(bbuf)
   371  	return
   372  }