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 }