Uses 11335K of libraries. Click here for Pure Java version (6107L/38K).
1 | sclass PersistentManagedObjects_v1<A extends IManagedObject> { |
2 | replace Addr with int. |
3 | replace BoxedAddr with Int. |
4 | |
5 | ManagedIntObjects_v1 mem; |
6 | IF2<ManagedIntObjects_v1, BoxedAddr, A> makeUserObject; // user needs to fill this |
7 | Root root; |
8 | |
9 | final static int |
10 | TYPE_STRING = -1, |
11 | TYPE_INTARRAY = -2, |
12 | TYPE_ROOT = -3; |
13 | |
14 | class Root extends AbstractManagedObject { |
15 | final static int |
16 | ofs_type = 0, |
17 | ofs_version = 1, |
18 | ofs_freeListPtr = 2, |
19 | ofs_userDataPtr = 3; |
20 | final static int objectSize = ofs_userDataPtr+1; |
21 | |
22 | ManagedIntObjects_v1 mem() { ret PersistentManagedObjects_v1.this.mem; } |
23 | |
24 | // initialize as wrapper for existing object |
25 | // or create new when addr == 0 |
26 | *(Addr addr) { |
27 | super(PersistentManagedObjects_v1.this.mem); |
28 | if (addr != 0) |
29 | setAddr(addr); |
30 | else |
31 | create(); |
32 | } |
33 | |
34 | // initialize as new object |
35 | *() { |
36 | super(PersistentManagedObjects_v1.this.mem); |
37 | create(); |
38 | } |
39 | |
40 | void create { setAddr(mem.alloc(objectSize)); init(); } |
41 | |
42 | void init { type(TYPE_ROOT); version(1); } |
43 | |
44 | // getters + setters |
45 | int type() { ret mem.get(addr+ofs_type); } |
46 | void type(int x) { mem.set(addr+ofs_type, x); } |
47 | int version() { ret mem.get(addr+ofs_version); } |
48 | void version(int x) { mem.set(addr+ofs_version, x); } |
49 | Addr freeListPtr() { ret mem.get(addr+ofs_freeListPtr); } |
50 | void freeListPtr(Addr x) { |
51 | mem.set(addr+ofs_freeListPtr, x); |
52 | print("Free list moved to " + x + " (length=" + (x == 0 ? 0 : mem.get(x)) + ")"); |
53 | } |
54 | Addr userDataPtr() { ret mem.get(addr+ofs_userDataPtr); } |
55 | void userDataPtr(Addr x) { mem.set(addr+ofs_userDataPtr, x); } |
56 | A userData() { |
57 | ret makeUserObject.get(mem, userDataPtr()); |
58 | } |
59 | void userData(A userData) { userDataPtr(userData == null ? 0 : userData.addr()); } |
60 | |
61 | public void setAddr(Addr newAddr) { |
62 | addr = newAddr; mem.setRootField(addr); |
63 | } |
64 | |
65 | // GC handling |
66 | public void scanForCollection(IManagedObjectCollector gc) { |
67 | deb()?.printVars("scanForCollection", +this, +addr, +objectSize); |
68 | gc.noteObject(0, 1, null); |
69 | gc.noteRootPointer(0); |
70 | gc.noteObject(addr, objectSize, lambda1 setAddr); |
71 | //print("note freeList"); |
72 | //gc.notePointer(addr+ofs_freeListPtr); |
73 | //gc.noteIntArray(freeListPtr()); // we're dropping it anyway (it's a compaction) |
74 | |
75 | print("note userDataPtr"); |
76 | gc.notePointer(addr+ofs_userDataPtr); |
77 | var userData = userData(); |
78 | deb()?.printVars("note", +userData); |
79 | userData?.scanForCollection(gc); |
80 | } |
81 | } |
82 | |
83 | // makes a new int[] based storage |
84 | *(IF2<ManagedIntObjects_v1, BoxedAddr, A> makeUserObject) { |
85 | this(new ManagedIntObjects_v1, makeUserObject); |
86 | } |
87 | |
88 | *(ManagedIntObjects_v1 *mem, IF2<ManagedIntObjects_v1, BoxedAddr, A> *makeUserObject) { |
89 | Addr rootPtr = mem.getRootField(); |
90 | print(+rootPtr); |
91 | root = new Root(rootPtr); |
92 | mem.freeList = FreeList.fromIntArray(mem.readIntArray(root.freeListPtr())); |
93 | } |
94 | |
95 | void flush { |
96 | if (mem.freeList.changed) |
97 | saveFreeList(); |
98 | } |
99 | |
100 | void saveFreeList { |
101 | print("Freeing old free list at " + root.freeListPtr()); |
102 | mem.freeIntArray(root.freeListPtr()); |
103 | int arraySize = (mem.freeList.size()+1)*2; // reserve space for one more entry made in the upcoming freeIntArray() call |
104 | int sizeNeeded = 1+arraySize; |
105 | deb()?.printVars(+arraySize, +sizeNeeded); |
106 | Addr ptr = mem.alloc(sizeNeeded); |
107 | deb()?.printVars(+ptr); |
108 | mem.set(ptr, arraySize); // set length |
109 | |
110 | // now all the allocs and frees are done and we can persist |
111 | // the FreeList |
112 | int[] data = mem.freeList.toIntArray(); |
113 | mem.freeList.changed = false; |
114 | |
115 | for i to arraySize: |
116 | mem.set(ptr+1+i, i < data.length ? data[i] : 0); // pad with zeros |
117 | root.freeListPtr(ptr); |
118 | print("Made new free list at " + root.freeListPtr() + " (l=" + mem.read(root.freeListPtr()) + ")"); |
119 | } |
120 | |
121 | A get aka getUserData() { |
122 | ret root.userData(); |
123 | } |
124 | |
125 | void set aka setUserData(A userData) { |
126 | root.userData(userData); |
127 | } |
128 | |
129 | PersistentManagedObjects_v1<A> rotate() { |
130 | flush(); |
131 | ret new PersistentManagedObjects_v1(mem.rotate(), makeUserObject); |
132 | } |
133 | |
134 | void collectAndCompact { |
135 | ManagedIntObjects_v1_Collector collector = new(mem); |
136 | collector.startAddress = 0; |
137 | mem.collectAndCompact(root, collector); |
138 | print("Resetting freeListPtr"); |
139 | root.freeListPtr(0); |
140 | } |
141 | } |
download show line numbers debug dex old transpilations
Travelled to 4 computer(s): bhatertpkbcr, mqqgnosmbjvj, pyentgdyhuwx, vouqrxazstgt
No comments. add comment
Snippet ID: | #1031652 |
Snippet name: | PersistentManagedObjects_v1 |
Eternal ID of this version: | #1031652/42 |
Text MD5: | b594dad86c45123220f9d50bed1b7190 |
Transpilation MD5: | e51b550b76b24ca804c6e98e7c165e2c |
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:14:17 |
Source code size: | 4598 bytes / 141 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 307 / 621 |
Version history: | 41 change(s) |
Referenced in: | [show references] |