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  }