package hashmap
import (
)
const (
chunkBits = 5
nodeCap = 1 << chunkBits
chunkMask = nodeCap - 1
)
type Equal func(k1, k2 interface{}) bool
type Hash func(k interface{}) uint32
func ( Equal, Hash) Map {
return &hashMap{0, emptyBitmapNode, nil, , }
}
type hashMap struct {
count int
root node
nilV *interface{}
equal Equal
hash Hash
}
func ( *hashMap) () int {
return .count
}
func ( *hashMap) ( interface{}) (interface{}, bool) {
if == nil {
if .nilV == nil {
return nil, false
}
return *.nilV, true
}
return .root.find(0, .hash(), , .equal)
}
func ( *hashMap) (, interface{}) Map {
if == nil {
:= .count
if .nilV == nil {
++
}
return &hashMap{, .root, &, .equal, .hash}
}
, := .root.assoc(0, .hash(), , , .hash, .equal)
:= .count
if {
++
}
return &hashMap{, , .nilV, .equal, .hash}
}
func ( *hashMap) ( interface{}) Map {
if == nil {
:= .count
if .nilV != nil {
--
}
return &hashMap{, .root, nil, .equal, .hash}
}
, := .root.without(0, .hash(), , .equal)
:= .count
if {
--
}
return &hashMap{, , .nilV, .equal, .hash}
}
func ( *hashMap) () Iterator {
if .nilV != nil {
return &nilVIterator{true, *.nilV, .root.iterator()}
}
return .root.iterator()
}
type nilVIterator struct {
atNil bool
nilV interface{}
tail Iterator
}
func ( *nilVIterator) () (interface{}, interface{}) {
if .atNil {
return nil, .nilV
}
return .tail.Elem()
}
func ( *nilVIterator) () bool {
return .atNil || .tail.HasElem()
}
func ( *nilVIterator) () {
if .atNil {
.atNil = false
} else {
.tail.Next()
}
}
func ( *hashMap) () ([]byte, error) {
var bytes.Buffer
.WriteByte('{')
:= true
for := .Iterator(); .HasElem(); .Next() {
if {
= false
} else {
.WriteByte(',')
}
, := .Elem()
, := convertKey()
if != nil {
return nil,
}
, := json.Marshal()
if != nil {
return nil,
}
, := json.Marshal()
if != nil {
return nil,
}
.Write()
.WriteByte(':')
.Write()
}
.WriteByte('}')
return .Bytes(), nil
}
func ( interface{}) (string, error) {
:= reflect.ValueOf()
if .Kind() == reflect.String {
return .String(), nil
}
if , := .(encoding.TextMarshaler); {
, := .MarshalText()
if != nil {
return "",
}
return string(), nil
}
switch .Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return strconv.FormatInt(.Int(), 10), nil
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
return strconv.FormatUint(.Uint(), 10), nil
}
return "", fmt.Errorf("unsupported key type %T", )
}
type node interface {
assoc(shift, hash uint32, k, v interface{}, h Hash, eq Equal) (node, bool)
without(shift, hash uint32, k interface{}, eq Equal) (node, bool)
find(shift, hash uint32, k interface{}, eq Equal) (interface{}, bool)
iterator() Iterator
}
type arrayNode struct {
nChildren int
children [nodeCap]node
}
func ( *arrayNode) ( uint32, node, int) *arrayNode {
:= .children
[] =
return &arrayNode{.nChildren + , }
}
func ( *arrayNode) (, uint32, , interface{}, Hash, Equal) (node, bool) {
:= chunk(, )
:= .children[]
if == nil {
, := emptyBitmapNode.assoc(+chunkBits, , , , , )
return .withNewChild(, , 1), true
}
, := .assoc(+chunkBits, , , , , )
return .withNewChild(, , 0),
}
func ( *arrayNode) (, uint32, interface{}, Equal) (node, bool) {
:= chunk(, )
:= .children[]
if == nil {
return , false
}
, := .without(+chunkBits, , , )
if == {
return , false
}
if == emptyBitmapNode {
if .nChildren <= nodeCap/4 {
return .pack(int()), true
}
return .withNewChild(, nil, -1), true
}
return .withNewChild(, , 0), true
}
func ( *arrayNode) ( int) *bitmapNode {
:= bitmapNode{0, make([]mapEntry, .nChildren-1)}
:= 0
for , := range .children {
if != && != nil {
.bitmap |= 1 << uint()
.entries[].value =
++
}
}
return &
}
func ( *arrayNode) (, uint32, interface{}, Equal) (interface{}, bool) {
:= chunk(, )
:= .children[]
if == nil {
return nil, false
}
return .find(+chunkBits, , , )
}
func ( *arrayNode) () Iterator {
:= &arrayNodeIterator{, 0, nil}
.fixCurrent()
return
}
type arrayNodeIterator struct {
n *arrayNode
index int
current Iterator
}
func ( *arrayNodeIterator) () {
for ; .index < nodeCap && .n.children[.index] == nil; .index++ {
}
if .index < nodeCap {
.current = .n.children[.index].iterator()
} else {
.current = nil
}
}
func ( *arrayNodeIterator) () (interface{}, interface{}) {
return .current.Elem()
}
func ( *arrayNodeIterator) () bool {
return .current != nil
}
func ( *arrayNodeIterator) () {
.current.Next()
if !.current.HasElem() {
.index++
.fixCurrent()
}
}
var emptyBitmapNode = &bitmapNode{}
type bitmapNode struct {
bitmap uint32
entries []mapEntry
}
type mapEntry struct {
key interface{}
value interface{}
}
func (, uint32) uint32 {
return ( >> ) & chunkMask
}
func (, uint32) uint32 {
return 1 << chunk(, )
}
func (, uint32) uint32 {
return popCount( & ( - 1))
}
const (
m1 uint32 = 0x55555555
m2 = 0x33333333
m4 = 0x0f0f0f0f
m8 = 0x00ff00ff
m16 = 0x0000ffff
)
func ( uint32) uint32 {
= ( & m1) + (( >> 1) & m1)
= ( & m2) + (( >> 2) & m2)
= ( & m4) + (( >> 4) & m4)
= ( & m8) + (( >> 8) & m8)
= ( & m16) + (( >> 16) & m16)
return
}
func ( uint32, interface{}, interface{}, uint32, interface{}, interface{}, Hash, Equal) node {
:= ()
if == {
return &collisionNode{, []mapEntry{{, }, {, }}}
}
, := emptyBitmapNode.assoc(, , , , , )
, _ = .assoc(, , , , , )
return
}
func ( *bitmapNode) (, uint32, node, Hash, Equal) *arrayNode {
var arrayNode
.nChildren = len(.entries) + 1
.children[] =
:= 0
for := uint(0); < nodeCap; ++ {
if (.bitmap>>)&1 != 0 {
:= .entries[]
++
if .key == nil {
.children[] = .value.(node)
} else {
.children[], _ = emptyBitmapNode.assoc(
+chunkBits, (.key), .key, .value, , )
}
}
}
return &
}
func ( *bitmapNode) (, uint32) *bitmapNode {
if .bitmap == {
return emptyBitmapNode
}
return &bitmapNode{.bitmap ^ , withoutEntry(.entries, )}
}
func ( []mapEntry, uint32) []mapEntry {
:= make([]mapEntry, len()-1)
copy([:], [:])
copy([:], [+1:])
return
}
func ( *bitmapNode) ( uint32, mapEntry) *bitmapNode {
return &bitmapNode{.bitmap, replaceEntry(.entries, , .key, .value)}
}
func ( []mapEntry, uint32, , interface{}) []mapEntry {
:= append([]mapEntry(nil), ...)
[] = mapEntry{, }
return
}
func ( *bitmapNode) (, uint32, , interface{}, Hash, Equal) (node, bool) {
:= bitpos(, )
:= index(.bitmap, )
if .bitmap& == 0 {
:= len(.entries)
if >= nodeCap/2 {
, := emptyBitmapNode.(+chunkBits, , , , , )
return .unpack(, chunk(, ), , , ), true
}
:= make([]mapEntry, len(.entries)+1)
copy([:], .entries[:])
[] = mapEntry{, }
copy([+1:], .entries[:])
return &bitmapNode{.bitmap | , }, true
}
:= .entries[]
if .key == nil {
:= .value.(node)
, := .assoc(+chunkBits, , , , , )
return .withReplacedEntry(, mapEntry{nil, }),
}
if (, .key) {
return .withReplacedEntry(, mapEntry{, }), false
}
:= createNode(+chunkBits, .key, .value, , , , , )
return .withReplacedEntry(, mapEntry{nil, }), true
}
func ( *bitmapNode) (, uint32, interface{}, Equal) (node, bool) {
:= bitpos(, )
if .bitmap& == 0 {
return , false
}
:= index(.bitmap, )
:= .entries[]
if .key == nil {
:= .value.(node)
, := .without(+chunkBits, , , )
if == {
return , false
}
if == emptyBitmapNode {
return .withoutEntry(, ), true
}
return .withReplacedEntry(, mapEntry{nil, }),
} else if (.key, ) {
return .withoutEntry(, ), true
}
return , false
}
func ( *bitmapNode) (, uint32, interface{}, Equal) (interface{}, bool) {
:= bitpos(, )
if .bitmap& == 0 {
return nil, false
}
:= index(.bitmap, )
:= .entries[]
if .key == nil {
:= .value.(node)
return .find(+chunkBits, , , )
} else if (.key, ) {
return .value, true
}
return nil, false
}
func ( *bitmapNode) () Iterator {
:= &bitmapNodeIterator{, 0, nil}
.fixCurrent()
return
}
type bitmapNodeIterator struct {
n *bitmapNode
index int
current Iterator
}
func ( *bitmapNodeIterator) () {
if .index < len(.n.entries) {
:= .n.entries[.index]
if .key == nil {
.current = .value.(node).iterator()
} else {
.current = nil
}
} else {
.current = nil
}
}
func ( *bitmapNodeIterator) () (interface{}, interface{}) {
if .current != nil {
return .current.Elem()
}
:= .n.entries[.index]
return .key, .value
}
func ( *bitmapNodeIterator) () bool {
return .index < len(.n.entries)
}
func ( *bitmapNodeIterator) () {
if .current != nil {
.current.Next()
}
if .current == nil || !.current.HasElem() {
.index++
.fixCurrent()
}
}
type collisionNode struct {
hash uint32
entries []mapEntry
}
func ( *collisionNode) (, uint32, , interface{}, Hash, Equal) (node, bool) {
if == .hash {
:= .findIndex(, )
if != -1 {
return &collisionNode{
.hash, replaceEntry(.entries, uint32(), , )}, false
}
:= make([]mapEntry, len(.entries)+1)
copy([:len(.entries)], .entries[:])
[len(.entries)] = mapEntry{, }
return &collisionNode{.hash, }, true
}
:= bitmapNode{bitpos(, .hash), []mapEntry{{nil, }}}
return .assoc(, , , , , )
}
func ( *collisionNode) (, uint32, interface{}, Equal) (node, bool) {
:= .findIndex(, )
if == -1 {
return , false
}
if len(.entries) == 1 {
return emptyBitmapNode, true
}
return &collisionNode{.hash, withoutEntry(.entries, uint32())}, true
}
func ( *collisionNode) (, uint32, interface{}, Equal) (interface{}, bool) {
:= .findIndex(, )
if == -1 {
return nil, false
}
return .entries[].value, true
}
func ( *collisionNode) ( interface{}, Equal) int {
for , := range .entries {
if (, .key) {
return
}
}
return -1
}
func ( *collisionNode) () Iterator {
return &collisionNodeIterator{, 0}
}
type collisionNodeIterator struct {
n *collisionNode
index int
}
func ( *collisionNodeIterator) () (interface{}, interface{}) {
:= .n.entries[.index]
return .key, .value
}
func ( *collisionNodeIterator) () bool {
return .index < len(.n.entries)
}
func ( *collisionNodeIterator) () {
.index++
}