github.com/matrixorigin/matrixone@v0.7.0/pkg/vm/engine/tae/logtail/operator.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 logtail
    16  
    17  import (
    18  	"github.com/matrixorigin/matrixone/pkg/common/moerr"
    19  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/catalog"
    20  )
    21  
    22  // BoundTableOperator holds a read only reader, knows how to iter entry.
    23  // Drive a entry visitor, which acts as an api resp builder
    24  type BaseOperator struct {
    25  	catalog *catalog.Catalog
    26  	reader  *Reader
    27  }
    28  
    29  type BoundOperator struct {
    30  	*BaseOperator
    31  	visitor catalog.Processor
    32  }
    33  
    34  func NewBoundOperator(catalog *catalog.Catalog,
    35  	reader *Reader,
    36  	visitor catalog.Processor) *BoundOperator {
    37  	return &BoundOperator{
    38  		BaseOperator: &BaseOperator{
    39  			catalog: catalog,
    40  			reader:  reader,
    41  		},
    42  		visitor: visitor,
    43  	}
    44  }
    45  
    46  func (op *BoundOperator) Run() (err error) {
    47  	var (
    48  		db  *catalog.DBEntry
    49  		tbl *catalog.TableEntry
    50  		seg *catalog.SegmentEntry
    51  		blk *catalog.BlockEntry
    52  	)
    53  	dirty, _ := op.reader.GetDirty()
    54  	for _, tblDirty := range dirty.Tables {
    55  		if db, err = op.catalog.GetDatabaseByID(tblDirty.DbID); err != nil {
    56  			return
    57  		}
    58  		if tbl, err = db.GetTableEntryByID(tblDirty.ID); err != nil {
    59  			return
    60  		}
    61  		for _, dirtySeg := range tblDirty.Segs {
    62  			if seg, err = tbl.GetSegmentByID(dirtySeg.ID); err != nil {
    63  				if moerr.IsMoErrCode(err, moerr.OkExpectedEOB) {
    64  					err = nil
    65  					continue
    66  				}
    67  				return
    68  			}
    69  			if err = op.visitor.OnSegment(seg); err != nil {
    70  				return err
    71  			}
    72  			for id := range dirtySeg.Blks {
    73  				if blk, err = seg.GetBlockEntryByID(id); err != nil {
    74  					if moerr.IsMoErrCode(err, moerr.OkExpectedEOB) {
    75  						err = nil
    76  						continue
    77  					}
    78  					return
    79  				}
    80  				if err = op.visitor.OnBlock(blk); err != nil {
    81  					return err
    82  				}
    83  			}
    84  		}
    85  	}
    86  	return
    87  }
    88  
    89  type BoundTableOperator struct {
    90  	*BoundOperator
    91  	dbID    uint64
    92  	tableID uint64
    93  	scope   Scope
    94  }
    95  
    96  func NewBoundTableOperator(catalog *catalog.Catalog,
    97  	reader *Reader,
    98  	scope Scope,
    99  	dbID, tableID uint64,
   100  	visitor catalog.Processor) *BoundTableOperator {
   101  	return &BoundTableOperator{
   102  		BoundOperator: NewBoundOperator(catalog, reader, visitor),
   103  		tableID:       tableID,
   104  		dbID:          dbID,
   105  		scope:         scope,
   106  	}
   107  }
   108  
   109  func (c *BoundTableOperator) Run() error {
   110  	switch c.scope {
   111  	case ScopeDatabases:
   112  		return c.processDatabases()
   113  	case ScopeTables, ScopeColumns:
   114  		return c.processTables()
   115  	case ScopeUserTables:
   116  		return c.processTableData()
   117  	default:
   118  		panic("unknown logtail collect scope")
   119  	}
   120  }
   121  
   122  func (c *BoundTableOperator) processTableData() (err error) {
   123  	var (
   124  		db  *catalog.DBEntry
   125  		tbl *catalog.TableEntry
   126  		seg *catalog.SegmentEntry
   127  		blk *catalog.BlockEntry
   128  	)
   129  	if db, err = c.catalog.GetDatabaseByID(c.dbID); err != nil {
   130  		return
   131  	}
   132  	if tbl, err = db.GetTableEntryByID(c.tableID); err != nil {
   133  		return
   134  	}
   135  	dirty := c.reader.GetDirtyByTable(c.dbID, c.tableID)
   136  	for _, dirtySeg := range dirty.Segs {
   137  		if seg, err = tbl.GetSegmentByID(dirtySeg.ID); err != nil {
   138  			if moerr.IsMoErrCode(err, moerr.OkExpectedEOB) {
   139  				err = nil
   140  				continue
   141  			}
   142  			return
   143  		}
   144  		if err = c.visitor.OnSegment(seg); err != nil {
   145  			return err
   146  		}
   147  		for id := range dirtySeg.Blks {
   148  			if blk, err = seg.GetBlockEntryByID(id); err != nil {
   149  				if moerr.IsMoErrCode(err, moerr.OkExpectedEOB) {
   150  					err = nil
   151  					continue
   152  				}
   153  				return
   154  			}
   155  			if err = c.visitor.OnBlock(blk); err != nil {
   156  				return err
   157  			}
   158  		}
   159  	}
   160  	return nil
   161  }
   162  
   163  func (c *BoundTableOperator) processDatabases() error {
   164  	if !c.reader.HasCatalogChanges() {
   165  		return nil
   166  	}
   167  	dbIt := c.catalog.MakeDBIt(true)
   168  	for ; dbIt.Valid(); dbIt.Next() {
   169  		dbentry := dbIt.Get().GetPayload()
   170  		if err := c.visitor.OnDatabase(dbentry); err != nil {
   171  			return err
   172  		}
   173  	}
   174  	return nil
   175  }
   176  
   177  func (c *BoundTableOperator) processTables() error {
   178  	if !c.reader.HasCatalogChanges() {
   179  		return nil
   180  	}
   181  	dbIt := c.catalog.MakeDBIt(true)
   182  	for ; dbIt.Valid(); dbIt.Next() {
   183  		db := dbIt.Get().GetPayload()
   184  		tblIt := db.MakeTableIt(true)
   185  		for ; tblIt.Valid(); tblIt.Next() {
   186  			if err := c.visitor.OnTable(tblIt.Get().GetPayload()); err != nil {
   187  				return err
   188  			}
   189  		}
   190  	}
   191  	return nil
   192  }