1package ds.persistent.map;
2
3
4
5
6
7
8
9
10
11
12import ds.interfaces.Map;
13
14import ds.util.K;
15import ds.util.V;
16import ds.util.KV;
17import static ds.util.KV.mkPair;
18
19import ds.util.Function2;
20import ds.util.Invariant;
21import ds.util.NullIterator;
22import ds.util.Pair;
23import ds.util.Predicate;
24
25import java.util.Iterator;
26
27import static java.lang.Integer.signum;
28import static ds.util.Undef.undefined;
29
30
31
32public abstract
33 class OrderedList
34 implements Map {
35
36
37
38
39
40 public static OrderedList empty() {
41 return
42 EMPTY;
43 }
44
45
46 public static OrderedList singleton(K k, V v) {
47 return
48 EMPTY.cons(k, v);
49 }
50
51
52 public static
53 OrderedList fromIterator(Iterator<KV> elems) {
54
55 OrderedList res = empty();
56 while ( elems.hasNext() ) {
57 KV p = elems.next();
58 res = res.insert(p.fst, p.snd);
59 }
60 return
61 res;
62 }
63
64 public boolean member(K k) {
65 return
66 lookup(k) != null;
67 }
68
69 public abstract OrderedList
70 insert(K k, V v);
71
72 public abstract OrderedList
73 remove(K k);
74
75 public OrderedList
76 union(Map m2) {
77 return
78 unionWith(const2, m2);
79 }
80
81 public abstract OrderedList
82 unionWith(Function2<V,V,V> op,
83 Map m2);
84
85 public OrderedList
86 difference(Map m2) {
87 return
88 differenceWith(null2, m2);
89 }
90
91 public abstract OrderedList
92 differenceWith(Function2<V,V,V> op,
93 Map m2);
94
95 public OrderedList copy() {
96 return
97 this;
98 }
99
100
101
102
103
104 Node node() { return nodeExpected(); }
105 K key() { return nodeExpected(); }
106 V value() { return nodeExpected(); }
107 OrderedList next() { return nodeExpected(); }
108
109 private static <A> A nodeExpected() {
110 return
111 undefined("Node expected");
112 }
113
114
115 protected
116 Node cons(K k, V v) {
117 return
118 new Node(k, v, this);
119 }
120
121 private static Function2<V,V,V> const2
122 = new Function2<V,V,V>() {
123 public V apply(V x, V y) {
124 return y;
125 }
126 };
127
128 private static Function2<V,V,V> null2
129 = new Function2<V,V,V>() {
130 public V apply(V x, V y) {
131 return null;
132 }
133 };
134
135
136
137
138
139
140
141 private static final OrderedList EMPTY
142 = new Empty();
143
144
145
146 private static final
147 class Empty
148 extends OrderedList {
149
150
151 public boolean isEmpty() {
152 return true;
153 }
154
155 public int size() {
156 return 0;
157 }
158
159 public V lookup(K k) {
160 return null;
161 }
162
163 public KV findMin() {
164 return nodeExpected();
165 }
166
167 public KV findMax() {
168 return nodeExpected();
169 }
170
171 public boolean inv() {
172 return true;
173 }
174
175 public Iterator<KV> iterator() {
176 ++cntIter;
177 return
178 new NullIterator<KV>();
179 }
180
181
182 public OrderedList insert(K k, V v) {
183 return
184 singleton(k, v);
185 }
186 public OrderedList remove(K k) {
187 return
188 this;
189 }
190
191 public OrderedList
192 unionWith(Function2<V,V,V> op,
193 Map m2) {
194 return
195 (OrderedList)m2;
196 }
197
198 public OrderedList
199 differenceWith(Function2<V,V,V> op,
200 Map m2) {
201 return
202 this;
203 }
204
205
206
207
208 Empty() { }
209
210 }
211
212
213
214
215 private static final
216 class Node
217 extends OrderedList {
218
219
220 final K k;
221 final V v;
222 final OrderedList next;
223
224
225
226
227
228
229
230 Node(K k, V v, OrderedList next) {
231 assert k != null;
232
233 this.k = k;
234 this.v = v;
235 this.next = next;
236 ++cntNode;
237 }
238
239
240
241
242 public boolean isEmpty() {
243 return false;
244 }
245
246 public int size() {
247 return
248 1 + next.size();
249 }
250
251 public V lookup(K k) {
252 assert k != null;
253
254 switch ( signum(k.compareTo(this.k)) ) {
255 case -1:
256 return
257 null;
258 case 0:
259 return
260 v;
261 case +1:
262 return
263 next.lookup(k);
264 }
265
266 return
267 null;
268 }
269
270 public KV findMin() {
271 return
272 mkPair(k, v);
273 }
274
275 public KV findMax() {
276 if ( next.isEmpty() )
277 return
278 mkPair(k, v);
279 return
280 next.findMax();
281 }
282
283 public Iterator<KV> iterator() {
284 ++cntIter;
285 return
286 new NodeIterator(this);
287 }
288
289 public boolean inv() {
290 if ( next.isEmpty() )
291 return
292 true;
293 return
294 k.compareTo(next.key()) < 0
295 &&
296 next.inv();
297 }
298
299
300
301
302
303
304 Node node() { return this; }
305 K key() { return k; }
306 V value() { return v; }
307 OrderedList next() { return next; }
308
309
310
311 private Node setNext(OrderedList next) {
312
313 if ( next == this.next )
314 return
315 this;
316 return
317 next.cons(this.k, this.v);
318
319
320
321
322
323
324 }
325
326 private Node setV(V v) {
327
328 return
329 ( v == this.v )
330 ? this
331 : next.cons(this.k, v);
332
333
334
335
336
337
338 }
339
340
341
342
343 public OrderedList insert(K k, V v) {
344 assert k != null;
345
346 switch ( signum(k.compareTo(this.k)) ) {
347 case -1:
348 return
349 this.cons(k, v);
350 case 0:
351 return
352 setV(v);
353 case +1:
354 return
355 setNext(next.insert(k, v));
356 }
357
358 return
359 null;
360 }
361
362 public OrderedList remove(K k) {
363 assert k != null;
364
365 switch ( signum(k.compareTo(this.k)) ) {
366 case -1:
367 return
368 this;
369 case 0:
370 return
371 next;
372 case +1:
373 return
374 setNext(next.remove(k));
375 }
376
377 return
378 null;
379 }
380
381 public OrderedList
382 union(Map m2) {
383 return
384 unionWith(const2, m2);
385 }
386
387 public OrderedList
388 unionWith(Function2<V,V,V> op,
389 Map m2) {
390 if ( m2.isEmpty() )
391 return
392 this;
393
394 Node n2 = ((OrderedList)m2).node();
395 switch ( signum(n2.k.compareTo(this.k)) ) {
396
397 case -1:
398 return
399 n2.setNext(unionWith(op, n2.next));
400
401 case 0:
402 return
403 setV(op.apply(v, n2.v)).setNext(next.unionWith(op, n2.next));
404
405 case +1:
406 return
407 setNext(next.unionWith(op, m2));
408 }
409
410 return
411 null;
412 }
413
414 public OrderedList
415 differenceWith(Function2<V,V,V> op,
416 Map m2) {
417 if ( m2.isEmpty() )
418 return
419 this;
420
421 Node n2 = ((OrderedList)m2).node();
422 switch ( signum(n2.k.compareTo(this.k)) ) {
423
424 case -1:
425 return
426 unionWith(op, n2.next);
427
428 case 0:
429 V v1 = op.apply(v, n2.v);
430 OrderedList l1 = next.unionWith(op, n2.next);
431 if ( v1 == null )
432 return
433 l1;
434 return
435 setV(v1).setNext(l1);
436
437 case +1:
438 return
439 setNext(next.unionWith(op, m2));
440 }
441
442 return
443 null;
444 }
445
446
447
448
449
450
451
452
453
454
455
456
457
458 private static
459 class NodeIterator
460 extends ds.util.Iterator<KV> {
461
462 OrderedList queue;
463
464 NodeIterator(Node n) {
465 queue = n;
466 ++cntIter;
467 }
468
469 public boolean hasNext() {
470 return
471 ! queue.isEmpty();
472 }
473
474 public KV next() {
475 if ( queue.isEmpty() )
476 return
477 undefined("empty list");
478
479 Node n = queue.node();
480 queue = queue.next();
481 return
482 mkPair(n.k, n.v);
483 }
484 }
485 }
486
487
488
489
490 private static int cntNode = 0;
491 private static int cntIter = 0;
492
493 public static String stats() {
494 return
495 "stats for ds.persistent.map.OrderedList:\n" +
496 "# new Node() : " + cntNode + "\n" +
497 "# new Iterator() : " + cntIter + "\n";
498 }
499
500 public String objStats() {
501 int s = size();
502 int o = s;
503 int f = 3 * s;
504 int m = o + f;
505
506 return
507 "mem stats for ds.persistent.map.OrderedList object:\n" +
508 "# elements (size) : " + s + "\n" +
509 "# objects : " + o + "\n" +
510 "# fields : " + f + "\n" +
511 "# mem words : " + m + "\n";
512 }
513}