github.com/kubewharf/katalyst-core@v0.5.3/pkg/custom-metric/store/data/object_store.go (about) 1 /* 2 Copyright 2022 The Katalyst Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package data 18 19 import ( 20 "bytes" 21 "hash/fnv" 22 "sync" 23 24 "github.com/kubewharf/katalyst-core/pkg/custom-metric/store/data/internal" 25 "github.com/kubewharf/katalyst-core/pkg/custom-metric/store/data/types" 26 ) 27 28 type ObjectMetricStoreType string 29 30 const ( 31 ObjectMetricStoreTypeSimple ObjectMetricStoreType = "simple" 32 ObjectMetricStoreTypeBucket ObjectMetricStoreType = "bucket" 33 ) 34 35 type ObjectMetricStore interface { 36 Add(objectMeta types.ObjectMetaImp) error 37 ObjectExists(objectMeta types.ObjectMetaImp) (bool, error) 38 GetInternalMetricImp(objectMeta types.ObjectMetaImp) (*internal.MetricImp, error) 39 40 // Iterate is read only, please do not perform any write operation like add/delete to this object 41 Iterate(f func(internalMetric *internal.MetricImp)) 42 Purge() 43 Len() int 44 } 45 46 type simpleObjectMetricStore struct { 47 metricMeta types.MetricMetaImp 48 objectMap map[types.ObjectMeta]*internal.MetricImp 49 sync.RWMutex 50 } 51 52 func NewSimpleObjectMetricStore(metricMeta types.MetricMetaImp) ObjectMetricStore { 53 return &simpleObjectMetricStore{ 54 metricMeta: metricMeta, 55 objectMap: make(map[types.ObjectMeta]*internal.MetricImp), 56 } 57 } 58 59 func (s *simpleObjectMetricStore) Add(objectMeta types.ObjectMetaImp) error { 60 s.Lock() 61 defer s.Unlock() 62 63 if _, ok := s.objectMap[objectMeta]; !ok { 64 s.objectMap[objectMeta] = internal.NewInternalMetric(s.metricMeta, objectMeta) 65 } 66 67 return nil 68 } 69 70 func (s *simpleObjectMetricStore) ObjectExists(objectMeta types.ObjectMetaImp) (bool, error) { 71 s.RLock() 72 defer s.RUnlock() 73 74 _, exist := s.objectMap[objectMeta] 75 return exist, nil 76 } 77 78 func (s *simpleObjectMetricStore) GetInternalMetricImp(objectMeta types.ObjectMetaImp) (*internal.MetricImp, error) { 79 s.RLock() 80 defer s.RUnlock() 81 82 return s.objectMap[objectMeta], nil 83 } 84 85 func (s *simpleObjectMetricStore) Iterate(f func(internalMetric *internal.MetricImp)) { 86 s.RLock() 87 defer s.RUnlock() 88 89 for _, InternalMetricImp := range s.objectMap { 90 f(InternalMetricImp) 91 } 92 } 93 94 func (s *simpleObjectMetricStore) Purge() { 95 s.Lock() 96 defer s.Unlock() 97 98 for _, internalMetric := range s.objectMap { 99 if internalMetric.Empty() { 100 delete(s.objectMap, internalMetric.ObjectMetaImp) 101 } 102 } 103 } 104 105 func (s *simpleObjectMetricStore) Len() int { 106 s.RLock() 107 defer s.RUnlock() 108 return len(s.objectMap) 109 } 110 111 type bucketObjectMetricStore struct { 112 bucketSize int 113 buckets map[int]ObjectMetricStore 114 } 115 116 func NewBucketObjectMetricStore(bucketSize int, metricMeta types.MetricMetaImp) ObjectMetricStore { 117 buckets := make(map[int]ObjectMetricStore, bucketSize) 118 for i := 0; i < bucketSize; i++ { 119 index := i 120 buckets[index] = NewSimpleObjectMetricStore(metricMeta) 121 } 122 123 return &bucketObjectMetricStore{ 124 bucketSize: bucketSize, 125 buckets: buckets, 126 } 127 } 128 129 func (b *bucketObjectMetricStore) getIndex(objectMeta types.ObjectMetaImp) (int, error) { 130 buffer := bytes.Buffer{} 131 buffer.WriteString(objectMeta.GetObjectNamespace()) 132 buffer.WriteString(":") 133 buffer.WriteString(objectMeta.GetObjectName()) 134 namespacedName := make([]byte, buffer.Len()) 135 _, err := buffer.Read(namespacedName) 136 if err != nil { 137 return -1, err 138 } 139 140 h := fnv.New64() 141 _, err = h.Write(namespacedName) 142 if err != nil { 143 return -1, err 144 } 145 return int(h.Sum64() % uint64(b.bucketSize)), nil 146 } 147 148 func (b *bucketObjectMetricStore) Add(objectMeta types.ObjectMetaImp) error { 149 index, err := b.getIndex(objectMeta) 150 if err != nil { 151 return err 152 } 153 return b.buckets[index].Add(objectMeta) 154 } 155 156 func (b *bucketObjectMetricStore) ObjectExists(objectMeta types.ObjectMetaImp) (bool, error) { 157 index, err := b.getIndex(objectMeta) 158 if err != nil { 159 return false, err 160 } 161 return b.buckets[index].ObjectExists(objectMeta) 162 } 163 164 func (b *bucketObjectMetricStore) GetInternalMetricImp(objectMeta types.ObjectMetaImp) (*internal.MetricImp, error) { 165 index, err := b.getIndex(objectMeta) 166 if err != nil { 167 return nil, err 168 } 169 170 return b.buckets[index].GetInternalMetricImp(objectMeta) 171 } 172 173 func (b *bucketObjectMetricStore) Iterate(f func(internalMetric *internal.MetricImp)) { 174 for i := range b.buckets { 175 b.buckets[i].Iterate(f) 176 } 177 } 178 179 func (b *bucketObjectMetricStore) Purge() { 180 for i := range b.buckets { 181 b.buckets[i].Purge() 182 } 183 } 184 185 func (b *bucketObjectMetricStore) Len() int { 186 var length int 187 for i := range b.buckets { 188 length += b.buckets[i].Len() 189 } 190 return length 191 }