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
}
func New() Map {
return pmap{}
type HashFunc = func(Key) uint32
func New(hash HashFunc) Map {
if hash == nil {
panic("pmap.New: nil hash")
}
return pmap{hash: hash}
}
func (p pmap) Len() int {
@ -52,13 +57,13 @@ func (p pmap) Len() int {
}
func (p pmap) Get(k Key) (Value, bool) {
var zero Key
h := hash(k) // TODO: p.hash
var zero Value
h := p.hash(k)
return lookup(p.root, 0, h, k, zero)
}
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)
p.root = root
if added {
@ -72,13 +77,6 @@ func (p pmap) Del(k Key) Map {
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{} {
i := hash >> shift & nodeMask
return m.child[i]
@ -131,9 +129,7 @@ func newnode(child interface{}, hash, shift uint32) *node {
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 {
return leaf{key, val}, true
}

View File

@ -5,8 +5,15 @@ import (
"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) {
p := New()
p := New(hash)
const numElems = 100
for i := range iter(numElems) {
p = p.Set(i, i)
@ -38,7 +45,7 @@ func BenchmarkGetAbsent(b *testing.B) {
}
func benchmarkGet(b *testing.B, numElems int) {
p := New()
p := New(hash)
for i := range iter(numElems) {
p = p.Set(i, i)
}
@ -60,7 +67,7 @@ func benchmarkGet(b *testing.B, numElems int) {
}
func benchmarkGetAbsent(b *testing.B, numElems int) {
p := New()
p := New(hash)
for i := range iter(numElems) {
p = p.Set(-i-1, i)
}