Libraryless. Click here for Pure Java version (6697L/37K).
1 | sclass FreeList {
|
2 | MultiSetMap<Int, IntRange> byLength = multiSetMap_innerCustomCompactTreeSet_outerTreeMap(intRangeComparator()); |
3 | CompactTreeSet<IntRange> inOrder = new(intRangeComparator()); |
4 | int totalFree; |
5 | bool changed; |
6 | |
7 | void add(IntRange r) {
|
8 | if (empty(r)) ret; |
9 | // only special case here is merging with previous and/or following entry |
10 | IntRange before = inOrder.floor(r), after = inOrder.ceiling(r); |
11 | deb()?.printVars("FreeList add", +r, +before, +after);
|
12 | |
13 | if (before != null && before.end >= r.start) {
|
14 | if (before.end > r.start) |
15 | failWithVars("You are adding free ranges twice!!", +before, +r);
|
16 | r = IntRange(before.start, r.end); |
17 | deb()?.printVars("FreeList merge", +r, +before);
|
18 | remove(before); |
19 | } |
20 | if (after != null && after.start <= r.end) {
|
21 | if (after.start < r.end) |
22 | failWithVars("You are adding free ranges twice!!", +r, +after);
|
23 | r = IntRange(r.start, after.end); |
24 | deb()?.printVars("FreeList merge", +r, +after);
|
25 | remove(after); |
26 | } |
27 | |
28 | internalAdd(r); |
29 | deb()?.print("FreeList add done", asList());
|
30 | } |
31 | |
32 | /*bool canAdd(IntRange r) { // what?
|
33 | IntRange before = inOrder.floor(r), after = inOrder.ceil(r); |
34 | ret (before == null || before.end <= r.start) |
35 | && (after == null || after.start >= r.end); |
36 | }*/ |
37 | |
38 | bool canRemove(IntRange r) {
|
39 | IntRange r2 = inOrder.floor(r); |
40 | ret r2 != null && r2.end >= r.end; |
41 | } |
42 | |
43 | void internalAdd(IntRange r) {
|
44 | if (r.isEmpty()) ret; |
45 | inOrder.add(r); |
46 | byLength.add(r.length(), r); |
47 | totalFree += r.length(); |
48 | set changed; |
49 | } |
50 | |
51 | void remove(IntRange r) {
|
52 | if (empty(r)) ret; |
53 | IntRange r2 = inOrder.floor(r); |
54 | if (r2 == null) fail("User error");
|
55 | if (eq(r, r2)) {
|
56 | deb()?.printVars("FreeList easy remove", r2);
|
57 | inOrder.remove(r2); |
58 | byLength.remove(r2.length(), r2); |
59 | totalFree -= r2.length(); |
60 | set changed; |
61 | ret; |
62 | } |
63 | |
64 | // remove full range, add back left and right remainders |
65 | deb()?.printVars("FreeList remove", +r, +r2);
|
66 | remove(r2); |
67 | add(IntRange(r2.start, r.start)); |
68 | add(IntRange(r.end, r2.end)); |
69 | deb()?.print("FreeList remove done", asList());
|
70 | } |
71 | |
72 | IntRange findFreeSpace(int minSize) {
|
73 | Map.Entry<Int, Set<IntRange>> e = ((NavigableMap) byLength.data).ceilingEntry(minSize); |
74 | deb()?.printVars("FreeList findFreeSpace", +minSize, e := mapEntryToPair(e));
|
75 | ret e == null ? null : first(e.getValue()); |
76 | } |
77 | |
78 | int totalFree() { ret totalFree; }
|
79 | |
80 | void clear {
|
81 | byLength.clear(); |
82 | inOrder.clear(); |
83 | totalFree = 0; |
84 | changed = false; |
85 | } |
86 | |
87 | IntRange highestFreeRange() { ret last(inOrder); }
|
88 | |
89 | L<IntRange> asList() { ret cloneList(inOrder); }
|
90 | |
91 | static FreeList fromSortedList(L<IntRange> l) {
|
92 | new FreeList fl; |
93 | fOr (IntRange r : l) |
94 | fl.internalAdd(r); |
95 | ret fl; |
96 | } |
97 | |
98 | int[] toIntArray() {
|
99 | ret intRangesToIntArray_startAndLength(inOrder); |
100 | } |
101 | |
102 | static FreeList fromIntArray(int[] a) {
|
103 | ret fromSortedList(intArrayToIntRanges_startAndLength(a)); |
104 | } |
105 | |
106 | int size() { ret l(inOrder); }
|
107 | |
108 | L<IntPair> lengthStats() { ret map toIntPair(multiSetMapToMultiSetPairs(byLength)); }
|
109 | |
110 | void sanityTest {
|
111 | assertEquals((long) totalFree, totalIntRangesLength(inOrder)); |
112 | int longestFree = intMax(intRangeLengths(inOrder)); |
113 | if (longestFree > 0) |
114 | if (findFreeSpace(longestFree) == null) |
115 | fail("Can't find space of size " + longestFree);
|
116 | } |
117 | } |
download show line numbers debug dex old transpilations
Travelled to 7 computer(s): bhatertpkbcr, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tvejysmllsmz, vouqrxazstgt, xrpafgyirdlv
No comments. add comment
| Snippet ID: | #1029228 |
| Snippet name: | FreeList [sems to work] |
| Eternal ID of this version: | #1029228/46 |
| Text MD5: | 51e47bf07f6ebb73bf34828cf8337a5b |
| Transpilation MD5: | 40456aa4b0ee8f55da60a5fc4cd52d67 |
| Author: | stefan |
| Category: | javax |
| Type: | JavaX fragment (include) |
| Public (visible to everyone): | Yes |
| Archived (hidden from active list): | No |
| Created/modified: | 2021-06-25 13:31:43 |
| Source code size: | 3592 bytes / 117 lines |
| Pitched / IR pitched: | No / No |
| Views / Downloads: | 570 / 1077 |
| Version history: | 45 change(s) |
| Referenced in: | [show references] |