github.com/matrixorigin/matrixone@v1.2.0/pkg/incrservice/table_cache.go (about) 1 // Copyright 2023 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 incrservice 16 17 import ( 18 "context" 19 "sync" 20 21 "github.com/matrixorigin/matrixone/pkg/common/log" 22 "github.com/matrixorigin/matrixone/pkg/container/batch" 23 "github.com/matrixorigin/matrixone/pkg/txn/client" 24 ) 25 26 type tableCache struct { 27 logger *log.MOLogger 28 tableID uint64 29 cols []AutoColumn 30 31 mu struct { 32 sync.RWMutex 33 committed bool 34 txnOp client.TxnOperator 35 cols map[string]*columnCache 36 } 37 } 38 39 func newTableCache( 40 ctx context.Context, 41 tableID uint64, 42 cols []AutoColumn, 43 cfg Config, 44 allocator valueAllocator, 45 txnOp client.TxnOperator, 46 committed bool) (incrTableCache, error) { 47 c := &tableCache{ 48 logger: getLogger(), 49 tableID: tableID, 50 cols: cols, 51 } 52 c.mu.cols = make(map[string]*columnCache, 1) 53 c.mu.txnOp = txnOp 54 c.mu.committed = committed 55 for _, col := range cols { 56 cc, err := newColumnCache( 57 ctx, 58 tableID, 59 col, 60 cfg, 61 committed, 62 allocator, 63 txnOp) 64 if err != nil { 65 return nil, err 66 } 67 c.mu.cols[col.ColName] = cc 68 } 69 return c, nil 70 } 71 72 func (c *tableCache) commit() { 73 c.mu.Lock() 74 defer c.mu.Unlock() 75 if c.mu.committed { 76 panic("commit already committed cache") 77 } 78 c.mu.committed = true 79 c.mu.txnOp = nil 80 for _, col := range c.mu.cols { 81 col.Lock() 82 col.committed = true 83 col.Unlock() 84 } 85 } 86 87 func (c *tableCache) getTxn() client.TxnOperator { 88 c.mu.Lock() 89 defer c.mu.Unlock() 90 return c.mu.txnOp 91 } 92 93 func (c *tableCache) insertAutoValues( 94 ctx context.Context, 95 tableID uint64, 96 bat *batch.Batch, 97 estimate int64, 98 ) (uint64, error) { 99 lastInsert := uint64(0) 100 txnOp := c.getTxn() 101 for _, col := range c.cols { 102 cc := c.getColumnCache(col.ColName) 103 if cc == nil { 104 panic("column cache should not be nil, " + col.ColName) 105 } 106 107 if estimate > int64(cc.cfg.CountPerAllocate) { 108 cc.preAllocate(ctx, tableID, int(estimate), txnOp) 109 } 110 111 rows := bat.RowCount() 112 vec := bat.GetVector(int32(col.ColIndex)) 113 if v, err := cc.insertAutoValues(ctx, tableID, vec, rows, txnOp); err != nil { 114 return 0, err 115 } else { 116 lastInsert = v 117 } 118 } 119 return lastInsert, nil 120 } 121 122 func (c *tableCache) currentValue( 123 ctx context.Context, 124 tableID uint64, 125 targetCol string) (uint64, error) { 126 for _, col := range c.cols { 127 if col.ColName == targetCol { 128 cc := c.getColumnCache(col.ColName) 129 if cc == nil { 130 panic("column cache should not be nil, " + col.ColName) 131 } 132 return cc.current(ctx) 133 } 134 } 135 return 0, nil 136 } 137 138 func (c *tableCache) table() uint64 { 139 return c.tableID 140 } 141 142 func (c *tableCache) columns() []AutoColumn { 143 return c.cols 144 } 145 146 func (c *tableCache) getColumnCache(col string) *columnCache { 147 c.mu.RLock() 148 defer c.mu.RUnlock() 149 return c.mu.cols[col] 150 } 151 152 func (c *tableCache) close() error { 153 c.mu.Lock() 154 defer c.mu.Unlock() 155 for _, cc := range c.mu.cols { 156 if err := cc.close(); err != nil { 157 return err 158 } 159 } 160 return nil 161 } 162 163 func (c *tableCache) adjust( 164 ctx context.Context, 165 cols []AutoColumn) error { 166 c.mu.Lock() 167 defer c.mu.Unlock() 168 for idx := range c.cols { 169 v, err := c.mu.cols[c.cols[idx].ColName].current(ctx) 170 if err != nil { 171 return err 172 } 173 if v > 0 { 174 cols[idx].Offset = v - 1 175 } 176 } 177 return nil 178 }