stop hardcoding the hash function
parent
c446aef67c
commit
c57649e758
26
pmap.go
26
pmap.go
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
13
pmap_test.go
13
pmap_test.go
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue