github.com/matrixorigin/matrixone@v0.7.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  	"encoding/binary"
    20  	"fmt"
    21  	"io"
    22  
    23  	"github.com/matrixorigin/matrixone/pkg/common/moerr"
    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  func init() {
    30  	txnif.RegisterCmdFactory(txnbase.CmdDelete, func(int16) txnif.TxnCmd {
    31  		return NewEmptyCmd(txnbase.CmdDelete)
    32  	})
    33  	txnif.RegisterCmdFactory(txnbase.CmdAppend, func(int16) txnif.TxnCmd {
    34  		return NewEmptyCmd(txnbase.CmdAppend)
    35  	})
    36  }
    37  
    38  type UpdateCmd struct {
    39  	*txnbase.BaseCustomizedCmd
    40  	dbid    uint64
    41  	dest    *common.ID
    42  	delete  *DeleteNode
    43  	append  *AppendNode
    44  	cmdType int16
    45  }
    46  
    47  func NewEmptyCmd(cmdType int16) *UpdateCmd {
    48  	cmd := &UpdateCmd{}
    49  	cmd.BaseCustomizedCmd = txnbase.NewBaseCustomizedCmd(0, cmd)
    50  	cmd.cmdType = cmdType
    51  	if cmdType == txnbase.CmdDelete {
    52  		cmd.delete = NewDeleteNode(nil, 0)
    53  	} else if cmdType == txnbase.CmdAppend {
    54  		cmd.append = NewAppendNode(nil, 0, 0, nil)
    55  	}
    56  	return cmd
    57  }
    58  
    59  func NewAppendCmd(id uint32, app *AppendNode) *UpdateCmd {
    60  	impl := &UpdateCmd{
    61  		append:  app,
    62  		cmdType: txnbase.CmdAppend,
    63  		dest:    app.mvcc.meta.AsCommonID(),
    64  		dbid:    app.mvcc.meta.GetSegment().GetTable().GetDB().ID,
    65  	}
    66  	impl.BaseCustomizedCmd = txnbase.NewBaseCustomizedCmd(id, impl)
    67  	return impl
    68  }
    69  
    70  func NewDeleteCmd(id uint32, del *DeleteNode) *UpdateCmd {
    71  	impl := &UpdateCmd{
    72  		delete:  del,
    73  		cmdType: txnbase.CmdDelete,
    74  		dest:    del.chain.mvcc.meta.AsCommonID(),
    75  		dbid:    del.chain.mvcc.meta.GetSegment().GetTable().GetDB().ID,
    76  	}
    77  	impl.BaseCustomizedCmd = txnbase.NewBaseCustomizedCmd(id, impl)
    78  	return impl
    79  }
    80  
    81  func (c *UpdateCmd) GetAppendNode() *AppendNode {
    82  	return c.append
    83  }
    84  func (c *UpdateCmd) GetDeleteNode() *DeleteNode {
    85  	return c.delete
    86  }
    87  func (c *UpdateCmd) GetDBID() uint64 {
    88  	return c.dbid
    89  }
    90  
    91  func (c *UpdateCmd) GetDest() *common.ID {
    92  	return c.dest
    93  }
    94  func (c *UpdateCmd) SetReplayTxn(txn txnif.AsyncTxn) {
    95  	switch c.cmdType {
    96  	case txnbase.CmdAppend:
    97  		c.append.Txn = txn
    98  	case txnbase.CmdDelete:
    99  		c.delete.Txn = txn
   100  	default:
   101  		panic(fmt.Sprintf("invalid command type %d", c.cmdType))
   102  	}
   103  }
   104  func (c *UpdateCmd) ApplyCommit() {
   105  	switch c.cmdType {
   106  	case txnbase.CmdAppend:
   107  		if _, err := c.append.TxnMVCCNode.ApplyCommit(nil); err != nil {
   108  			panic(err)
   109  		}
   110  	case txnbase.CmdDelete:
   111  		if _, err := c.delete.TxnMVCCNode.ApplyCommit(nil); err != nil {
   112  			panic(err)
   113  		}
   114  	default:
   115  		panic(fmt.Sprintf("invalid command type %d", c.cmdType))
   116  	}
   117  }
   118  func (c *UpdateCmd) ApplyRollback() {
   119  	switch c.cmdType {
   120  	case txnbase.CmdAppend:
   121  		if err := c.append.ApplyRollback(nil); err != nil {
   122  			panic(err)
   123  		}
   124  	case txnbase.CmdDelete:
   125  		if err := c.delete.ApplyRollback(nil); err != nil {
   126  			panic(err)
   127  		}
   128  	default:
   129  		panic(fmt.Sprintf("invalid command type %d", c.cmdType))
   130  	}
   131  }
   132  func (c *UpdateCmd) Desc() string {
   133  	if c.cmdType == txnbase.CmdAppend {
   134  		return fmt.Sprintf("CmdName=Append;Dest=%s;%s;CSN=%d", c.dest.BlockString(), c.append.GeneralDesc(), c.ID)
   135  	} else if c.cmdType == txnbase.CmdDelete {
   136  		return fmt.Sprintf("CmdName=Delete;Dest=%s;%s;CSN=%d", c.dest.BlockString(), c.delete.GeneralDesc(), c.ID)
   137  	}
   138  	panic(moerr.NewInternalErrorNoCtx("unknown cmd type: %d", c.cmdType))
   139  }
   140  
   141  func (c *UpdateCmd) String() string {
   142  	if c.cmdType == txnbase.CmdAppend {
   143  		return fmt.Sprintf("CmdName=Append;Dest=%s;%s;CSN=%d", c.dest.BlockString(), c.append.GeneralString(), c.ID)
   144  	} else if c.cmdType == txnbase.CmdDelete {
   145  		return fmt.Sprintf("CmdName=Delete;Dest=%s;%s;CSN=%d", c.dest.BlockString(), c.delete.GeneralString(), c.ID)
   146  	}
   147  	panic(moerr.NewInternalErrorNoCtx("unknown cmd type: %d", c.cmdType))
   148  }
   149  
   150  func (c *UpdateCmd) VerboseString() string {
   151  	if c.cmdType == txnbase.CmdAppend {
   152  		return fmt.Sprintf("CmdName=Append;Dest=%s;CSN=%d;%s", c.dest.BlockString(), c.ID, c.append.GeneralVerboseString())
   153  	} else if c.cmdType == txnbase.CmdDelete {
   154  		return fmt.Sprintf("CmdName=Delete;Dest=%s;CSN=%d;%s", c.dest.BlockString(), c.ID, c.delete.GeneralVerboseString())
   155  	}
   156  	panic(moerr.NewInternalErrorNoCtx("unknown cmd type: %d", c.cmdType))
   157  }
   158  
   159  func (c *UpdateCmd) GetType() int16 { return c.cmdType }
   160  
   161  func (c *UpdateCmd) WriteTo(w io.Writer) (n int64, err error) {
   162  	var sn int64
   163  	if err = binary.Write(w, binary.BigEndian, c.GetType()); err != nil {
   164  		return
   165  	}
   166  	if err = binary.Write(w, binary.BigEndian, c.ID); err != nil {
   167  		return
   168  	}
   169  	if err = binary.Write(w, binary.BigEndian, c.dbid); err != nil {
   170  		return
   171  	}
   172  	if err = binary.Write(w, binary.BigEndian, c.dest.TableID); err != nil {
   173  		return
   174  	}
   175  	if err = binary.Write(w, binary.BigEndian, c.dest.SegmentID); err != nil {
   176  		return
   177  	}
   178  	if err = binary.Write(w, binary.BigEndian, c.dest.BlockID); err != nil {
   179  		return
   180  	}
   181  	switch c.GetType() {
   182  	case txnbase.CmdDelete:
   183  		sn, err = c.delete.WriteTo(w)
   184  	case txnbase.CmdAppend:
   185  		sn, err = c.append.WriteTo(w)
   186  	}
   187  	n += sn + 2 + 4
   188  	return
   189  }
   190  
   191  func (c *UpdateCmd) ReadFrom(r io.Reader) (n int64, err error) {
   192  	if err = binary.Read(r, binary.BigEndian, &c.ID); err != nil {
   193  		return
   194  	}
   195  	if err = binary.Read(r, binary.BigEndian, &c.dbid); err != nil {
   196  		return
   197  	}
   198  	c.dest = &common.ID{}
   199  	if err = binary.Read(r, binary.BigEndian, &c.dest.TableID); err != nil {
   200  		return
   201  	}
   202  	if err = binary.Read(r, binary.BigEndian, &c.dest.SegmentID); err != nil {
   203  		return
   204  	}
   205  	if err = binary.Read(r, binary.BigEndian, &c.dest.BlockID); err != nil {
   206  		return
   207  	}
   208  	switch c.GetType() {
   209  	case txnbase.CmdDelete:
   210  		n, err = c.delete.ReadFrom(r)
   211  	case txnbase.CmdAppend:
   212  		n, err = c.append.ReadFrom(r)
   213  	}
   214  	n += 4
   215  	return
   216  }
   217  
   218  func (c *UpdateCmd) Marshal() (buf []byte, err error) {
   219  	var bbuf bytes.Buffer
   220  	if _, err = c.WriteTo(&bbuf); err != nil {
   221  		return
   222  	}
   223  	buf = bbuf.Bytes()
   224  	return
   225  }
   226  
   227  func (c *UpdateCmd) Unmarshal(buf []byte) error {
   228  	bbuf := bytes.NewBuffer(buf)
   229  	_, err := c.ReadFrom(bbuf)
   230  	return err
   231  }