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