github.com/matrixorigin/matrixone@v1.2.0/pkg/incrservice/range_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 type ranges struct { 18 step uint64 19 values []uint64 20 minCanAdded uint64 21 } 22 23 func (r *ranges) rangeCount() int { 24 return len(r.values) / 2 25 } 26 27 func (r *ranges) empty() bool { 28 n := r.rangeCount() 29 for i := 0; i < n; i++ { 30 from, to := r.values[2*i], r.values[2*i+1] 31 if from < to { 32 return false 33 } 34 } 35 return true 36 } 37 38 func (r *ranges) next() uint64 { 39 n := r.rangeCount() 40 for i := 0; i < n; i++ { 41 from, to := r.values[2*i], r.values[2*i+1] 42 if from < to { 43 r.values[2*i] += r.step 44 if r.values[2*i] == to { 45 r.values = r.values[2*i+2:] 46 } 47 return from 48 } 49 } 50 return 0 51 } 52 53 func (r *ranges) current() uint64 { 54 n := r.rangeCount() 55 for i := 0; i < n; i++ { 56 from, to := r.values[2*i], r.values[2*i+1] 57 if from < to { 58 return from 59 } 60 } 61 return 0 62 } 63 64 func (r *ranges) left() int { 65 v := 0 66 n := r.rangeCount() 67 for i := 0; i < n; i++ { 68 from, to := r.values[2*i], r.values[2*i+1] 69 v += int((to - from) / r.step) 70 } 71 return v 72 } 73 74 func (r *ranges) setManual( 75 value uint64, 76 skipped *ranges) { 77 newValues := r.values[:0] 78 n := r.rangeCount() 79 for i := 0; i < n; i++ { 80 from, to := r.values[2*i], r.values[2*i+1] 81 if to <= value { 82 skipped.add(from, to) 83 continue 84 } 85 if from > value { 86 newValues = append(newValues, from, to) 87 continue 88 } 89 skipped.add(from, value) 90 if value+1 < to { 91 newValues = append(newValues, value+1, to) 92 } 93 } 94 r.values = newValues 95 } 96 97 func (r *ranges) add(from, to uint64) { 98 if r.minCanAdded >= to { 99 return 100 } 101 if r.minCanAdded >= from { 102 from = r.minCanAdded 103 } 104 if from < to { 105 r.values = append(r.values, from, to) 106 } 107 r.minCanAdded = to 108 } 109 110 // updateTo after updateTo returns, make sure that the value 111 // returned by ranges.next() must be greater than value. 112 // Return true means the value is include in old ranges, otherwise 113 // the value of this value must be updated to the store to avoid 114 // skipping the value when restarting or other cache is allocated 115 // next time. 116 func (r *ranges) updateTo(value uint64) bool { 117 n := r.rangeCount() 118 compactTo := -1 119 contains := false 120 for i := 0; i < n; i++ { 121 from, to := r.values[2*i], r.values[2*i+1] 122 if from > value { 123 contains = true 124 break 125 } 126 if value >= to { 127 compactTo = 2*i + 2 128 continue 129 } 130 r.values[2*i] = value 131 contains = true 132 break 133 } 134 if compactTo != -1 { 135 r.values = r.values[compactTo:] 136 } 137 if !contains { 138 r.minCanAdded = value 139 } 140 return contains 141 }