github.com/matrixorigin/matrixone@v1.2.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 iterate catalog entries. 23 type BoundTableOperator struct { 24 catalog *catalog.Catalog 25 reader *Reader 26 visitor catalog.Processor 27 dbID uint64 28 tableID uint64 29 scope Scope 30 } 31 32 func NewBoundTableOperator(catalog *catalog.Catalog, 33 reader *Reader, 34 scope Scope, 35 dbID, tableID uint64, 36 visitor catalog.Processor) *BoundTableOperator { 37 return &BoundTableOperator{ 38 catalog: catalog, 39 reader: reader, 40 visitor: visitor, 41 tableID: tableID, 42 dbID: dbID, 43 scope: scope, 44 } 45 } 46 47 // Run takes a RespBuilder to visit every table/Object/block touched by all txn 48 // in the Reader. During the visiting, RespBuiler will fetch information to return logtail entry 49 func (c *BoundTableOperator) Run() error { 50 switch c.scope { 51 case ScopeDatabases: 52 return c.processDatabases() 53 case ScopeTables, ScopeColumns: 54 return c.processTables() 55 case ScopeUserTables: 56 return c.processTableData() 57 default: 58 panic("unknown logtail collect scope") 59 } 60 } 61 62 // For normal user table, pick out all dirty blocks and call OnBlock 63 func (c *BoundTableOperator) processTableData() error { 64 db, err := c.catalog.GetDatabaseByID(c.dbID) 65 if err != nil { 66 return err 67 } 68 tbl, err := db.GetTableEntryByID(c.tableID) 69 if err != nil { 70 return err 71 } 72 dirty := c.reader.GetDirtyByTable(c.dbID, c.tableID) 73 for _, dirtyObj := range dirty.Objs { 74 obj, err := tbl.GetObjectByID(dirtyObj.ID) 75 if err != nil { 76 if moerr.IsMoErrCode(err, moerr.OkExpectedEOB) { 77 continue 78 } 79 return err 80 } 81 if err = c.visitor.OnObject(obj); err != nil { 82 return err 83 } 84 85 } 86 tombstones := tbl.GetDeleteList().Copy().Items() 87 for _, deletes := range tombstones { 88 err = c.visitor.OnTombstone(deletes) 89 if err != nil { 90 return err 91 } 92 } 93 return nil 94 } 95 96 // For mo_database, iterate over all database and call OnBlock. 97 // TODO: avoid iterating all. For now it is acceptable because all catalog is in 98 // memory and ddl is much smaller than dml 99 func (c *BoundTableOperator) processDatabases() error { 100 if !c.reader.HasCatalogChanges() { 101 return nil 102 } 103 dbIt := c.catalog.MakeDBIt(true) 104 for ; dbIt.Valid(); dbIt.Next() { 105 dbentry := dbIt.Get().GetPayload() 106 if err := c.visitor.OnDatabase(dbentry); err != nil { 107 return err 108 } 109 } 110 return nil 111 } 112 113 // For mo_table and mo_columns, iterate over all tables and call OnTable 114 // TODO: avoid iterating all. For now it is acceptable because all catalog is in 115 // memory and ddl is much smaller than dml 116 func (c *BoundTableOperator) processTables() error { 117 if !c.reader.HasCatalogChanges() { 118 return nil 119 } 120 dbIt := c.catalog.MakeDBIt(true) 121 for ; dbIt.Valid(); dbIt.Next() { 122 db := dbIt.Get().GetPayload() 123 tblIt := db.MakeTableIt(true) 124 for ; tblIt.Valid(); tblIt.Next() { 125 if err := c.visitor.OnTable(tblIt.Get().GetPayload()); err != nil { 126 return err 127 } 128 } 129 } 130 return nil 131 }