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 }