github.com/matrixorigin/matrixone@v1.2.0/pkg/vm/engine/tae/tables/updates/cmd.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 updates
    16  
    17  import (
    18  	"bytes"
    19  	"fmt"
    20  	"io"
    21  
    22  	"github.com/matrixorigin/matrixone/pkg/common/moerr"
    23  	"github.com/matrixorigin/matrixone/pkg/container/types"
    24  	"github.com/matrixorigin/matrixone/pkg/objectio"
    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  const (
    31  	IOET_WALTxnCommand_AppendNode          uint16 = 3004
    32  	IOET_WALTxnCommand_DeleteNode          uint16 = 3005
    33  	IOET_WALTxnCommand_PersistedDeleteNode uint16 = 3013
    34  
    35  	IOET_WALTxnCommand_AppendNode_V1          uint16 = 1
    36  	IOET_WALTxnCommand_DeleteNode_V1          uint16 = 1
    37  	IOET_WALTxnCommand_DeleteNode_V2          uint16 = 2
    38  	IOET_WALTxnCommand_PersistedDeleteNode_V1 uint16 = 1
    39  
    40  	IOET_WALTxnCommand_AppendNode_CurrVer          = IOET_WALTxnCommand_AppendNode_V1
    41  	IOET_WALTxnCommand_DeleteNode_CurrVer          = IOET_WALTxnCommand_DeleteNode_V2
    42  	IOET_WALTxnCommand_PersistedDeleteNode_CurrVer = IOET_WALTxnCommand_PersistedDeleteNode_V1
    43  )
    44  
    45  func init() {
    46  	objectio.RegisterIOEnrtyCodec(
    47  		objectio.IOEntryHeader{
    48  			Type:    IOET_WALTxnCommand_AppendNode,
    49  			Version: IOET_WALTxnCommand_AppendNode_V1,
    50  		},
    51  		nil,
    52  		func(b []byte) (any, error) {
    53  			txnCmd := NewEmptyCmd(IOET_WALTxnCommand_AppendNode,
    54  				IOET_WALTxnCommand_AppendNode_V1)
    55  			err := txnCmd.UnmarshalBinary(b)
    56  			return txnCmd, err
    57  		},
    58  	)
    59  	objectio.RegisterIOEnrtyCodec(
    60  		objectio.IOEntryHeader{
    61  			Type:    IOET_WALTxnCommand_DeleteNode,
    62  			Version: IOET_WALTxnCommand_DeleteNode_V1,
    63  		},
    64  		nil,
    65  		func(b []byte) (any, error) {
    66  			txnCmd := NewEmptyCmd(IOET_WALTxnCommand_DeleteNode,
    67  				IOET_WALTxnCommand_DeleteNode_V1)
    68  			err := txnCmd.UnmarshalBinary(b)
    69  			return txnCmd, err
    70  		},
    71  	)
    72  	objectio.RegisterIOEnrtyCodec(
    73  		objectio.IOEntryHeader{
    74  			Type:    IOET_WALTxnCommand_DeleteNode,
    75  			Version: IOET_WALTxnCommand_DeleteNode_V2,
    76  		},
    77  		nil,
    78  		func(b []byte) (any, error) {
    79  			txnCmd := NewEmptyCmd(IOET_WALTxnCommand_DeleteNode,
    80  				IOET_WALTxnCommand_DeleteNode_V2)
    81  			err := txnCmd.UnmarshalBinary(b)
    82  			return txnCmd, err
    83  		},
    84  	)
    85  	objectio.RegisterIOEnrtyCodec(
    86  		objectio.IOEntryHeader{
    87  			Type:    IOET_WALTxnCommand_PersistedDeleteNode,
    88  			Version: IOET_WALTxnCommand_PersistedDeleteNode_V1,
    89  		},
    90  		nil,
    91  		func(b []byte) (any, error) {
    92  			txnCmd := NewEmptyCmd(IOET_WALTxnCommand_PersistedDeleteNode,
    93  				IOET_WALTxnCommand_PersistedDeleteNode_V1)
    94  			err := txnCmd.UnmarshalBinary(b)
    95  			return txnCmd, err
    96  		},
    97  	)
    98  }
    99  
   100  type UpdateCmd struct {
   101  	*txnbase.BaseCustomizedCmd
   102  	dest    *common.ID
   103  	delete  *DeleteNode
   104  	append  *AppendNode
   105  	cmdType uint16
   106  }
   107  
   108  func NewEmptyCmd(cmdType uint16, version uint16) *UpdateCmd {
   109  	cmd := &UpdateCmd{}
   110  	cmd.BaseCustomizedCmd = txnbase.NewBaseCustomizedCmd(0, cmd)
   111  	cmd.cmdType = cmdType
   112  	if cmdType == IOET_WALTxnCommand_DeleteNode {
   113  		cmd.delete = NewDeleteNode(nil, 0, version)
   114  	} else if cmdType == IOET_WALTxnCommand_AppendNode {
   115  		cmd.append = NewAppendNode(nil, 0, 0, nil)
   116  	} else if cmdType == IOET_WALTxnCommand_PersistedDeleteNode {
   117  		cmd.delete = NewEmptyPersistedDeleteNode()
   118  	}
   119  	return cmd
   120  }
   121  
   122  func NewAppendCmd(id uint32, app *AppendNode) *UpdateCmd {
   123  	impl := &UpdateCmd{
   124  		append:  app,
   125  		cmdType: IOET_WALTxnCommand_AppendNode,
   126  		dest:    app.mvcc.meta.AsCommonID(),
   127  	}
   128  	impl.BaseCustomizedCmd = txnbase.NewBaseCustomizedCmd(id, impl)
   129  	return impl
   130  }
   131  
   132  func NewDeleteCmd(id uint32, del *DeleteNode) *UpdateCmd {
   133  	impl := &UpdateCmd{
   134  		delete:  del,
   135  		cmdType: IOET_WALTxnCommand_DeleteNode,
   136  		dest:    del.chain.Load().mvcc.meta.AsCommonID(),
   137  	}
   138  	impl.BaseCustomizedCmd = txnbase.NewBaseCustomizedCmd(id, impl)
   139  	return impl
   140  }
   141  
   142  func NewPersistedDeleteCmd(id uint32, del *DeleteNode) *UpdateCmd {
   143  	impl := &UpdateCmd{
   144  		delete:  del,
   145  		cmdType: IOET_WALTxnCommand_PersistedDeleteNode,
   146  		dest:    del.chain.Load().mvcc.meta.AsCommonID(),
   147  	}
   148  	impl.BaseCustomizedCmd = txnbase.NewBaseCustomizedCmd(id, impl)
   149  	return impl
   150  }
   151  
   152  func (c *UpdateCmd) GetAppendNode() *AppendNode {
   153  	return c.append
   154  }
   155  func (c *UpdateCmd) GetDeleteNode() *DeleteNode {
   156  	return c.delete
   157  }
   158  
   159  func (c *UpdateCmd) GetDest() *common.ID {
   160  	return c.dest
   161  }
   162  func (c *UpdateCmd) SetReplayTxn(txn txnif.AsyncTxn) {
   163  	switch c.cmdType {
   164  	case IOET_WALTxnCommand_AppendNode:
   165  		c.append.Txn = txn
   166  	case IOET_WALTxnCommand_DeleteNode, IOET_WALTxnCommand_PersistedDeleteNode:
   167  		c.delete.Txn = txn
   168  	default:
   169  		panic(fmt.Sprintf("invalid command type %d", c.cmdType))
   170  	}
   171  }
   172  func (c *UpdateCmd) GetCurrentVersion() uint16 {
   173  	switch c.cmdType {
   174  	case IOET_WALTxnCommand_AppendNode:
   175  		return IOET_WALTxnCommand_AppendNode_CurrVer
   176  	case IOET_WALTxnCommand_DeleteNode:
   177  		return IOET_WALTxnCommand_DeleteNode_CurrVer
   178  	case IOET_WALTxnCommand_PersistedDeleteNode:
   179  		return IOET_WALTxnCommand_PersistedDeleteNode_CurrVer
   180  	default:
   181  		panic(fmt.Sprintf("invalid command type %d", c.cmdType))
   182  	}
   183  }
   184  func (c *UpdateCmd) ApplyCommit() {
   185  	switch c.cmdType {
   186  	case IOET_WALTxnCommand_AppendNode:
   187  		if _, err := c.append.TxnMVCCNode.ApplyCommit(); err != nil {
   188  			panic(err)
   189  		}
   190  	case IOET_WALTxnCommand_DeleteNode, IOET_WALTxnCommand_PersistedDeleteNode:
   191  		if _, err := c.delete.TxnMVCCNode.ApplyCommit(); err != nil {
   192  			panic(err)
   193  		}
   194  	default:
   195  		panic(fmt.Sprintf("invalid command type %d", c.cmdType))
   196  	}
   197  }
   198  func (c *UpdateCmd) ApplyRollback() {
   199  	switch c.cmdType {
   200  	case IOET_WALTxnCommand_AppendNode:
   201  		if err := c.append.ApplyRollback(); err != nil {
   202  			panic(err)
   203  		}
   204  	case IOET_WALTxnCommand_DeleteNode, IOET_WALTxnCommand_PersistedDeleteNode:
   205  		if err := c.delete.ApplyRollback(); err != nil {
   206  			panic(err)
   207  		}
   208  	default:
   209  		panic(fmt.Sprintf("invalid command type %d", c.cmdType))
   210  	}
   211  }
   212  func (c *UpdateCmd) Desc() string {
   213  	switch c.cmdType {
   214  	case IOET_WALTxnCommand_AppendNode:
   215  		return fmt.Sprintf("CmdName=Append;Dest=%s;%s;CSN=%d", c.dest.BlockString(), c.append.GeneralDesc(), c.ID)
   216  	case IOET_WALTxnCommand_DeleteNode, IOET_WALTxnCommand_PersistedDeleteNode:
   217  		return fmt.Sprintf("CmdName=Delete;Dest=%s;%s;CSN=%d", c.dest.BlockString(), c.delete.GeneralDesc(), c.ID)
   218  	}
   219  	panic(moerr.NewInternalErrorNoCtx("unknown cmd type: %d", c.cmdType))
   220  }
   221  
   222  func (c *UpdateCmd) String() string {
   223  	switch c.cmdType {
   224  	case IOET_WALTxnCommand_AppendNode:
   225  		return fmt.Sprintf("CmdName=Append;Dest=%s;%s;CSN=%d", c.dest.BlockString(), c.append.GeneralString(), c.ID)
   226  	case IOET_WALTxnCommand_DeleteNode, IOET_WALTxnCommand_PersistedDeleteNode:
   227  		return fmt.Sprintf("CmdName=Delete;Dest=%s;%s;CSN=%d", c.dest.BlockString(), c.delete.GeneralString(), c.ID)
   228  	}
   229  	panic(moerr.NewInternalErrorNoCtx("unknown cmd type: %d", c.cmdType))
   230  }
   231  
   232  func (c *UpdateCmd) VerboseString() string {
   233  	switch c.cmdType {
   234  	case IOET_WALTxnCommand_AppendNode:
   235  		return fmt.Sprintf("CmdName=Append;Dest=%s;CSN=%d;%s", c.dest.BlockString(), c.ID, c.append.GeneralVerboseString())
   236  	case IOET_WALTxnCommand_DeleteNode, IOET_WALTxnCommand_PersistedDeleteNode:
   237  		return fmt.Sprintf("CmdName=Delete;Dest=%s;CSN=%d;%s", c.dest.BlockString(), c.ID, c.delete.GeneralVerboseString())
   238  	}
   239  	panic(moerr.NewInternalErrorNoCtx("unknown cmd type: %d", c.cmdType))
   240  }
   241  
   242  func (c *UpdateCmd) GetType() uint16 { return c.cmdType }
   243  
   244  func (c *UpdateCmd) WriteTo(w io.Writer) (n int64, err error) {
   245  	var sn int64
   246  	if _, err = w.Write(types.EncodeUint16(&c.cmdType)); err != nil {
   247  		return
   248  	}
   249  	ver := c.GetCurrentVersion()
   250  	if _, err = w.Write(types.EncodeUint16(&ver)); err != nil {
   251  		return
   252  	}
   253  
   254  	if _, err = w.Write(types.EncodeUint32(&c.ID)); err != nil {
   255  		return
   256  	}
   257  	n += 6
   258  	if _, err = w.Write(common.EncodeID(c.dest)); err != nil {
   259  		return
   260  	}
   261  	n += common.IDSize
   262  	switch c.GetType() {
   263  	case IOET_WALTxnCommand_DeleteNode, IOET_WALTxnCommand_PersistedDeleteNode:
   264  		sn, err = c.delete.WriteTo(w)
   265  	case IOET_WALTxnCommand_AppendNode:
   266  		sn, err = c.append.WriteTo(w)
   267  	}
   268  	n += sn
   269  	return
   270  }
   271  
   272  func (c *UpdateCmd) ReadFrom(r io.Reader) (n int64, err error) {
   273  	if _, err = r.Read(types.EncodeUint32(&c.ID)); err != nil {
   274  		return
   275  	}
   276  	c.dest = &common.ID{}
   277  	if _, err = r.Read(common.EncodeID(c.dest)); err != nil {
   278  		return
   279  	}
   280  	switch c.GetType() {
   281  	case IOET_WALTxnCommand_DeleteNode, IOET_WALTxnCommand_PersistedDeleteNode:
   282  		n, err = c.delete.ReadFrom(r)
   283  	case IOET_WALTxnCommand_AppendNode:
   284  		n, err = c.append.ReadFrom(r)
   285  	}
   286  	n += 4 + common.IDSize
   287  	return
   288  }
   289  
   290  func (c *UpdateCmd) MarshalBinary() (buf []byte, err error) {
   291  	var bbuf bytes.Buffer
   292  	if _, err = c.WriteTo(&bbuf); err != nil {
   293  		return
   294  	}
   295  	buf = bbuf.Bytes()
   296  	return
   297  }
   298  
   299  func (c *UpdateCmd) UnmarshalBinary(buf []byte) error {
   300  	bbuf := bytes.NewBuffer(buf)
   301  	_, err := c.ReadFrom(bbuf)
   302  	return err
   303  }