github.com/matrixorigin/matrixone@v1.2.0/pkg/incrservice/store_mem.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 "math" 20 "sync" 21 "time" 22 23 "github.com/matrixorigin/matrixone/pkg/pb/txn" 24 "github.com/matrixorigin/matrixone/pkg/txn/client" 25 ) 26 27 type memStore struct { 28 sync.Mutex 29 caches map[uint64][]AutoColumn 30 uncommitted map[string]map[uint64][]AutoColumn 31 } 32 33 // NewMemStore new mem store 34 func NewMemStore() IncrValueStore { 35 return &memStore{ 36 caches: make(map[uint64][]AutoColumn), 37 uncommitted: make(map[string]map[uint64][]AutoColumn), 38 } 39 } 40 41 func (s *memStore) NewTxnOperator(_ context.Context) client.TxnOperator { 42 return nil 43 } 44 45 func (s *memStore) SelectAll(_ context.Context, _ uint64, _ client.TxnOperator) (string, error) { 46 return "", nil 47 } 48 49 func (s *memStore) Create( 50 ctx context.Context, 51 tableID uint64, 52 cols []AutoColumn, 53 txnOp client.TxnOperator) error { 54 s.Lock() 55 defer s.Unlock() 56 m := s.caches 57 if txnOp != nil { 58 m = make(map[uint64][]AutoColumn) 59 s.uncommitted[string(txnOp.Txn().ID)] = m 60 txnOp.AppendEventCallback( 61 client.ClosedEvent, 62 func(event client.TxnEvent) { 63 txnMeta := event.Txn 64 s.Lock() 65 defer s.Unlock() 66 delete(s.uncommitted, string(txnMeta.ID)) 67 if txnMeta.Status == txn.TxnStatus_Committed { 68 for k, v := range m { 69 s.caches[k] = v 70 } 71 } 72 }) 73 } 74 75 caches := m[tableID] 76 for _, col := range cols { 77 has := false 78 for _, cache := range caches { 79 if cache.ColName == col.ColName { 80 has = true 81 break 82 } 83 } 84 if !has { 85 caches = append(caches, col) 86 } 87 } 88 m[tableID] = caches 89 return nil 90 } 91 92 func (s *memStore) GetColumns( 93 ctx context.Context, 94 tableID uint64, 95 txnOp client.TxnOperator) ([]AutoColumn, error) { 96 s.Lock() 97 defer s.Unlock() 98 s.Lock() 99 defer s.Unlock() 100 m := s.caches 101 if txnOp != nil { 102 m = s.uncommitted[string(txnOp.Txn().ID)] 103 } 104 return m[tableID], nil 105 } 106 107 func (s *memStore) Allocate( 108 ctx context.Context, 109 tableID uint64, 110 key string, 111 count int, 112 txnOp client.TxnOperator) (uint64, uint64, error) { 113 s.Lock() 114 defer s.Unlock() 115 m := s.caches 116 if txnOp != nil { 117 m = s.uncommitted[string(txnOp.Txn().ID)] 118 } 119 120 cols, ok := m[tableID] 121 if !ok { 122 panic("missing incr column record") 123 } 124 125 var c *AutoColumn 126 for i := range cols { 127 if cols[i].ColName == key { 128 c = &cols[i] 129 } 130 } 131 if !ok { 132 panic("missing incr column record") 133 } 134 135 curr := c.Offset 136 next := getNext(curr, count, int(c.Step)) 137 c.Offset = next 138 from, to := getNextRange(curr, next, int(c.Step)) 139 time.Sleep(time.Millisecond * 10) 140 return from, to, nil 141 } 142 143 func (s *memStore) UpdateMinValue( 144 ctx context.Context, 145 tableID uint64, 146 col string, 147 minValue uint64, 148 txnOp client.TxnOperator) error { 149 s.Lock() 150 defer s.Unlock() 151 m := s.caches 152 if txnOp != nil { 153 m = s.uncommitted[string(txnOp.Txn().ID)] 154 } 155 156 cols, ok := m[tableID] 157 if !ok { 158 panic("missing incr column record") 159 } 160 161 var c *AutoColumn 162 for i := range cols { 163 if cols[i].ColName == col { 164 c = &cols[i] 165 } 166 } 167 if !ok { 168 panic("missing incr column record") 169 } 170 171 if c != nil && c.Offset < minValue { 172 c.Offset = minValue 173 } 174 return nil 175 } 176 177 func (s *memStore) Delete( 178 ctx context.Context, 179 tableID uint64) error { 180 s.Lock() 181 defer s.Unlock() 182 delete(s.caches, tableID) 183 return nil 184 } 185 186 func (s *memStore) Close() { 187 188 } 189 190 func getNext(curr uint64, count, step int) uint64 { 191 n := uint64(count * step) 192 diff := math.MaxUint64 - curr 193 if diff <= n { 194 return math.MaxUint64 195 } 196 return curr + n 197 } 198 199 // [from, to) 200 func getNextRange(curr uint64, next uint64, step int) (uint64, uint64) { 201 return curr + uint64(step), next + uint64(step) 202 }