func (b *bitmapIndexedHmnode) without(shift uint32, hash uint32, key interface{}) hmnode { bit := bitpos(hash, shift) if (b.bitmap & bit) == 0 { return b } idx := b.index(bit) keyOrNil := b.array[2*idx] valOrNode := b.array[2*idx+1] if keyOrNil == nil { n := valOrNode.(hmnode).without(shift+5, hash, key) // TOOD: use switch if n == valOrNode { return b } if n != nil { return &bitmapIndexedHmnode{b.bitmap, cloneAndSetObjectSlice(b.array, 2*idx+1, n)} } if b.bitmap == bit { return nil } return &bitmapIndexedHmnode{b.bitmap ^ bit, removePair(b.array, idx)} } if sequtil.Equiv(key, keyOrNil) { // TODO: Collapse (TODO in Java code) return &bitmapIndexedHmnode{b.bitmap ^ bit, removePair(b.array, idx)} } return b }
func (h *hashCollisionHmnode) findIndex(key interface{}) int { for i := 0; i < 2*h.count; i = i + 2 { if sequtil.Equiv(key, h.array[i]) { return i } } return -1 }
func (h *hashCollisionHmnode) findD(shift uint32, hash uint32, key interface{}, notFound interface{}) interface{} { idx := h.findIndex(key) if idx < 0 { return notFound } if sequtil.Equiv(key, h.array[idx]) { return h.array[idx+1] } return notFound }
func (h *hashCollisionHmnode) find(shift uint32, hash uint32, key interface{}) iseq.MapEntry { idx := h.findIndex(key) if idx < 0 { return nil } if sequtil.Equiv(key, h.array[idx]) { return &MapEntry{h.array[idx], h.array[idx+1]} } return nil }
func (b *bitmapIndexedHmnode) assoc2(shift uint32, hash uint32, key interface{}, val interface{}) (hmnode, bool) { bit := bitpos(hash, shift) idx := b.index(bit) if (b.bitmap & bit) != 0 { keyOrNil := b.array[2*idx] valOrNode := b.array[2*idx+1] if keyOrNil == nil { n, ok := valOrNode.(hmnode) if !ok { panic("Unexpected node type") } n, addedLeaf := n.assoc2(shift+5, hash, key, val) if n == valOrNode { return b, false } return &bitmapIndexedHmnode{b.bitmap, cloneAndSetObjectSlice(b.array, 2*idx+1, n)}, addedLeaf } if sequtil.Equiv(key, keyOrNil) { if val == valOrNode { return b, false } return &bitmapIndexedHmnode{b.bitmap, cloneAndSetObjectSlice(b.array, 2*idx+1, val)}, false } return &bitmapIndexedHmnode{b.bitmap, cloneAndSetObjectSlice2(b.array, 2*idx, nil, 2*idx+1, createNode(shift+5, keyOrNil, valOrNode, hash, key, val))}, true } n := sequtil.BitCountU32(b.bitmap) if n >= 16 { nodes := make([]hmnode, 32) jdx := imask(hash, shift) nodes[jdx] = emptyBitmapIndexedHmnode.assoc(shift+5, hash, key, val) for i, j := 0, 0; i < 32; i++ { if ((b.bitmap >> uint(i)) & 1) != 0 { if b.array[j] == nil { if nn, ok := b.array[j+1].(hmnode); ok { nodes[i] = nn } else { panic("Unexpected node type") } } else { nodes[i] = emptyBitmapIndexedHmnode.assoc(shift+5, Hash(b.array[j]), b.array[j], b.array[j+1]) } j += 2 } } return &arrayHmnode{n + 1, nodes}, true } newArray := make([]interface{}, 2*(n+1)) copy(newArray, b.array[0:2*idx]) newArray[2*idx] = key newArray[2*idx+1] = val copy(newArray[2*(idx+1):], b.array[2*idx:]) return &bitmapIndexedHmnode{b.bitmap | bit, newArray}, true }
func (p *PVector) Equiv(o interface{}) bool { if p == o { return true } if ov, ok := o.(iseq.PVector); ok { if p.Count1() != ov.Count1() { return false } for i := 0; i < p.Count1(); i++ { if !sequtil.Equiv(p.Nth(i), ov.Nth(i)) { return false } } return true } // TODO: when we have Sequential, fix this if os, ok := o.(iseq.Seqable); ok { s := os.Seq() for i := 0; i < p.Count1(); i, s = i+1, s.Next() { if s == nil || !sequtil.Equiv(p.Nth(i), s.First()) { return false } } if s != nil { return false } return true } // TODO: handle built-in 'sequable' things such as arrays, slices, strings return false }
func (b *bitmapIndexedHmnode) findD(shift uint32, hash uint32, key interface{}, notFound interface{}) interface{} { bit := bitpos(hash, shift) if (b.bitmap & bit) == 0 { return notFound } // TODO: Factor out the following three lines -- repeated idx := b.index(bit) keyOrNil := b.array[2*idx] valOrNode := b.array[2*idx+1] if keyOrNil == nil { return valOrNode.(hmnode).findD(shift+5, hash, key, notFound) } if sequtil.Equiv(key, keyOrNil) { return valOrNode } return notFound }
// TODO: Check to make sure not a loop func (h *hmnodeSeq) Equiv(o interface{}) bool { return sequtil.Equiv(h, o) }
func (a *arrayHmnodeSeq) Equiv(o interface{}) bool { return sequtil.Equiv(a, o) }
func (t *tmNodeSeq) Equiv(o interface{}) bool { return sequtil.Equiv(t, o) }
// Equiv returns true if its argument is an iseq.MapEntry with equivalent key and value. func (m MapEntry) Equiv(o interface{}) bool { if you, ok := o.(iseq.MapEntry); ok { return sequtil.Equiv(m.key, you.Key()) && sequtil.Equiv(m.val, you.Val()) } return false }
func (c *chunkedSeq) Equiv(o interface{}) bool { return sequtil.Equiv(c, o) }