1 | sclass SortedStringMap_managed extends AbstractManagedObject { |
2 | replace Addr with int. |
3 | |
4 | new TreeMap<S, Entry> map; |
5 | int physicalLength; // total array length is twice this. data is: String *key, String *value, ... |
6 | int size; // our actual length |
7 | |
8 | // it's actually a union |
9 | class Entry { |
10 | int index; // also when not loaded |
11 | S value; // only when loaded |
12 | |
13 | *(int *index) {} |
14 | *(int *index, S *value) {} |
15 | |
16 | S value() { |
17 | if (value == null) |
18 | value = mem.readString(valueAddr(index)); |
19 | ret value; |
20 | } |
21 | } |
22 | |
23 | int size() { ret l(map); } |
24 | |
25 | int arrayStart() { ret addr+2; } |
26 | int keyAddr(int i) { ret arrayStart()+i*2; } |
27 | int valueAddr(int i) { ret arrayStart()+i*2+1; } |
28 | |
29 | // read from memory |
30 | *(ManagedIntObjects_v1 *mem, Addr *addr) { |
31 | physicalLength = mem.get(addr); |
32 | size = mem.get(addr+1); |
33 | for i to size: |
34 | map.put(mem.readString(keyAddr(i)), new Entry(valueAddr(i))); |
35 | } |
36 | |
37 | *(ManagedIntObjects_v1 *mem, SS initialData) { |
38 | SS sorted; |
39 | if (initialData instanceof TreeMap) { |
40 | map.setComparator(initialData.comparator()); |
41 | sorted = initialData; |
42 | } else |
43 | sorted = new TreeMap(unnull(initialData), map.comparator()); |
44 | |
45 | physicalLength = l(sorted); |
46 | alloc(objectSize()); |
47 | mem.set(addr, physicalLength); |
48 | |
49 | int i = 0; |
50 | for (S key, S value : sorted) |
51 | map.put(key, new Entry(i++, value)); |
52 | |
53 | flush(); |
54 | } |
55 | |
56 | void flush { |
57 | ensureCapacityInternal(size()); |
58 | mem.set(addr+1, size()); |
59 | int i = 0; |
60 | for (S key, Entry entry : map) { |
61 | int keyPtr = mem.get(keyAddr(i)); |
62 | if (!eq(mem.readString(keyPtr), key)) { |
63 | mem.freeString(keyAddr(i)); // strings belong to map |
64 | mem.set(keyAddr(i), mem.newString(key)); |
65 | } |
66 | |
67 | int valuePtr = mem.get(valueAddr(i)); |
68 | if (entry.index != i |
69 | || entry.value != null && !eq(entry.value |
70 | if (!eq(mem.readString(valuePtr), entry.value())) { |
71 | mem.freeString(valueAddr(i)); // strings belong to map |
72 | mem.set(valueAddr(i), mem.newString(key)); |
73 | } |
74 | map.put(key, new Entry(i++, value)); |
75 | } |
76 | } |
77 | |
78 | void ensureCapacityInternal(int minCapacity) { |
79 | if (physicalLength < minCapacity) grow(minCapacity); |
80 | } |
81 | |
82 | private void grow(int minCapacity) { |
83 | int oldCapacity = physicalLength; |
84 | int newCapacity = oldCapacity + (oldCapacity >> 1); |
85 | if (newCapacity - minCapacity < 0) |
86 | newCapacity = minCapacity; |
87 | long oldAddr = addr, oldSize = objectSize(); |
88 | physicalLength = newCapacity; |
89 | setAddr(mem.alloc(objectSize())); |
90 | for (int i = 1; i < oldSize; i++) |
91 | mem.set(addr+i, mem.get(oldAddr+i)); |
92 | mem.free(oldAddr, oldSize); |
93 | mem.set(addr, physicalLength); |
94 | } |
95 | |
96 | // GC handling |
97 | public void scanForCollection(IManagedObjectCollector gc) { |
98 | gc.noteObject(addr, objectSize()); |
99 | } |
100 | |
101 | int objectSize() { ret 2+physicalLength*2; } |
102 | } |
Began life as a copy of #1031653
download show line numbers debug dex old transpilations
Travelled to 4 computer(s): bhatertpkbcr, mqqgnosmbjvj, pyentgdyhuwx, vouqrxazstgt
No comments. add comment
Snippet ID: | #1031661 |
Snippet name: | SortedStringMap_managed [dev.] |
Eternal ID of this version: | #1031661/3 |
Text MD5: | 3a79d5de0b5b54aac42266729022f9b4 |
Author: | stefan |
Category: | javax |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2021-06-25 07:44:07 |
Source code size: | 3002 bytes / 102 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 137 / 164 |
Version history: | 2 change(s) |
Referenced in: | [show references] |