pavone@202
|
1 {
|
pavone@202
|
2 linearWithEls <- :els {
|
pavone@74
|
3 key:val <- :k v {
|
pavone@74
|
4 #{
|
pavone@74
|
5 key <- k
|
pavone@74
|
6 val <- v
|
pavone@74
|
7 }
|
pavone@74
|
8 }
|
pavone@74
|
9 find <- :tofind {
|
pavone@74
|
10 idx <- 0
|
pavone@164
|
11 while: {
|
pavone@164
|
12 if: idx < (els length) {
|
pavone@74
|
13 ((els get: idx) key: ) != tofind
|
pavone@164
|
14 } else: {false}
|
pavone@74
|
15 } do: {
|
pavone@74
|
16 idx <- idx + 1
|
pavone@74
|
17 }
|
pavone@74
|
18 if: idx < (els length) {idx} else: {-1}
|
pavone@74
|
19 }
|
pavone@74
|
20 #{
|
pavone@74
|
21 set <- :k v {
|
pavone@74
|
22 idx <- find: k
|
pavone@74
|
23 if: idx < 0 {
|
pavone@74
|
24 els append: (key: k val: v)
|
pavone@74
|
25 } else: {
|
pavone@74
|
26 (els get: idx) val!: v
|
pavone@74
|
27 }
|
pavone@74
|
28 self
|
pavone@74
|
29 }
|
pavone@164
|
30
|
pavone@74
|
31 get <- :k {
|
pavone@74
|
32 get: k withDefault: false
|
pavone@74
|
33 }
|
pavone@164
|
34
|
pavone@74
|
35 get:withDefault <- :k default {
|
pavone@74
|
36 idx <- find: k
|
pavone@74
|
37 if: idx < 0 {
|
pavone@74
|
38 default
|
pavone@74
|
39 } else: {
|
pavone@74
|
40 (els get: idx) val
|
pavone@74
|
41 }
|
pavone@74
|
42 }
|
pavone@164
|
43
|
pavone@164
|
44 get:elseSet <- :k :else {
|
pavone@248
|
45 get: k else: {
|
pavone@164
|
46 v <- else:
|
pavone@164
|
47 els append: (key: k val: v)
|
pavone@164
|
48 v
|
pavone@248
|
49 }
|
pavone@248
|
50 }
|
pavone@248
|
51
|
pavone@248
|
52 get:else <- :k :else {
|
pavone@248
|
53 idx <- find: k
|
pavone@248
|
54 if: idx < 0 {
|
pavone@248
|
55 else:
|
pavone@164
|
56 } else: {
|
pavone@164
|
57 (els get: idx) val
|
pavone@164
|
58 }
|
pavone@164
|
59 }
|
pavone@164
|
60
|
pavone@192
|
61 contains? <- :k {
|
pavone@192
|
62 (find: k) >= 0
|
pavone@192
|
63 }
|
pavone@192
|
64
|
bill@91
|
65 foreach <- :l {
|
bill@91
|
66 foreach: els :idx el {
|
bill@94
|
67 l: (el key) (el val)
|
bill@91
|
68 }
|
bill@91
|
69 }
|
bill@94
|
70
|
pavone@202
|
71 map <- :fun {
|
pavone@202
|
72 newels <- #[]
|
pavone@202
|
73 foreach: els :idx el {
|
pavone@202
|
74 newels append: (key: (el key) val: (fun: (el val)))
|
pavone@202
|
75 }
|
pavone@202
|
76 linearWithEls: newels
|
pavone@202
|
77 }
|
pavone@202
|
78
|
pavone@164
|
79 length <- { els length }
|
pavone@74
|
80 }
|
pavone@74
|
81 }
|
pavone@250
|
82 _empty <- #{
|
pavone@250
|
83 empty? <- { true }
|
pavone@250
|
84 }
|
pavone@250
|
85 _makeBucket <- :key val {
|
pavone@250
|
86 #{
|
pavone@250
|
87 empty? <- { false }
|
pavone@250
|
88 k <- key
|
pavone@250
|
89 v <- val
|
pavone@250
|
90 = <- :other { k = other }
|
pavone@250
|
91 }
|
pavone@250
|
92 }
|
pavone@202
|
93 #{
|
pavone@202
|
94 //requires only that keys support equality
|
pavone@202
|
95 linear <- {
|
pavone@202
|
96 linearWithEls: #[]
|
pavone@202
|
97 }
|
pavone@250
|
98
|
pavone@250
|
99 //requires that keys support equality and hash
|
pavone@250
|
100 hash <- {
|
pavone@250
|
101
|
pavone@250
|
102 _buckets <- #[
|
pavone@250
|
103 _empty
|
pavone@250
|
104 _empty
|
pavone@250
|
105 _empty
|
pavone@250
|
106 _empty]
|
pavone@250
|
107 _size <- 0
|
pavone@250
|
108 _hashdiffs <- #[0]
|
pavone@250
|
109 #{
|
pavone@250
|
110 size <- { size }
|
pavone@250
|
111 ifget:else <- :key ifpres :ifnot {
|
pavone@250
|
112 basehash <- key hash
|
pavone@250
|
113 notdone <- true
|
pavone@250
|
114 i <- 0
|
pavone@250
|
115 ret <- _empty
|
pavone@250
|
116
|
pavone@250
|
117 while: { if: notdone { i < (_hashdiffs length)}} do: {
|
pavone@250
|
118 hv <- basehash + (_hashdiffs get: i)
|
pavone@250
|
119 trunc <- hv % (_buckets length)
|
pavone@250
|
120 if: trunc < 0 { trunc <- 0 - trunc }
|
pavone@250
|
121 bucket <- _buckets get: trunc
|
pavone@250
|
122 if: (bucket empty?) {
|
pavone@250
|
123 notdone <- false
|
pavone@250
|
124 } else: {
|
pavone@250
|
125 if: bucket = key {
|
pavone@250
|
126 ret <- bucket
|
pavone@250
|
127 notdone <- false
|
pavone@250
|
128 }
|
pavone@250
|
129 }
|
pavone@253
|
130 i <- i + 1
|
pavone@250
|
131 }
|
pavone@250
|
132 if: (ret empty?) ifnot else: {
|
pavone@250
|
133 ifpres: (ret v)
|
pavone@250
|
134 }
|
pavone@250
|
135 }
|
pavone@250
|
136
|
pavone@250
|
137 get:else <- :key :else {
|
pavone@250
|
138 ifget: key :val {
|
pavone@250
|
139 val
|
pavone@250
|
140 } else: else
|
pavone@250
|
141 }
|
pavone@250
|
142
|
pavone@250
|
143 contains? <- :key {
|
pavone@250
|
144 ifget: key :_ {
|
pavone@250
|
145 true
|
pavone@250
|
146 } else: {
|
pavone@250
|
147 false
|
pavone@250
|
148 }
|
pavone@250
|
149 }
|
pavone@250
|
150
|
pavone@250
|
151 set <- :key val {
|
pavone@250
|
152 notdone <- true
|
pavone@250
|
153 basehash <- key hash
|
pavone@250
|
154 i <- 0
|
pavone@250
|
155 while: { if: notdone { i < (_hashdiffs length) } } do: {
|
pavone@250
|
156 hv <- basehash + (_hashdiffs get: i)
|
pavone@250
|
157 trunc <- hv % (_buckets length)
|
pavone@250
|
158 if: trunc < 0 { trunc <- 0 - trunc }
|
pavone@250
|
159 bucket <- (_buckets get: trunc)
|
pavone@250
|
160 if: (bucket empty?) {
|
pavone@250
|
161 _size <- _size + 1
|
pavone@250
|
162 _buckets set: trunc (_makeBucket: key val)
|
pavone@250
|
163 notdone <- false
|
pavone@250
|
164 } else: {
|
pavone@250
|
165 if: bucket = key {
|
pavone@250
|
166 bucket v!: val
|
pavone@250
|
167 notdone <- false
|
pavone@250
|
168 }
|
pavone@250
|
169 }
|
pavone@250
|
170 i <- i + 1
|
pavone@250
|
171 }
|
pavone@250
|
172 if: notdone {
|
pavone@250
|
173 newsize <- (_buckets length) * 3 + 1
|
pavone@250
|
174 lastdiff <- _hashdiffs get: ((_hashdiffs length) - 1)
|
pavone@250
|
175 if: lastdiff <= 0 {
|
pavone@250
|
176 _hashdiffs append: 0 - lastdiff + 1
|
pavone@250
|
177 } else: {
|
pavone@250
|
178 _hashdiffs append: 0 - lastdiff
|
pavone@250
|
179 }
|
pavone@250
|
180 newbucks <- #[]
|
pavone@250
|
181 newbucks resize: newsize
|
pavone@250
|
182 while: { (newbucks length) < newsize } do: {
|
pavone@250
|
183 newbucks append: _empty
|
pavone@250
|
184 }
|
pavone@250
|
185 oldbucks <- _buckets
|
pavone@250
|
186 _buckets <- newbucks
|
pavone@250
|
187 _size <- 0
|
pavone@250
|
188 foreach: oldbucks :idx el {
|
pavone@250
|
189 if: (not: (el empty?)) {
|
pavone@250
|
190 set: (el k) (el v)
|
pavone@250
|
191 }
|
pavone@250
|
192 }
|
pavone@250
|
193 set: key val
|
pavone@250
|
194 }
|
pavone@250
|
195 self
|
pavone@250
|
196 }
|
pavone@250
|
197
|
pavone@250
|
198 foreach <- :fun {
|
pavone@250
|
199 foreach: _buckets :idx el {
|
pavone@250
|
200 if: (not: (el empty?)) {
|
pavone@250
|
201 fun: (el k) (el v)
|
pavone@250
|
202 }
|
pavone@250
|
203 }
|
pavone@250
|
204 }
|
pavone@250
|
205 }
|
pavone@250
|
206 }
|
pavone@250
|
207
|
pavone@250
|
208 main <- {
|
pavone@250
|
209 d <- hash
|
pavone@250
|
210 d set: "foo" "bar"
|
pavone@250
|
211 d set: "baz" "qux"
|
pavone@250
|
212 i <- 0
|
pavone@250
|
213 while: { i < 32 } do: {
|
pavone@250
|
214 d set: (string: i) "blah " . (string: i)
|
pavone@250
|
215 i <- i + 1
|
pavone@250
|
216 }
|
pavone@250
|
217 foreach: d :k v {
|
pavone@250
|
218 print: "k: " . k . ", v: " . v . "\n"
|
pavone@250
|
219 }
|
pavone@250
|
220 0
|
pavone@250
|
221 }
|
pavone@202
|
222 }
|
pavone@74
|
223 }
|