diff --git a/pmap.go b/pmap.go index fe09ee0..1c5ed8a 100644 --- a/pmap.go +++ b/pmap.go @@ -5,9 +5,11 @@ import ( "math/bits" ) -const deg = 16 // branch factor of nodes -const log2deg = 4 -const mask = 0b1111 +const ( + nodeDegree = 16 // branch factor of nodes + nodeShift = 4 + nodeMask = 0b1111 +) type Key = interface{} type Value = interface{} @@ -27,7 +29,7 @@ type pmap struct { // A Map implemented as a hashed trie type node struct { - child [deg]interface{} + child [nodeDegree]interface{} bitmap uint32 } @@ -50,8 +52,9 @@ func (p pmap) Len() int { } func (p pmap) Get(k Key) (Value, bool) { + var zero Key h := hash(k) // TODO: p.hash - return lookup(p.root, 0, h, k) + return lookup(p.root, 0, h, k, zero) } func (p pmap) Set(k Key, v Value) Map { @@ -73,8 +76,8 @@ func (p pmap) Set(k Key, v Value) Map { if n == nil { n = &node{} } - n.child[h&mask] = leaf{k, v} - n.bitmap = 1 << (h & mask) + n.child[h&nodeMask] = leaf{k, v} + n.bitmap = 1 << (h & nodeMask) p.root = n p.len++ return p @@ -92,7 +95,7 @@ func hash(k Key) uint32 { } func (m *node) getNode(shift, hash uint32, key Key) interface{} { - i := hash >> shift & mask + i := hash >> shift & nodeMask return m.child[i] } @@ -108,21 +111,21 @@ func (m *collision) getNode(hash uint32, key Key) interface{} { return nil } -func lookup(root interface{}, shift, hash uint32, key Key) (Value, bool) { +func lookup(root interface{}, shift, hash uint32, key Key, zero Key) (Value, bool) { cur := root for { switch n := cur.(type) { case nil: - return nil, false + return zero, false case leaf: if n.k == key { return n.v, true } else { - return nil, false + return zero, false } case *node: cur = n.getNode(shift, hash, key) - shift += log2deg + shift += nodeShift case *collision: cur = n.getNode(hash, key) default: @@ -137,7 +140,7 @@ func singleton(key Key, val Value, hash, shift uint32) *node { func newnode(child interface{}, hash, shift uint32) *node { n := &node{} - idx := hash >> shift & mask + idx := hash >> shift & nodeMask n.child[idx] = child n.bitmap = 1 << idx return n @@ -181,9 +184,9 @@ func insert(n interface{}, shift, hash uint32, key Key, val Value, hashFn hashFu c = leaf{key, val} added = true } else { - c = _insert(c, shift+log2deg) + c = _insert(c, shift+nodeShift) } - idx := hash >> shift & mask + idx := hash >> shift & nodeMask x := &node{child: n.child, bitmap: n.bitmap} x.child[idx] = c x.bitmap |= 1 << idx