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  }