forked from cevaris/ordered_map
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathordered_map.go
141 lines (125 loc) · 2.75 KB
/
ordered_map.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package ordered_map
import (
"fmt"
)
type OrderedMap struct {
store map[interface{}]interface{}
mapper map[interface{}]*node
root *node
}
func NewOrderedMap() *OrderedMap {
om := &OrderedMap{
store: make(map[interface{}]interface{}),
mapper: make(map[interface{}]*node),
root: newRootNode(),
}
return om
}
func NewOrderedMapWithArgs(args []*KVPair) *OrderedMap {
om := NewOrderedMap()
om.update(args)
return om
}
func (om *OrderedMap) update(args []*KVPair) {
for _, pair := range args {
om.Set(pair.Key, pair.Value)
}
}
func (om *OrderedMap) Set(key interface{}, value interface{}) {
if _, ok := om.store[key]; ok == false {
root := om.root
last := root.Prev
last.Next = newNode(last, root, key)
root.Prev = last.Next
om.mapper[key] = last.Next
}
om.store[key] = value
}
func (om *OrderedMap) Get(key interface{}) (interface{}, bool) {
val, ok := om.store[key]
return val, ok
}
func (om *OrderedMap) Delete(key interface{}) {
_, ok := om.store[key]
if ok {
delete(om.store, key)
}
root, rootFound := om.mapper[key]
if rootFound {
prev := root.Prev
next := root.Next
prev.Next = next
next.Prev = prev
}
}
func (om *OrderedMap) String() string {
builder := make([]string, len(om.store))
var index int = 0
iter := om.IterFunc()
for kv, ok := iter(); ok; kv, ok = iter() {
val, _ := om.Get(kv.Key)
builder[index] = fmt.Sprintf("%v:%v, ", kv.Key, val)
index++
}
return fmt.Sprintf("OrderedMap%v", builder)
}
func (om *OrderedMap) Iter() <-chan *KVPair {
println("Iter() method is deprecated!. Use IterFunc() instead.")
return om.UnsafeIter()
}
/*
Beware, Iterator leaks goroutines if we do not fully traverse the map.
For most cases, `IterFunc()` should work as an iterator.
*/
func (om *OrderedMap) UnsafeIter() <-chan *KVPair {
keys := make(chan *KVPair)
go func() {
defer close(keys)
var curr *node
root := om.root
curr = root.Next
for curr != root {
v, _ := om.store[curr.Value]
keys <- &KVPair{curr.Value, v}
curr = curr.Next
}
}()
return keys
}
func (om *OrderedMap) IterFunc() func() (*KVPair, bool) {
var curr *node
root := om.root
curr = root.Next
return func() (*KVPair, bool) {
for curr != root {
tmp := curr
curr = curr.Next
v, _ := om.store[tmp.Value]
return &KVPair{tmp.Value, v}, true
}
return nil, false
}
}
func (om *OrderedMap) RevIterFunc() func() (*KVPair, bool) {
curr := om.root
for {
if curr.Next == nil || curr.Next == curr || curr == om.root {
break
}
curr = curr.Next
}
start := curr
curr = start.Prev
return func() (*KVPair, bool) {
for curr != start {
tmp := curr
curr = curr.Prev
v, _ := om.store[tmp.Value]
return &KVPair{tmp.Value, v}, true
}
return nil, false
}
}
func (om *OrderedMap) Len() int {
return len(om.store)
}