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: | 334 / 783 |
Version history: | 45 change(s) |
Referenced in: | [show references] |