forked from Matway/mpl-sl
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Pool.mpl
executable file
·205 lines (166 loc) · 4.5 KB
/
Pool.mpl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
"Pool" module
"control" includeModule
"memory" includeModule
"Union" includeModule
Pool: [
element:;
{
virtual POOL: ();
schema elementSchema: @element;
virtual entrySize: (0 @element newVarOfTheSameType) Union storageSize;
data: 0nx dynamic;
dataSize: 0 dynamic;
firstFree: -1 dynamic;
getAddressByIndex: [
Natx cast entrySize * data +
];
getTailAddressByIndex: [
Natx cast dataSize Natx cast entrySize * data + +
];
elementAt: [
getAddressByIndex @elementSchema addressToReference
];
nextFreeAt: [
getAddressByIndex Int32 addressToReference
];
validAt: [
getTailAddressByIndex Nat8 addressToReference
];
valid: [
copy index:;
index 0i32 same not [0 .ONLY_I32_ALLOWED] when
[index 0 < not [index dataSize <] &&] "Index is out of range!" assert
position: index 3n32 rshift;
offset: index Nat32 cast 7n32 and Nat8 cast;
bitBlock: position validAt;
bitBlock 1n8 offset lshift and 0n8 = not
];
getNextIndex: [
firstFree 0 < [
dataSize copy
] [
firstFree copy
] if
];
at: [
copy index:;
[index valid] "Pool::at: element is invalid!" assert
index elementAt
];
getSize: [
dataSize copy
];
erase: [
copy index:;
[index valid] "Pool::erase: element is invalid!" assert
index getAddressByIndex @elementSchema addressToReference manuallyDestroyVariable
firstFree index nextFreeAt set
position: index 3n32 rshift;
offset: index Nat32 cast 7n32 and Nat8 cast;
bitBlock: position validAt;
bitBlock 1n8 offset lshift xor @bitBlock set
index @firstFree set
];
clear: [
i: firstValid;
[i getSize <] [
i erase
i nextValid !i
] while
];
firstValid: [
i: 0;
[
i dataSize < [i valid not] && [i 1 + !i TRUE] &&
] loop
i
];
nextValid: [
i: 1 +;
[
i dataSize < [i valid not] && [i 1 + !i TRUE] &&
] loop
i
];
insert: [
elementIsMoved: isMoved;
element:;
index: -1 dynamic;
firstFree 0 < [
dataSize @index set
dataSize 0 = [
entrySize 8nx * 1nx + mplMalloc @data set
7 [
i 2 +
i 1 + nextFreeAt set
] times
-1 7 nextFreeAt set
8 @dataSize set
1 @firstFree set
0n8 0 validAt set
] [
upTo8: [Nat32 cast 7n32 + 7n32 ~ and Int32 cast];
newDataSize: dataSize dataSize 4 / + upTo8;
tailSize: dataSize 3n32 rshift;
newTailSize: newDataSize 3n32 rshift;
entrySize newDataSize Natx cast * newTailSize Natx cast + data mplRealloc @data set
getNewTailAddressByIndex: [
Natx cast newDataSize Natx cast entrySize * data + +
];
newValidAt: [
getNewTailAddressByIndex Nat8 addressToReference
];
#set valid
tailSize [
i validAt i newValidAt set
] times
newTailSize tailSize - [
0n8 tailSize i + newValidAt set
] times
#set nextFree entries
newDataSize dataSize - 1 - [
dataSize 2 + i +
dataSize 1 + i + nextFreeAt set
] times
-1 newDataSize 1 - nextFreeAt set
dataSize 1 + @firstFree set
newDataSize @dataSize set
] if
] [
firstFree @index set
index nextFreeAt @firstFree set
] if
newElement: index elementAt;
@newElement manuallyInitVariable
@element elementIsMoved moveIf @newElement set
position: index 3n32 rshift;
offset: index Nat32 cast 7n32 and Nat8 cast;
bitBlock: position validAt;
bitBlock 1n8 offset lshift or @bitBlock set
index
];
INIT: [
0nx dynamic @data set
0 dynamic @dataSize set
-1 dynamic @firstFree set
];
DIE: [
clear
data 0nx = not [
data mplFree
] when
];
}
];
@: ["POOL" has] [.at] pfunc;
!: ["POOL" has] [.at set] pfunc;
each: [b:; "POOL" has] [
eachInPoolBody:;
eachInPoolPool:;
eachInPoolIndex: eachInPoolPool.firstValid;
[eachInPoolIndex eachInPoolPool.getSize <] [
eachInPoolElement: eachInPoolIndex @eachInPoolPool.at;
{index: eachInPoolIndex copy; value: @eachInPoolElement;} @eachInPoolBody call
eachInPoolIndex eachInPoolPool.nextValid !eachInPoolIndex
] while
] pfunc;