blob: f16bb293bbe54c6be39c98d8c10870d7340a170b [file] [log] [blame]
Naveen Sampath04696f72022-06-13 15:19:14 +05301/*
2* Copyright 2022-present Open Networking Foundation
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
16package util
17
18import (
19 "sync"
20
21 "go.uber.org/atomic"
22)
23
24// ConcurrentMap implements a wrapper on top of SyncMap so that the count is also maintained
25type ConcurrentMap struct {
26 syncMap sync.Map
27 count *atomic.Uint64
28 MapLock sync.RWMutex
29}
30
31// NewConcurrentMap - Initializes new ConcurentMap Object
32func NewConcurrentMap() *ConcurrentMap {
33 var cm ConcurrentMap
34 cm.count = atomic.NewUint64(0)
35 return &cm
36}
37
38// Get - Gets return the value store in the sync map
39//If value is present, the result will be true else false
40func (cm *ConcurrentMap) Get(key interface{}) (value interface{}, result bool) {
41 return cm.syncMap.Load(key)
42}
43
44// Set - Store the value in sync map against the key provided
45func (cm *ConcurrentMap) Set(key, value interface{}) {
46 if cm.count == nil {
47 cm.count = atomic.NewUint64(0)
48 }
49 _, exists := cm.syncMap.Load(key)
50 cm.syncMap.Store(key, value)
51 if !exists {
52 cm.count.Inc()
53 }
54}
55
56// Remove - Removes the key-value pair from the sync map
57func (cm *ConcurrentMap) Remove(key interface{}) bool {
58
59 if _, ok := cm.syncMap.Load(key); ok {
60 cm.syncMap.Delete(key)
61 cm.count.Dec()
62 return true
63 }
64 return false
65}
66
67// Range calls f sequentially for each key and value present in the sync map.
68// If f returns false, range stops the iteration.
69//
70// Range does not necessarily correspond to any consistent snapshot of the Sync Map's
71// contents: no key will be visited more than once, but if the value for any key
72// is stored or deleted concurrently, Range may reflect any mapping for that key
73// from any point during the Range call.
74//
75// Range may be O(N) with the number of elements in the sync map even if f returns
76// false after a constant number of calls.
77func (cm *ConcurrentMap) Range(f func(key, value interface{}) bool) {
78 cm.syncMap.Range(f)
79}
80
81// Length - return the no of entries present in the map
82func (cm *ConcurrentMap) Length() uint64 {
83 if cm.count == nil {
84 return 0
85 }
86 return cm.count.Load()
87}