1 | // A must be comparable |
2 | sclass ArrayTreeMap<A, B> extends AbstractMap<A, B> { |
3 | O[] array; // key, value, key, value... |
4 | int size; |
5 | |
6 | *() {} |
7 | *(Map<A, B> map) { |
8 | array = new O[roundUpToPowerOfTwo(l(map))*2]; |
9 | fill(sorted(keys(map)), map, 0, l(array)/2, 0); |
10 | size = l(map); |
11 | } |
12 | |
13 | public int size() { ret size; } |
14 | |
15 | public Set<Map.Entry<A, B>> entrySet() { |
16 | ret new EntrySet; |
17 | } |
18 | |
19 | bool inRange(int i) { |
20 | ret i >= 0 && i < l(array); |
21 | } |
22 | |
23 | int check(int i) { ret inRange(i) ? i : -1; } |
24 | |
25 | int parent(int i) { ret check(i == 0 ? -1 : ((i-2)/2) & ~1); } |
26 | int left(int i) { ret check(i*2+2); } |
27 | int right(int i) { ret check(i*2+4); } |
28 | |
29 | int first() { |
30 | if (l(array) == 0) ret -1; |
31 | int p = 0; |
32 | while (left(p) >= 0) |
33 | p = left(p); |
34 | ret p; |
35 | } |
36 | |
37 | int successor(int t) { |
38 | if (!inRange(t)) ret -1; |
39 | if (right(t) >= 0) { |
40 | int p = right(t); |
41 | while (left(p) >= 0) |
42 | p = left(p); |
43 | ret p; |
44 | } |
45 | int p = parent(t); |
46 | int ch = t; |
47 | while (p >= 0 && ch == right(p)) { |
48 | ch = p; |
49 | p = parent(p); |
50 | } |
51 | ret p; |
52 | } |
53 | |
54 | void fill(L<A> l, Map<A, B> map, int lIdx1, int lIdx2, int aIdx) { |
55 | if (lIdx2 <= lIdx1) ret; |
56 | int middle = (lIdx1+lIdx2)/2; |
57 | A key = _get(l, middle); |
58 | array[aIdx*2] = key; |
59 | array[aIdx*2+1] = map.get(key); |
60 | fill(l, map, lIdx1, middle, aIdx*2+1); |
61 | fill(l, map, middle+1, lIdx2, aIdx*2+2); |
62 | } |
63 | |
64 | int find(O a) { |
65 | int i = 0; |
66 | while (i < l(array)) { |
67 | int x = array[i] == null ? -1 : cmp(a, array[i]); |
68 | if (x == 0) ret i; |
69 | i = i*2+(x > 0 ? 4 : 2); |
70 | } |
71 | ret -1; |
72 | } |
73 | |
74 | public bool containsKey(O a) { |
75 | ret find(a) >= 0; |
76 | } |
77 | |
78 | public B get(O a) { |
79 | int i = find(a); |
80 | ret i >= 0 ? (B) array[i+1] : null; |
81 | } |
82 | |
83 | class EntrySet extends AbstractSet<Map.Entry<A, B>> { |
84 | public Iterator<Map.Entry<A, B>> iterator() { |
85 | ret new EntryIterator(first()); |
86 | } |
87 | |
88 | public int size() { |
89 | ret ArrayTreeMap.this.size(); |
90 | } |
91 | } |
92 | |
93 | class EntryIterator implements Iterator<Map.Entry<A, B>> { |
94 | int next = -1, lastReturned = -1; |
95 | |
96 | *(int first) { |
97 | next = first; |
98 | } |
99 | |
100 | public final bool hasNext() { |
101 | ret next >= 0; |
102 | } |
103 | |
104 | public Map.Entry<A, B> next() { |
105 | int e = next; |
106 | if (e < 0) |
107 | throw new NoSuchElementException; |
108 | |
109 | do { |
110 | next = successor(next); |
111 | } while (next >= 0 && array[next] == null); |
112 | |
113 | lastReturned = e; |
114 | ret new SimpleImmutableEntry((A) array[e], (B) array[e+1]); |
115 | } |
116 | } |
117 | } |
Began life as a copy of #1011276
download show line numbers debug dex old transpilations
Travelled to 13 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt
No comments. add comment
Snippet ID: | #1011277 |
Snippet name: | ArrayTreeMap - quite compact map, but SortedImmutableList is more compact |
Eternal ID of this version: | #1011277/22 |
Text MD5: | 0adcd67678ce58199577c84e468d5799 |
Author: | stefan |
Category: | javax |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2017-10-29 23:33:47 |
Source code size: | 2644 bytes / 117 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 345 / 962 |
Version history: | 21 change(s) |
Referenced in: | [show references] |