github.com/matrixorigin/matrixone@v1.2.0/pkg/vm/engine/tae/model/tree.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 model 16 17 import ( 18 "bytes" 19 "encoding/hex" 20 "fmt" 21 "io" 22 "unsafe" 23 24 "github.com/matrixorigin/matrixone/pkg/common/moerr" 25 "github.com/matrixorigin/matrixone/pkg/container/types" 26 "github.com/matrixorigin/matrixone/pkg/objectio" 27 ) 28 29 const ( 30 MemoTreeVersion1 uint16 = iota 31 MemoTreeVersion2 32 MemoTreeVersion3 33 ) 34 35 type keyT struct { 36 Num, Seq uint16 37 } 38 39 func encodeKey(k *keyT) []byte { 40 return unsafe.Slice((*byte)(unsafe.Pointer(k)), 4) 41 } 42 43 type TreeVisitor interface { 44 VisitTable(dbID, id uint64) error 45 VisitObject(uint64, uint64, *objectio.ObjectId) error 46 VisitBlock(uint64, uint64, *objectio.ObjectId, uint16) error 47 String() string 48 } 49 50 type BaseTreeVisitor struct { 51 TableFn func(uint64, uint64) error 52 ObjectFn func(uint64, uint64, *objectio.ObjectId) error 53 BlockFn func(uint64, uint64, *objectio.ObjectId, uint16) error 54 } 55 56 func (visitor *BaseTreeVisitor) String() string { return "" } 57 58 func (visitor *BaseTreeVisitor) VisitTable(dbID, tableID uint64) (err error) { 59 if visitor.TableFn != nil { 60 return visitor.TableFn(dbID, tableID) 61 } 62 return 63 } 64 65 func (visitor *BaseTreeVisitor) VisitObject(dbID, tableID uint64, ObjectID *objectio.ObjectId) (err error) { 66 if visitor.ObjectFn != nil { 67 return visitor.ObjectFn(dbID, tableID, ObjectID) 68 } 69 return 70 } 71 72 func (visitor *BaseTreeVisitor) VisitBlock( 73 dbID, tableID uint64, ObjectID *objectio.ObjectId, Seq uint16) (err error) { 74 if visitor.BlockFn != nil { 75 return visitor.BlockFn(dbID, tableID, ObjectID, Seq) 76 } 77 return 78 } 79 80 type stringVisitor struct { 81 buf bytes.Buffer 82 } 83 84 func (visitor *stringVisitor) VisitTable(dbID, id uint64) (err error) { 85 if visitor.buf.Len() != 0 { 86 _ = visitor.buf.WriteByte('\n') 87 } 88 _, _ = visitor.buf.WriteString(fmt.Sprintf("Tree-TBL(%d,%d)", dbID, id)) 89 return 90 } 91 92 func (visitor *stringVisitor) VisitObject(dbID, tableID uint64, id *objectio.ObjectId) (err error) { 93 _, _ = visitor.buf.WriteString(fmt.Sprintf("\nTree-OBJ[%s]", id.String())) 94 return 95 } 96 97 func (visitor *stringVisitor) VisitBlock(dbID, tableID uint64, ObjectID *objectio.ObjectId, Seq uint16) (err error) { 98 _, _ = visitor.buf.WriteString(fmt.Sprintf(" BLK[%d]", Seq)) 99 return 100 } 101 102 func (visitor *stringVisitor) String() string { 103 if visitor.buf.Len() == 0 { 104 return "<Empty Tree>" 105 } 106 return visitor.buf.String() 107 } 108 109 type Tree struct { 110 Tables map[uint64]*TableTree 111 } 112 113 type TableTree struct { 114 DbID uint64 115 ID uint64 116 Objs map[objectio.ObjectId]*ObjectTree 117 } 118 119 type ObjectTree struct { 120 ID *objectio.ObjectId 121 } 122 123 func NewTree() *Tree { 124 return &Tree{ 125 Tables: make(map[uint64]*TableTree), 126 } 127 } 128 129 func NewTableTree(dbID, id uint64) *TableTree { 130 return &TableTree{ 131 DbID: dbID, 132 ID: id, 133 Objs: make(map[objectio.ObjectId]*ObjectTree), 134 } 135 } 136 137 func NewObjectTree(id *objectio.ObjectId) *ObjectTree { 138 return &ObjectTree{ 139 ID: id, 140 } 141 } 142 143 func (tree *Tree) Reset() { 144 tree.Tables = make(map[uint64]*TableTree) 145 } 146 147 func (tree *Tree) String() string { 148 visitor := new(stringVisitor) 149 _ = tree.Visit(visitor) 150 return visitor.String() 151 } 152 153 func (tree *Tree) visitTable(visitor TreeVisitor, table *TableTree) (err error) { 154 for _, Object := range table.Objs { 155 if err = visitor.VisitObject(table.DbID, table.ID, Object.ID); err != nil { 156 if moerr.IsMoErrCode(err, moerr.OkStopCurrRecur) { 157 err = nil 158 continue 159 } 160 return 161 } 162 } 163 return 164 } 165 166 func (tree *Tree) Visit(visitor TreeVisitor) (err error) { 167 for _, table := range tree.Tables { 168 if err = visitor.VisitTable(table.DbID, table.ID); err != nil { 169 if moerr.IsMoErrCode(err, moerr.OkStopCurrRecur) { 170 err = nil 171 continue 172 } 173 return 174 } 175 if err = tree.visitTable(visitor, table); err != nil { 176 return 177 } 178 } 179 return 180 } 181 func (tree *Tree) IsEmpty() bool { return tree.TableCount() == 0 } 182 func (tree *Tree) TableCount() int { return len(tree.Tables) } 183 func (tree *Tree) GetTable(id uint64) *TableTree { return tree.Tables[id] } 184 func (tree *Tree) HasTable(id uint64) bool { 185 _, found := tree.Tables[id] 186 return found 187 } 188 189 func (tree *Tree) Equal(o *Tree) bool { 190 if tree == nil && o == nil { 191 return true 192 } else if tree == nil || o == nil { 193 return false 194 } 195 if len(tree.Tables) != len(o.Tables) { 196 return false 197 } 198 for id, table := range tree.Tables { 199 if otable, found := o.Tables[id]; !found { 200 return false 201 } else { 202 if !table.Equal(otable) { 203 return false 204 } 205 } 206 } 207 return true 208 } 209 func (tree *Tree) AddTable(dbID, id uint64) { 210 if _, exist := tree.Tables[id]; !exist { 211 table := NewTableTree(dbID, id) 212 tree.Tables[id] = table 213 } 214 } 215 216 func (tree *Tree) AddObject(dbID, tableID uint64, id *objectio.ObjectId) { 217 var table *TableTree 218 var exist bool 219 if table, exist = tree.Tables[tableID]; !exist { 220 table = NewTableTree(dbID, tableID) 221 tree.Tables[tableID] = table 222 } 223 table.AddObject(id) 224 } 225 226 func (tree *Tree) Shrink(tableID uint64) (empty bool) { 227 delete(tree.Tables, tableID) 228 empty = tree.IsEmpty() 229 return 230 } 231 232 func (tree *Tree) GetObject(tableID uint64, objID types.Objectid) *ObjectTree { 233 table := tree.GetTable(tableID) 234 if table == nil { 235 return nil 236 } 237 return table.GetObject(objID) 238 } 239 240 func (tree *Tree) Compact() (empty bool) { 241 toDelete := make([]uint64, 0) 242 for id, table := range tree.Tables { 243 if table.Compact() { 244 toDelete = append(toDelete, id) 245 } 246 } 247 for _, id := range toDelete { 248 delete(tree.Tables, id) 249 } 250 empty = tree.IsEmpty() 251 return 252 } 253 254 func (tree *Tree) Merge(ot *Tree) { 255 if ot == nil { 256 return 257 } 258 for _, ott := range ot.Tables { 259 t, found := tree.Tables[ott.ID] 260 if !found { 261 t = NewTableTree(ott.DbID, ott.ID) 262 tree.Tables[ott.ID] = t 263 } 264 t.Merge(ott) 265 } 266 } 267 268 func (tree *Tree) WriteTo(w io.Writer) (n int64, err error) { 269 cnt := uint32(len(tree.Tables)) 270 if _, err = w.Write(types.EncodeUint32(&cnt)); err != nil { 271 return 272 } 273 n += 4 274 var tmpn int64 275 for _, table := range tree.Tables { 276 if tmpn, err = table.WriteTo(w); err != nil { 277 return 278 } 279 n += tmpn 280 } 281 return 282 } 283 284 func (tree *Tree) ReadFromWithVersion(r io.Reader, ver uint16) (n int64, err error) { 285 var cnt uint32 286 if _, err = r.Read(types.EncodeUint32(&cnt)); err != nil { 287 return 288 } 289 n += 4 290 if cnt == 0 { 291 return 292 } 293 var tmpn int64 294 for i := 0; i < int(cnt); i++ { 295 table := NewTableTree(0, 0) 296 if tmpn, err = table.ReadFromWithVersion(r, ver); err != nil { 297 return 298 } 299 tree.Tables[table.ID] = table 300 n += tmpn 301 } 302 return 303 } 304 func (ttree *TableTree) GetObject(id types.Objectid) *ObjectTree { 305 return ttree.Objs[id] 306 } 307 308 func (ttree *TableTree) AddObject(sid *objectio.ObjectId) { 309 id := *sid 310 if _, exist := ttree.Objs[id]; !exist { 311 ttree.Objs[id] = NewObjectTree(&id) 312 } 313 } 314 315 func (ttree *TableTree) ShortBlocksString() string { 316 buf := bytes.Buffer{} 317 for _, obj := range ttree.Objs { 318 var shortuuid [8]byte 319 hex.Encode(shortuuid[:], obj.ID[:4]) 320 buf.WriteString(fmt.Sprintf(" %s-%d", string(shortuuid[:]), obj.ID.Offset())) 321 } 322 return buf.String() 323 } 324 325 func (ttree *TableTree) IsEmpty() bool { 326 return len(ttree.Objs) == 0 327 } 328 329 func (ttree *TableTree) Shrink(objID types.Objectid) (empty bool) { 330 delete(ttree.Objs, objID) 331 empty = len(ttree.Objs) == 0 332 return 333 } 334 335 func (ttree *TableTree) Compact() (empty bool) { 336 empty = len(ttree.Objs) == 0 337 return 338 } 339 340 func (ttree *TableTree) Merge(ot *TableTree) { 341 if ot == nil { 342 return 343 } 344 if ot.ID != ttree.ID { 345 panic(fmt.Sprintf("Cannot merge 2 different table tree: %d, %d", ttree.ID, ot.ID)) 346 } 347 for _, obj := range ot.Objs { 348 ttree.AddObject(obj.ID) 349 } 350 } 351 352 func (ttree *TableTree) WriteTo(w io.Writer) (n int64, err error) { 353 if _, err = w.Write(types.EncodeUint64(&ttree.DbID)); err != nil { 354 return 355 } 356 if _, err = w.Write(types.EncodeUint64(&ttree.ID)); err != nil { 357 return 358 } 359 cnt := uint32(len(ttree.Objs)) 360 if _, err = w.Write(types.EncodeUint32(&cnt)); err != nil { 361 return 362 } 363 n += 8 + 8 + 4 364 var tmpn int64 365 for _, obj := range ttree.Objs { 366 if tmpn, err = obj.WriteTo(w); err != nil { 367 return 368 } 369 n += tmpn 370 } 371 return 372 } 373 374 func (ttree *TableTree) ReadFromWithVersion(r io.Reader, ver uint16) (n int64, err error) { 375 if _, err = r.Read(types.EncodeUint64(&ttree.DbID)); err != nil { 376 return 377 } 378 if _, err = r.Read(types.EncodeUint64(&ttree.ID)); err != nil { 379 return 380 } 381 var cnt uint32 382 if _, err = r.Read(types.EncodeUint32(&cnt)); err != nil { 383 return 384 } 385 n += 8 + 8 + 4 386 if cnt == 0 { 387 return 388 } 389 var tmpn int64 390 for i := 0; i < int(cnt); i++ { 391 id := objectio.NewObjectid() 392 if ver < MemoTreeVersion2 { 393 objs, tmpn, err := ReadObjectTreesV1(r) 394 if err != nil { 395 return n, err 396 } 397 for _, obj := range objs { 398 ttree.Objs[*obj.ID] = obj 399 } 400 n += tmpn 401 402 } else if ver < MemoTreeVersion3 { 403 obj := NewObjectTree(id) 404 if tmpn, err = obj.ReadFromV2(r); err != nil { 405 return 406 } 407 ttree.Objs[*obj.ID] = obj 408 n += tmpn 409 } else { 410 obj := NewObjectTree(id) 411 if tmpn, err = obj.ReadFromV3(r); err != nil { 412 return 413 } 414 ttree.Objs[*obj.ID] = obj 415 n += tmpn 416 417 } 418 } 419 return 420 } 421 422 func (ttree *TableTree) Equal(o *TableTree) bool { 423 if ttree == nil && o == nil { 424 return true 425 } else if ttree == nil || o == nil { 426 return false 427 } 428 if ttree.ID != o.ID || ttree.DbID != o.DbID { 429 return false 430 } 431 if len(ttree.Objs) != len(o.Objs) { 432 return false 433 } 434 for id, obj := range ttree.Objs { 435 if oobj, found := o.Objs[id]; !found { 436 return false 437 } else { 438 if !obj.Equal(oobj) { 439 return false 440 } 441 } 442 } 443 return true 444 } 445 446 func (stree *ObjectTree) Merge(ot *ObjectTree) { 447 if ot == nil { 448 return 449 } 450 if !stree.ID.Eq(*ot.ID) { 451 panic(fmt.Sprintf("Cannot merge 2 different obj tree: %d, %d", stree.ID, ot.ID)) 452 } 453 } 454 455 func (stree *ObjectTree) Equal(o *ObjectTree) bool { 456 if stree == nil && o == nil { 457 return true 458 } else if stree == nil || o == nil { 459 return false 460 } 461 return stree.ID.Eq(*o.ID) 462 } 463 464 func (stree *ObjectTree) WriteTo(w io.Writer) (n int64, err error) { 465 if _, err = w.Write(stree.ID[:]); err != nil { 466 return 467 } 468 n += int64(types.UuidSize) 469 return 470 } 471 472 func ReadObjectTreesV1(r io.Reader) (strees []*ObjectTree, n int64, err error) { 473 segmentID := new(types.Segmentid) 474 if _, err = r.Read(segmentID[:]); err != nil { 475 return 476 } 477 n += int64(types.UuidSize) 478 var cnt uint32 479 if _, err = r.Read(types.EncodeUint32(&cnt)); err != nil { 480 return 481 } 482 n += 4 483 if cnt == 0 { 484 return 485 } 486 numSeqMap := make(map[uint16][]uint16) 487 var id keyT 488 for i := 0; i < int(cnt); i++ { 489 if _, err = r.Read(encodeKey(&id)); err != nil { 490 return 491 } 492 seqs, ok := numSeqMap[id.Num] 493 if !ok { 494 seqs = make([]uint16, 0) 495 } 496 seqs = append(seqs, id.Seq) 497 numSeqMap[id.Num] = seqs 498 } 499 n += 4 * int64(cnt) 500 501 return 502 } 503 504 func (stree *ObjectTree) ReadFromV2(r io.Reader) (n int64, err error) { 505 if _, err = r.Read(stree.ID[:]); err != nil { 506 return 507 } 508 n += int64(types.UuidSize) 509 var cnt uint32 510 if _, err = r.Read(types.EncodeUint32(&cnt)); err != nil { 511 return 512 } 513 n += 4 514 if cnt == 0 { 515 return 516 } 517 var id uint16 518 for i := 0; i < int(cnt); i++ { 519 if _, err = r.Read(types.EncodeUint16(&id)); err != nil { 520 return 521 } 522 } 523 n += 4 * int64(cnt) 524 return 525 } 526 527 func (stree *ObjectTree) ReadFromV3(r io.Reader) (n int64, err error) { 528 if _, err = r.Read(stree.ID[:]); err != nil { 529 return 530 } 531 n += int64(types.UuidSize) 532 return 533 }