Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 16 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,13 @@ The default bucket size is 24 if a BucketSizeOption is not set.
### for k, v := range
Since this is a concurrent hashmap, you'll need to call `Lock()` before doing a
range operation. And remember to call `Unlock()` afterwards.
```
```go
func rangeMap(m HashMap) error {
f := func(interface{}, interface{}) error {
// define what to do for each entry in the map
return
}
f := func(interface{}, interface{}) error {
// define what to do for each entry in the map
return
}

m.Lock()
for k, v, ok := m.Next(); ok; k, v, ok = m.Next() {
if err := f(k, v); err != nil {
Expand All @@ -98,6 +98,16 @@ func rangeMap(m HashMap) error {
return nil
}
```
A shortcut:
```go
m.Iterate(func(_k interface{}, _v interface{}) error {
k := _k.(string)
v := _v.(int64)
// do something
return nil
})
```

## Queue
- FIFO list that can be concurrently accessed
- can put different data types into the queue
Expand Down
11 changes: 11 additions & 0 deletions hashmap/hmap.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,17 @@ func (h *hmap) Next() (interface{}, interface{}, bool) {

}

func (h *hmap) Iterate(f func(_k interface{}, _v interface{}) error) error {
h.Lock()
defer h.Unlock() // unlock even panic
for k, v, ok := h.Next(); ok; k, v, ok = h.Next() {
if err := f(k, v); err != nil {
return err
}
}
return nil
}

func (h *hmap) getBucket(hash uint64) *bucket {
h.mutex.RLock()
b := h.buckets[hash>>(64-h.B)]
Expand Down
24 changes: 24 additions & 0 deletions hashmap/hmap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,28 @@ func TestHmap(t *testing.T) {
req.Equal(len(tests)-1, match)
req.Equal(10000+len(tests)-1, total)
m.info()

// test Iterate()
total = 0
match = 0
err := m.Iterate(func(k interface{}, v interface{}) error {
for i := range tests {
if k == tests[i].k {
req.Equal(tests[i].v, v)
match++
}
}
total++
return nil
})
req.Nil(err)

k, v, ok = m.Next()
req.False(ok)
req.Nil(k)
req.Nil(v)
m.Unlock()
req.Equal(len(tests)-1, match)
req.Equal(10000+len(tests)-1, total)
m.info()
}
3 changes: 3 additions & 0 deletions map.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ type (

// returns next <k, v> in the map
Next() (interface{}, interface{}, bool)

// iterate over all element
Iterate(func(_k interface{}, _v interface{}) error) error
}
)

Expand Down