@@ -60,80 +60,121 @@ func (c *smap) Range(f func(key string, value any) bool) {
6060
6161type (
6262 ConcurrentMap [K comparable , V any ] struct {
63- hasher maphash.Hasher [K ]
64- sharding uint64
65- buckets []* bucket [K , V ]
66- }
67-
68- bucket [K comparable , V any ] struct {
69- sync.Mutex
70- m map [K ]V
63+ hasher maphash.Hasher [K ]
64+ num uint64
65+ shardings []* Map [K , V ]
7166 }
7267)
7368
74- func NewConcurrentMap [K comparable , V any ](sharding uint64 ) * ConcurrentMap [K , V ] {
75- sharding = internal .SelectValue (sharding == 0 , 16 , sharding )
76- sharding = internal .ToBinaryNumber (sharding )
69+ // NewConcurrentMap create a new concurrency-safe map
70+ // arg0 represents the number of shardings; arg1 represents the initialized capacity of a sharding.
71+ func NewConcurrentMap [K comparable , V any ](size ... uint64 ) * ConcurrentMap [K , V ] {
72+ size = append (size , 0 , 0 )
73+ num , capacity := size [0 ], size [1 ]
74+ num = internal .ToBinaryNumber (internal .SelectValue (num <= 0 , 16 , num ))
7775 var cm = & ConcurrentMap [K , V ]{
78- hasher : maphash .NewHasher [K ](),
79- sharding : sharding ,
80- buckets : make ([]* bucket [K , V ], sharding ),
76+ hasher : maphash .NewHasher [K ](),
77+ num : num ,
78+ shardings : make ([]* Map [K , V ], num ),
8179 }
82- for i , _ := range cm .buckets {
83- cm .buckets [i ] = & bucket [K , V ]{ m : make ( map [ K ] V )}
80+ for i , _ := range cm .shardings {
81+ cm .shardings [i ] = NewMap [K , V ]( int ( capacity ))
8482 }
8583 return cm
8684}
8785
88- func (c * ConcurrentMap [K , V ]) getBucket (key K ) * bucket [K , V ] {
86+ // GetSharding returns a map sharding for a key
87+ // the operations inside the sharding is lockless, and need to be locked manually.
88+ func (c * ConcurrentMap [K , V ]) GetSharding (key K ) * Map [K , V ] {
8989 var hashCode = c .hasher .Hash (key )
90- var index = hashCode & (c .sharding - 1 )
91- return c .buckets [index ]
90+ var index = hashCode & (c .num - 1 )
91+ return c .shardings [index ]
9292}
9393
94+ // Len returns the number of elements in the map
9495func (c * ConcurrentMap [K , V ]) Len () int {
9596 var length = 0
96- for _ , b := range c .buckets {
97+ for _ , b := range c .shardings {
9798 b .Lock ()
98- length += len ( b . m )
99+ length += b . Len ( )
99100 b .Unlock ()
100101 }
101102 return length
102103}
103104
104- func (c * ConcurrentMap [K , V ]) Load (key K ) (value V , exist bool ) {
105- var b = c .getBucket (key )
105+ // Load returns the value stored in the map for a key, or nil if no
106+ // value is present.
107+ // The ok result indicates whether value was found in the map.
108+ func (c * ConcurrentMap [K , V ]) Load (key K ) (value V , ok bool ) {
109+ var b = c .GetSharding (key )
106110 b .Lock ()
107- value , exist = b .m [ key ]
111+ value , ok = b .Load ( key )
108112 b .Unlock ()
109113 return
110114}
111115
116+ // Delete deletes the value for a key.
112117func (c * ConcurrentMap [K , V ]) Delete (key K ) {
113- var b = c .getBucket (key )
118+ var b = c .GetSharding (key )
114119 b .Lock ()
115- delete ( b . m , key )
120+ b . Delete ( key )
116121 b .Unlock ()
117122}
118123
124+ // Store sets the value for a key.
119125func (c * ConcurrentMap [K , V ]) Store (key K , value V ) {
120- var b = c .getBucket (key )
126+ var b = c .GetSharding (key )
121127 b .Lock ()
122- b .m [ key ] = value
128+ b .Store ( key , value )
123129 b .Unlock ()
124130}
125131
126132// Range calls f sequentially for each key and value present in the map.
127133// If f returns false, range stops the iteration.
128134func (c * ConcurrentMap [K , V ]) Range (f func (key K , value V ) bool ) {
129- for _ , b := range c .buckets {
135+ var next = true
136+ var cb = func (k K , v V ) bool {
137+ next = f (k , v )
138+ return next
139+ }
140+ for i := uint64 (0 ); i < c .num && next ; i ++ {
141+ var b = c .shardings [i ]
130142 b .Lock ()
131- for k , v := range b .m {
132- if ! f (k , v ) {
133- b .Unlock ()
134- return
135- }
136- }
143+ b .Range (cb )
137144 b .Unlock ()
138145 }
139146}
147+
148+ type Map [K comparable , V any ] struct {
149+ sync.Mutex
150+ m map [K ]V
151+ }
152+
153+ func NewMap [K comparable , V any ](size ... int ) * Map [K , V ] {
154+ var capacity = 0
155+ if len (size ) > 0 {
156+ capacity = size [0 ]
157+ }
158+ c := new (Map [K , V ])
159+ c .m = make (map [K ]V , capacity )
160+ return c
161+ }
162+
163+ func (c * Map [K , V ]) Len () int { return len (c .m ) }
164+
165+ func (c * Map [K , V ]) Load (key K ) (value V , ok bool ) {
166+ value , ok = c .m [key ]
167+ return
168+ }
169+
170+ func (c * Map [K , V ]) Delete (key K ) { delete (c .m , key ) }
171+
172+ func (c * Map [K , V ]) Store (key K , value V ) { c .m [key ] = value }
173+
174+ func (c * Map [K , V ]) Range (f func (K , V ) bool ) {
175+ for k , v := range c .m {
176+ if ! f (k , v ) {
177+ return
178+ }
179+ }
180+ }
0 commit comments