stop hardcoding the hash function

master
magical 2022-01-23 01:25:42 +00:00
parent c446aef67c
commit c57649e758
2 changed files with 21 additions and 18 deletions

26
pmap.go
View File

@ -43,8 +43,13 @@ type leaf struct {
v Value v Value
} }
func New() Map { type HashFunc = func(Key) uint32
return pmap{}
func New(hash HashFunc) Map {
if hash == nil {
panic("pmap.New: nil hash")
}
return pmap{hash: hash}
} }
func (p pmap) Len() int { func (p pmap) Len() int {
@ -52,13 +57,13 @@ func (p pmap) Len() int {
} }
func (p pmap) Get(k Key) (Value, bool) { func (p pmap) Get(k Key) (Value, bool) {
var zero Key var zero Value
h := hash(k) // TODO: p.hash h := p.hash(k)
return lookup(p.root, 0, h, k, zero) return lookup(p.root, 0, h, k, zero)
} }
func (p pmap) Set(k Key, v Value) Map { func (p pmap) Set(k Key, v Value) Map {
h := hash(k) // TODO: p.hash h := p.hash(k)
root, added := insert(p.root, 0, h, k, v, hash) root, added := insert(p.root, 0, h, k, v, hash)
p.root = root p.root = root
if added { if added {
@ -72,13 +77,6 @@ func (p pmap) Del(k Key) Map {
return p return p
} }
func hash(k Key) uint32 {
//u := uint(k.(int))*6364136223846793005 + 1
//return uint32(u >> 32)
u := uint(k.(int))
return uint32(u + u>>32)
}
func (m *node) getNode(shift, hash uint32, key Key) interface{} { func (m *node) getNode(shift, hash uint32, key Key) interface{} {
i := hash >> shift & nodeMask i := hash >> shift & nodeMask
return m.child[i] return m.child[i]
@ -131,9 +129,7 @@ func newnode(child interface{}, hash, shift uint32) *node {
return n return n
} }
type hashFunc = func(Key) uint32 func insert(n interface{}, shift, hash uint32, key Key, val Value, hashFn HashFunc) (newNode interface{}, added bool) {
func insert(n interface{}, shift, hash uint32, key Key, val Value, hashFn hashFunc) (newNode interface{}, added bool) {
if n == nil { if n == nil {
return leaf{key, val}, true return leaf{key, val}, true
} }

View File

@ -5,8 +5,15 @@ import (
"testing" "testing"
) )
func hash(k Key) uint32 {
//u := uint(k.(int))*6364136223846793005 + 1
//return uint32(u >> 32)
u := uint(k.(int))
return uint32(u + u>>32)
}
func TestPmap(t *testing.T) { func TestPmap(t *testing.T) {
p := New() p := New(hash)
const numElems = 100 const numElems = 100
for i := range iter(numElems) { for i := range iter(numElems) {
p = p.Set(i, i) p = p.Set(i, i)
@ -38,7 +45,7 @@ func BenchmarkGetAbsent(b *testing.B) {
} }
func benchmarkGet(b *testing.B, numElems int) { func benchmarkGet(b *testing.B, numElems int) {
p := New() p := New(hash)
for i := range iter(numElems) { for i := range iter(numElems) {
p = p.Set(i, i) p = p.Set(i, i)
} }
@ -60,7 +67,7 @@ func benchmarkGet(b *testing.B, numElems int) {
} }
func benchmarkGetAbsent(b *testing.B, numElems int) { func benchmarkGetAbsent(b *testing.B, numElems int) {
p := New() p := New(hash)
for i := range iter(numElems) { for i := range iter(numElems) {
p = p.Set(-i-1, i) p = p.Set(-i-1, i)
} }