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 }