Skip to content

Commit

Permalink
Merge pull request orcaman#33 from redbaron/nolock-fnv
Browse files Browse the repository at this point in the history
Replace hash/fnv + sync.pool magic with simple fnv32 func
  • Loading branch information
Eran Chetz authored Aug 14, 2016
2 parents 430cc62 + e3b11eb commit e5717b3
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 15 deletions.
26 changes: 11 additions & 15 deletions concurrent_map.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,9 @@ package cmap

import (
"encoding/json"
"hash"
"hash/fnv"
"sync"
)

var hashPool = new(sync.Pool)

var SHARD_COUNT = 32

// A "thread" safe map of type string:Anything.
Expand All @@ -32,17 +28,7 @@ func New() ConcurrentMap {

// Returns shard under given key
func (m ConcurrentMap) GetShard(key string) *ConcurrentMapShared {
hasherAsInterface := hashPool.Get()
var hasher hash.Hash32
if hasherAsInterface == nil {
hasher = fnv.New32()
} else {
hasher = hasherAsInterface.(hash.Hash32)
hasher.Reset()
}
hasher.Write([]byte(key))
sum := hasher.Sum32()
hashPool.Put(hasher)
sum := fnv32([]byte(key))
return m[uint(sum)%uint(SHARD_COUNT)]
}

Expand Down Expand Up @@ -236,6 +222,16 @@ func (m ConcurrentMap) MarshalJSON() ([]byte, error) {
return json.Marshal(tmp)
}

func fnv32(key []byte) uint32 {
hash := uint32(2166136261)
prime32 := uint32(16777619)
for _, c := range key {
hash *= prime32
hash ^= uint32(c)
}
return hash
}

// Concurrent map uses Interface{} as its value, therefor JSON Unmarshal
// will probably won't know which to type to unmarshal into, in such case
// we'll end up with a value of type map[string]interface{}, In most cases this isn't
Expand Down
11 changes: 11 additions & 0 deletions concurrent_map_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cmap

import (
"encoding/json"
"hash/fnv"
"sort"
"strconv"
"testing"
Expand Down Expand Up @@ -316,3 +317,13 @@ func TestMInsert(t *testing.T) {
t.Error("map should contain exactly two elements.")
}
}

func TestFnv32(t *testing.T) {
key := []byte("ABC")

hasher := fnv.New32()
hasher.Write(key)
if fnv32(key) != hasher.Sum32() {
t.Errorf("Bundled fnv32 produced %d, expected result from hash/fnv32 is %d", fnv32(key), hasher.Sum32())
}
}

0 comments on commit e5717b3

Please sign in to comment.