@peerbit/shared-log 8.0.7 → 9.0.0-55cebfe
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/benchmark/get-samples.d.ts +2 -0
- package/dist/benchmark/get-samples.d.ts.map +1 -0
- package/dist/benchmark/get-samples.js +69 -0
- package/dist/benchmark/get-samples.js.map +1 -0
- package/dist/benchmark/index.d.ts +2 -0
- package/dist/benchmark/index.d.ts.map +1 -0
- package/{lib/esm/__benchmark__ → dist/benchmark}/index.js +16 -16
- package/dist/benchmark/index.js.map +1 -0
- package/dist/benchmark/replication-prune.d.ts +2 -0
- package/dist/benchmark/replication-prune.d.ts.map +1 -0
- package/dist/benchmark/replication-prune.js +103 -0
- package/dist/benchmark/replication-prune.js.map +1 -0
- package/dist/benchmark/replication.d.ts +2 -0
- package/dist/benchmark/replication.d.ts.map +1 -0
- package/dist/benchmark/replication.js +91 -0
- package/dist/benchmark/replication.js.map +1 -0
- package/{lib/esm → dist/src}/blocks.d.ts +1 -0
- package/dist/src/blocks.d.ts.map +1 -0
- package/{lib/esm → dist/src}/blocks.js +1 -1
- package/dist/src/blocks.js.map +1 -0
- package/{lib/esm → dist/src}/cpu.d.ts +2 -1
- package/dist/src/cpu.d.ts.map +1 -0
- package/{lib/esm → dist/src}/cpu.js +2 -2
- package/dist/src/cpu.js.map +1 -0
- package/{lib/esm → dist/src}/exchange-heads.d.ts +2 -1
- package/dist/src/exchange-heads.d.ts.map +1 -0
- package/{lib/esm → dist/src}/exchange-heads.js +9 -7
- package/dist/src/exchange-heads.js.map +1 -0
- package/{lib/esm → dist/src}/index.d.ts +64 -54
- package/dist/src/index.d.ts.map +1 -0
- package/{lib/esm → dist/src}/index.js +569 -399
- package/dist/src/index.js.map +1 -0
- package/{lib/esm → dist/src}/message.d.ts +1 -0
- package/dist/src/message.d.ts.map +1 -0
- package/{lib/esm → dist/src}/pid.d.ts +1 -0
- package/dist/src/pid.d.ts.map +1 -0
- package/{lib/esm → dist/src}/pid.js +20 -20
- package/dist/src/pid.js.map +1 -0
- package/dist/src/ranges.d.ts +10 -0
- package/dist/src/ranges.d.ts.map +1 -0
- package/dist/src/ranges.js +645 -0
- package/dist/src/ranges.js.map +1 -0
- package/dist/src/replication.d.ts +112 -0
- package/dist/src/replication.d.ts.map +1 -0
- package/dist/src/replication.js +348 -0
- package/dist/src/replication.js.map +1 -0
- package/dist/src/role.d.ts +2 -0
- package/dist/src/role.d.ts.map +1 -0
- package/dist/src/role.js +106 -0
- package/dist/src/role.js.map +1 -0
- package/package.json +70 -43
- package/src/blocks.ts +1 -1
- package/src/cpu.ts +7 -6
- package/src/exchange-heads.ts +19 -19
- package/src/index.ts +881 -609
- package/src/pid.ts +22 -21
- package/src/ranges.ts +692 -148
- package/src/replication.ts +271 -19
- package/src/role.ts +63 -83
- package/LICENSE +0 -202
- package/lib/esm/__benchmark__/index.d.ts +0 -1
- package/lib/esm/__benchmark__/index.js.map +0 -1
- package/lib/esm/blocks.js.map +0 -1
- package/lib/esm/cpu.js.map +0 -1
- package/lib/esm/exchange-heads.js.map +0 -1
- package/lib/esm/index.js.map +0 -1
- package/lib/esm/pid.js.map +0 -1
- package/lib/esm/ranges.d.ts +0 -12
- package/lib/esm/ranges.js +0 -247
- package/lib/esm/ranges.js.map +0 -1
- package/lib/esm/replication.d.ts +0 -53
- package/lib/esm/replication.js +0 -105
- package/lib/esm/replication.js.map +0 -1
- package/lib/esm/role.d.ts +0 -38
- package/lib/esm/role.js +0 -130
- package/lib/esm/role.js.map +0 -1
- package/src/__benchmark__/index.ts +0 -115
- /package/{lib/esm → dist/src}/message.js +0 -0
- /package/{lib/esm → dist/src}/message.js.map +0 -0
package/src/ranges.ts
CHANGED
|
@@ -1,10 +1,30 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { type PublicSignKey, equals } from "@peerbit/crypto";
|
|
2
|
+
import {
|
|
3
|
+
And,
|
|
4
|
+
Compare,
|
|
5
|
+
type Index,
|
|
6
|
+
type IndexIterator,
|
|
7
|
+
type IndexedResult,
|
|
8
|
+
type IndexedResults,
|
|
9
|
+
IntegerCompare,
|
|
10
|
+
Or,
|
|
11
|
+
type Query,
|
|
12
|
+
SearchRequest,
|
|
13
|
+
Sort,
|
|
14
|
+
SortDirection,
|
|
15
|
+
StringMatch,
|
|
16
|
+
iterate,
|
|
17
|
+
iteratorInSeries,
|
|
18
|
+
} from "@peerbit/indexer-interface";
|
|
19
|
+
import {
|
|
20
|
+
/* getSegmentsFromOffsetAndRange, */
|
|
21
|
+
type ReplicationRangeIndexable,
|
|
22
|
+
} from "./replication.js";
|
|
23
|
+
import { SEGMENT_COORDINATE_SCALE } from "./role.js";
|
|
24
|
+
|
|
25
|
+
/*
|
|
6
26
|
export const containsPoint = (
|
|
7
|
-
rect: { offset: number;
|
|
27
|
+
rect: { offset: number; length: number },
|
|
8
28
|
point: number,
|
|
9
29
|
eps = 0.00001 // we do this to handle numerical errors
|
|
10
30
|
) => {
|
|
@@ -26,209 +46,733 @@ export const containsPoint = (
|
|
|
26
46
|
!inFirstInterval && wrapped && point >= 0 && point < end;
|
|
27
47
|
|
|
28
48
|
return inFirstInterval || inSecondInterval;
|
|
49
|
+
}; */
|
|
50
|
+
|
|
51
|
+
/* const resolveRectsThatContainPoint = async (
|
|
52
|
+
rects: Index<ReplicationRangeIndexable>,
|
|
53
|
+
point: number,
|
|
54
|
+
roleAgeLimit: number,
|
|
55
|
+
matured: boolean
|
|
56
|
+
): Promise<ReplicationRangeIndexable[]> => {
|
|
57
|
+
// point is between 0 and 1, and the range can start at any offset between 0 and 1 and have length between 0 and 1
|
|
58
|
+
// so we need to query for all ranges that contain the point
|
|
59
|
+
const scaledPoint = Math.round(point * SEGMENT_COORDINATE_SCALE)
|
|
60
|
+
let queries = [
|
|
61
|
+
new IntegerCompare({ key: 'start', compare: Compare.LessOrEqual, value: scaledPoint }),
|
|
62
|
+
new IntegerCompare({ key: 'end', compare: Compare.Greater, value: scaledPoint }),
|
|
63
|
+
new IntegerCompare({ key: 'timestamp', compare: matured ? Compare.LessOrEqual : Compare.Greater, value: Date.now() - roleAgeLimit })
|
|
64
|
+
]
|
|
65
|
+
|
|
66
|
+
const results = await rects.query(new SearchRequest({
|
|
67
|
+
query: [
|
|
68
|
+
new Nested({
|
|
69
|
+
path: 'segments',
|
|
70
|
+
query: queries
|
|
71
|
+
})
|
|
72
|
+
]
|
|
73
|
+
}))
|
|
74
|
+
return results.results.map(x => x.value)
|
|
75
|
+
} */
|
|
76
|
+
|
|
77
|
+
/* const resolveRectsInRange = async (rects: Index<ReplicationRangeIndexable>,
|
|
78
|
+
start: number,
|
|
79
|
+
end: number,
|
|
80
|
+
roleAgeLimit: number,
|
|
81
|
+
matured: boolean
|
|
82
|
+
): Promise<ReplicationRangeIndexable[]> => {
|
|
83
|
+
// point is between 0 and 1, and the range can start at any offset between 0 and 1 and have length between 0 and 1
|
|
84
|
+
// so we need to query for all ranges that contain the point
|
|
85
|
+
let endScaled = Math.round(end * SEGMENT_COORDINATE_SCALE);
|
|
86
|
+
let startScaled = Math.round(start * SEGMENT_COORDINATE_SCALE);
|
|
87
|
+
let queries = [
|
|
88
|
+
new Or([
|
|
89
|
+
new And([
|
|
90
|
+
new IntegerCompare({ key: 'start1', compare: Compare.Less, value: endScaled }),
|
|
91
|
+
new IntegerCompare({ key: 'end1', compare: Compare.GreaterOrEqual, value: startScaled }),
|
|
92
|
+
]),
|
|
93
|
+
new And([
|
|
94
|
+
new IntegerCompare({ key: 'start2', compare: Compare.Less, value: endScaled }),
|
|
95
|
+
new IntegerCompare({ key: 'end2', compare: Compare.GreaterOrEqual, value: startScaled }),
|
|
96
|
+
])
|
|
97
|
+
]),
|
|
98
|
+
new IntegerCompare({ key: 'timestamp', compare: matured ? Compare.LessOrEqual : Compare.Greater, value: BigInt(+new Date - roleAgeLimit) })
|
|
99
|
+
]
|
|
100
|
+
|
|
101
|
+
const results = await rects.query(new SearchRequest({
|
|
102
|
+
query: queries,
|
|
103
|
+
sort: [new Sort({ key: "start1" }), new Sort({ key: "start2" })],
|
|
104
|
+
fetch: 0xffffffff
|
|
105
|
+
}))
|
|
106
|
+
return results.results.map(x => x.value)
|
|
107
|
+
} */
|
|
108
|
+
|
|
109
|
+
const containingPoint = (
|
|
110
|
+
rects: Index<ReplicationRangeIndexable>,
|
|
111
|
+
point: number,
|
|
112
|
+
roleAgeLimit: number,
|
|
113
|
+
matured: boolean,
|
|
114
|
+
now: number,
|
|
115
|
+
options?: {
|
|
116
|
+
sort?: Sort[];
|
|
117
|
+
scaled?: boolean;
|
|
118
|
+
},
|
|
119
|
+
): IndexIterator<ReplicationRangeIndexable> => {
|
|
120
|
+
// point is between 0 and 1, and the range can start at any offset between 0 and 1 and have length between 0 and 1
|
|
121
|
+
// so we need to query for all ranges that contain the point
|
|
122
|
+
let pointScaled = Math.round(
|
|
123
|
+
point * (options?.scaled ? 1 : SEGMENT_COORDINATE_SCALE),
|
|
124
|
+
);
|
|
125
|
+
let queries = [
|
|
126
|
+
new Or([
|
|
127
|
+
new And([
|
|
128
|
+
new IntegerCompare({
|
|
129
|
+
key: "start1",
|
|
130
|
+
compare: Compare.LessOrEqual,
|
|
131
|
+
value: pointScaled,
|
|
132
|
+
}),
|
|
133
|
+
new IntegerCompare({
|
|
134
|
+
key: "end1",
|
|
135
|
+
compare: Compare.Greater,
|
|
136
|
+
value: pointScaled,
|
|
137
|
+
}),
|
|
138
|
+
]),
|
|
139
|
+
new And([
|
|
140
|
+
new IntegerCompare({
|
|
141
|
+
key: "start2",
|
|
142
|
+
compare: Compare.LessOrEqual,
|
|
143
|
+
value: pointScaled,
|
|
144
|
+
}),
|
|
145
|
+
new IntegerCompare({
|
|
146
|
+
key: "end2",
|
|
147
|
+
compare: Compare.Greater,
|
|
148
|
+
value: pointScaled,
|
|
149
|
+
}),
|
|
150
|
+
]),
|
|
151
|
+
]),
|
|
152
|
+
new IntegerCompare({
|
|
153
|
+
key: "timestamp",
|
|
154
|
+
compare: matured ? Compare.LessOrEqual : Compare.Greater,
|
|
155
|
+
value: BigInt(now - roleAgeLimit),
|
|
156
|
+
}),
|
|
157
|
+
];
|
|
158
|
+
return iterate(
|
|
159
|
+
rects,
|
|
160
|
+
new SearchRequest({
|
|
161
|
+
query: queries,
|
|
162
|
+
sort: options?.sort,
|
|
163
|
+
fetch: 0xffffffff,
|
|
164
|
+
}),
|
|
165
|
+
);
|
|
166
|
+
/* const results = await rects.query(new SearchRequest({
|
|
167
|
+
query: queries,
|
|
168
|
+
sort: options?.sort,
|
|
169
|
+
fetch: 0xffffffff
|
|
170
|
+
}))
|
|
171
|
+
return results.results.map(x => x.value) */
|
|
29
172
|
};
|
|
30
173
|
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
peers: yallist<ReplicatorRect>,
|
|
35
|
-
currentNode: yallist.Node<ReplicatorRect> | null,
|
|
36
|
-
collector: (rect: ReplicatorRect, matured: boolean) => void,
|
|
174
|
+
const getClosest = (
|
|
175
|
+
direction: "above" | "below",
|
|
176
|
+
rects: Index<ReplicationRangeIndexable>,
|
|
37
177
|
point: number,
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
178
|
+
roleAgeLimit: number,
|
|
179
|
+
matured: boolean,
|
|
180
|
+
now: number,
|
|
181
|
+
scaled: boolean = false,
|
|
182
|
+
): IndexIterator<ReplicationRangeIndexable> => {
|
|
183
|
+
const scaledPoint = Math.round(
|
|
184
|
+
point * (scaled ? 1 : SEGMENT_COORDINATE_SCALE),
|
|
185
|
+
);
|
|
186
|
+
const createQueries = (p: number, equality: boolean) => {
|
|
187
|
+
let queries: Query[];
|
|
188
|
+
if (direction === "below") {
|
|
189
|
+
queries = [
|
|
190
|
+
new IntegerCompare({
|
|
191
|
+
key: "end2",
|
|
192
|
+
compare: equality ? Compare.LessOrEqual : Compare.Less,
|
|
193
|
+
value: p,
|
|
194
|
+
}),
|
|
195
|
+
new IntegerCompare({
|
|
196
|
+
key: "timestamp",
|
|
197
|
+
compare: matured ? Compare.LessOrEqual : Compare.GreaterOrEqual,
|
|
198
|
+
value: BigInt(now - roleAgeLimit),
|
|
199
|
+
}),
|
|
200
|
+
];
|
|
201
|
+
} else {
|
|
202
|
+
queries = [
|
|
203
|
+
new IntegerCompare({
|
|
204
|
+
key: "start1",
|
|
205
|
+
compare: equality ? Compare.GreaterOrEqual : Compare.Greater,
|
|
206
|
+
value: p,
|
|
207
|
+
}),
|
|
208
|
+
new IntegerCompare({
|
|
209
|
+
key: "timestamp",
|
|
210
|
+
compare: matured ? Compare.LessOrEqual : Compare.GreaterOrEqual,
|
|
211
|
+
value: BigInt(now - roleAgeLimit),
|
|
212
|
+
}),
|
|
213
|
+
];
|
|
214
|
+
}
|
|
215
|
+
queries.push(
|
|
216
|
+
new IntegerCompare({ key: "width", compare: Compare.Greater, value: 0 }),
|
|
217
|
+
);
|
|
218
|
+
return queries;
|
|
44
219
|
};
|
|
45
220
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
221
|
+
const iterator = iterate(
|
|
222
|
+
rects,
|
|
223
|
+
new SearchRequest({
|
|
224
|
+
query: createQueries(scaledPoint, false),
|
|
225
|
+
sort:
|
|
226
|
+
direction === "below"
|
|
227
|
+
? new Sort({ key: ["end2"], direction: "desc" })
|
|
228
|
+
: new Sort({ key: ["start1"], direction: "asc" }),
|
|
229
|
+
}),
|
|
230
|
+
);
|
|
231
|
+
const iteratorWrapped = iterate(
|
|
232
|
+
rects,
|
|
233
|
+
new SearchRequest({
|
|
234
|
+
query: createQueries(
|
|
235
|
+
direction === "below" ? SEGMENT_COORDINATE_SCALE : 0,
|
|
236
|
+
true,
|
|
237
|
+
),
|
|
238
|
+
sort:
|
|
239
|
+
direction === "below"
|
|
240
|
+
? new Sort({ key: ["end2"], direction: "desc" })
|
|
241
|
+
: new Sort({ key: ["start1"], direction: "asc" }),
|
|
242
|
+
}),
|
|
243
|
+
);
|
|
244
|
+
|
|
245
|
+
return joinIterator(
|
|
246
|
+
[iterator, iteratorWrapped],
|
|
247
|
+
scaledPoint,
|
|
248
|
+
true,
|
|
249
|
+
direction,
|
|
250
|
+
);
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
export const getDistance = (
|
|
254
|
+
from: number,
|
|
255
|
+
to: number,
|
|
256
|
+
direction: "above" | "below" | "closest",
|
|
257
|
+
end = SEGMENT_COORDINATE_SCALE,
|
|
258
|
+
) => {
|
|
259
|
+
// if direction is 'above' only measure distance from 'from to 'to' from above.
|
|
260
|
+
// i.e if from < to, then from needs to wrap around 0 to 1 and then to to
|
|
261
|
+
// if direction is 'below' and from > to, then from needs to wrap around 1 to 0 and then to to
|
|
262
|
+
// if direction is 'closest' then the shortest distance is the distance
|
|
263
|
+
|
|
264
|
+
// also from is 0.1 and to is 0.9, then distance should be 0.2 not 0.8
|
|
265
|
+
// same as for if from is 0.9 and to is 0.1, then distance should be 0.2 not 0.8
|
|
266
|
+
|
|
267
|
+
if (direction === "closest") {
|
|
268
|
+
if (from === to) {
|
|
269
|
+
return 0;
|
|
68
270
|
}
|
|
69
271
|
|
|
70
|
-
|
|
272
|
+
return Math.min(Math.abs(from - to), Math.abs(end - Math.abs(from - to)));
|
|
273
|
+
}
|
|
71
274
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
) {
|
|
76
|
-
break; // TODO throw error for failing to fetch ffull width
|
|
275
|
+
if (direction === "above") {
|
|
276
|
+
if (from <= to) {
|
|
277
|
+
return Math.abs(end - to) + from;
|
|
77
278
|
}
|
|
279
|
+
return from - to;
|
|
78
280
|
}
|
|
79
281
|
|
|
80
|
-
if (
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
282
|
+
if (direction === "below") {
|
|
283
|
+
if (from >= to) {
|
|
284
|
+
return Math.abs(end - from) + to;
|
|
285
|
+
}
|
|
286
|
+
return to - from;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
throw new Error("Invalid direction");
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
const joinIterator = (
|
|
293
|
+
iterators: IndexIterator<ReplicationRangeIndexable>[],
|
|
294
|
+
point: number,
|
|
295
|
+
scaled: boolean,
|
|
296
|
+
direction: "above" | "below" | "closest",
|
|
297
|
+
) => {
|
|
298
|
+
const scaledPoint = Math.round(
|
|
299
|
+
point * (scaled ? 1 : SEGMENT_COORDINATE_SCALE),
|
|
300
|
+
);
|
|
301
|
+
let queues: {
|
|
302
|
+
kept: number;
|
|
303
|
+
elements: {
|
|
304
|
+
result: IndexedResult<ReplicationRangeIndexable>;
|
|
305
|
+
dist: number;
|
|
306
|
+
}[];
|
|
307
|
+
}[] = [];
|
|
308
|
+
|
|
309
|
+
return {
|
|
310
|
+
next: async (
|
|
311
|
+
count: number,
|
|
312
|
+
): Promise<IndexedResults<ReplicationRangeIndexable>> => {
|
|
313
|
+
let results: IndexedResults<ReplicationRangeIndexable> = {
|
|
314
|
+
kept: 0, // TODO
|
|
315
|
+
results: [],
|
|
316
|
+
};
|
|
317
|
+
for (let i = 0; i < iterators.length; i++) {
|
|
318
|
+
let queue = queues[i];
|
|
319
|
+
if (!queue) {
|
|
320
|
+
queue = { elements: [], kept: 0 };
|
|
321
|
+
queues[i] = queue;
|
|
322
|
+
}
|
|
323
|
+
let iterator = iterators[i];
|
|
324
|
+
if (queue.elements.length < count && iterator.done() === false) {
|
|
325
|
+
let res = await iterator.next(count);
|
|
326
|
+
queue.kept = res.kept;
|
|
327
|
+
|
|
328
|
+
for (const el of res.results) {
|
|
329
|
+
const closest = el.value;
|
|
330
|
+
|
|
331
|
+
let dist: number;
|
|
332
|
+
if (direction === "closest") {
|
|
333
|
+
dist = Math.min(
|
|
334
|
+
getDistance(closest.start1, scaledPoint, direction),
|
|
335
|
+
getDistance(closest.end2, scaledPoint, direction),
|
|
336
|
+
);
|
|
337
|
+
} else if (direction === "above") {
|
|
338
|
+
dist = getDistance(closest.start1, scaledPoint, direction);
|
|
339
|
+
} else if (direction === "below") {
|
|
340
|
+
dist = getDistance(closest.end2, scaledPoint, direction);
|
|
341
|
+
} else {
|
|
342
|
+
throw new Error("Invalid direction");
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
queue.elements.push({ result: el, dist });
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// pull the 'count' the closest element from one of the queue
|
|
351
|
+
|
|
352
|
+
for (let i = 0; i < count; i++) {
|
|
353
|
+
let closestQueue = -1;
|
|
354
|
+
let closestDist = Number.MAX_SAFE_INTEGER;
|
|
355
|
+
for (let j = 0; j < queues.length; j++) {
|
|
356
|
+
let queue = queues[j];
|
|
357
|
+
if (queue && queue.elements.length > 0) {
|
|
358
|
+
let closest = queue.elements[0];
|
|
359
|
+
if (closest.dist < closestDist) {
|
|
360
|
+
closestDist = closest.dist;
|
|
361
|
+
closestQueue = j;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
if (closestQueue === -1) {
|
|
367
|
+
break;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
let closest = queues[closestQueue]?.elements.shift();
|
|
371
|
+
if (closest) {
|
|
372
|
+
results.results.push(closest.result);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
for (let i = 0; i < queues.length; i++) {
|
|
377
|
+
results.kept += queues[i].elements.length + queues[i].kept;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
return results;
|
|
381
|
+
},
|
|
382
|
+
done: () => iterators.every((x) => x.done()),
|
|
383
|
+
close: async () => {
|
|
384
|
+
for (const iterator of iterators) {
|
|
385
|
+
await iterator.close();
|
|
386
|
+
}
|
|
387
|
+
},
|
|
388
|
+
all: async () => {
|
|
389
|
+
let results: IndexedResult<ReplicationRangeIndexable>[] = [];
|
|
390
|
+
for (const iterator of iterators) {
|
|
391
|
+
let res = await iterator.all();
|
|
392
|
+
results.push(...res);
|
|
393
|
+
}
|
|
394
|
+
return results;
|
|
395
|
+
},
|
|
396
|
+
};
|
|
397
|
+
};
|
|
398
|
+
|
|
399
|
+
const getClosestAround = (
|
|
400
|
+
peers: Index<ReplicationRangeIndexable>,
|
|
401
|
+
point: number,
|
|
402
|
+
roleAge: number,
|
|
403
|
+
now: number,
|
|
404
|
+
scaled: boolean,
|
|
405
|
+
) => {
|
|
406
|
+
const closestBelow = getClosest(
|
|
407
|
+
"below",
|
|
408
|
+
peers,
|
|
409
|
+
point,
|
|
410
|
+
roleAge,
|
|
411
|
+
true,
|
|
412
|
+
now,
|
|
413
|
+
scaled,
|
|
414
|
+
);
|
|
415
|
+
const closestAbove = getClosest(
|
|
416
|
+
"above",
|
|
417
|
+
peers,
|
|
418
|
+
point,
|
|
419
|
+
roleAge,
|
|
420
|
+
true,
|
|
421
|
+
now,
|
|
422
|
+
scaled,
|
|
423
|
+
);
|
|
424
|
+
const containing = containingPoint(peers, point, roleAge, true, now, {
|
|
425
|
+
scaled: scaled,
|
|
426
|
+
});
|
|
427
|
+
|
|
428
|
+
return iteratorInSeries(
|
|
429
|
+
containing,
|
|
430
|
+
joinIterator([closestBelow, closestAbove], point, scaled, "closest"),
|
|
431
|
+
);
|
|
432
|
+
};
|
|
433
|
+
|
|
434
|
+
const collectNodesAroundPoint = async (
|
|
435
|
+
roleAge: number,
|
|
436
|
+
peers: Index<ReplicationRangeIndexable>,
|
|
437
|
+
collector: (rect: ReplicationRangeIndexable, matured: boolean) => void,
|
|
438
|
+
point: number,
|
|
439
|
+
now: number,
|
|
440
|
+
done: () => boolean = () => true,
|
|
441
|
+
) => {
|
|
442
|
+
const containing = containingPoint(peers, point, 0, true, now, {
|
|
443
|
+
scaled: false,
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
const allContaining = await containing.next(0xffffffff);
|
|
447
|
+
for (const rect of allContaining.results) {
|
|
448
|
+
collector(rect.value, isMatured(rect.value, now, roleAge));
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
if (done()) {
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
const closestBelow = getClosest("below", peers, point, 0, true, now, false);
|
|
456
|
+
const closestAbove = getClosest("above", peers, point, 0, true, now, false);
|
|
457
|
+
const aroundIterator = joinIterator(
|
|
458
|
+
[closestBelow, closestAbove],
|
|
459
|
+
point,
|
|
460
|
+
false,
|
|
461
|
+
"closest",
|
|
462
|
+
);
|
|
463
|
+
while (aroundIterator.done() === false && done() === false) {
|
|
464
|
+
const res = await aroundIterator.next(1);
|
|
465
|
+
for (const rect of res.results) {
|
|
466
|
+
collector(rect.value, isMatured(rect.value, now, roleAge));
|
|
467
|
+
if (done()) {
|
|
468
|
+
return;
|
|
86
469
|
}
|
|
87
470
|
}
|
|
88
471
|
}
|
|
89
472
|
};
|
|
90
473
|
|
|
91
|
-
export const isMatured = (
|
|
92
|
-
|
|
474
|
+
export const isMatured = (
|
|
475
|
+
segment: { timestamp: bigint },
|
|
476
|
+
now: number,
|
|
477
|
+
minAge: number,
|
|
478
|
+
) => {
|
|
479
|
+
return now - Number(segment.timestamp) >= minAge;
|
|
93
480
|
};
|
|
94
481
|
|
|
95
|
-
export const getSamples = (
|
|
482
|
+
export const getSamples = async (
|
|
96
483
|
cursor: number,
|
|
97
|
-
peers:
|
|
484
|
+
peers: Index<ReplicationRangeIndexable>,
|
|
98
485
|
amount: number,
|
|
99
486
|
roleAge: number,
|
|
100
|
-
dbg?: string
|
|
101
487
|
) => {
|
|
102
488
|
const leaders: Set<string> = new Set();
|
|
103
489
|
const width = 1;
|
|
104
|
-
if (!peers
|
|
490
|
+
if (!peers) {
|
|
105
491
|
return [];
|
|
106
492
|
}
|
|
107
|
-
amount = Math.min(amount, peers.length);
|
|
108
493
|
|
|
109
|
-
const
|
|
494
|
+
const size = await peers.getSize();
|
|
495
|
+
|
|
496
|
+
amount = Math.min(amount, size);
|
|
497
|
+
|
|
498
|
+
if (amount === 0) {
|
|
499
|
+
return [];
|
|
500
|
+
}
|
|
110
501
|
|
|
111
|
-
const
|
|
502
|
+
const now = +new Date();
|
|
112
503
|
|
|
113
504
|
const maturedLeaders = new Set();
|
|
114
505
|
for (let i = 0; i < amount; i++) {
|
|
115
506
|
// evenly distributed
|
|
116
507
|
const point = ((cursor + i / amount) % 1) * width;
|
|
117
|
-
const currentNode = peers.head;
|
|
118
508
|
|
|
119
509
|
// aquire at least one unique node for each point
|
|
120
|
-
|
|
121
|
-
collectNodesAroundPoint(
|
|
122
|
-
t,
|
|
510
|
+
await collectNodesAroundPoint(
|
|
123
511
|
roleAge,
|
|
124
512
|
peers,
|
|
125
|
-
currentNode,
|
|
126
513
|
(rect, m) => {
|
|
514
|
+
// console.log(m, rect.start1 / SEGMENT_COORDINATE_SCALE, rect.width / SEGMENT_COORDINATE_SCALE)
|
|
127
515
|
if (m) {
|
|
128
|
-
maturedLeaders.add(rect.
|
|
516
|
+
maturedLeaders.add(rect.hash);
|
|
129
517
|
}
|
|
130
|
-
leaders.add(rect.
|
|
518
|
+
leaders.add(rect.hash);
|
|
131
519
|
},
|
|
132
520
|
point,
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
}
|
|
521
|
+
now,
|
|
522
|
+
() => {
|
|
523
|
+
if (maturedLeaders.size > i) {
|
|
524
|
+
return true;
|
|
138
525
|
}
|
|
139
|
-
return false;
|
|
140
|
-
}
|
|
526
|
+
return false;
|
|
527
|
+
},
|
|
141
528
|
);
|
|
142
529
|
}
|
|
143
530
|
|
|
144
531
|
return [...leaders];
|
|
145
532
|
};
|
|
146
533
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
startNodeIdentity?: PublicSignKey
|
|
152
|
-
): string[] => {
|
|
153
|
-
return [...getCoverSet(coveringWidth, peers, roleAge, startNodeIdentity)];
|
|
534
|
+
const fetchOne = async (iterator: IndexIterator<ReplicationRangeIndexable>) => {
|
|
535
|
+
const value = await iterator.next(1);
|
|
536
|
+
await iterator.close();
|
|
537
|
+
return value.results[0]?.value;
|
|
154
538
|
};
|
|
155
|
-
|
|
539
|
+
|
|
540
|
+
export const getCoverSet = async (
|
|
156
541
|
coveringWidth: number,
|
|
157
|
-
peers:
|
|
542
|
+
peers: Index<ReplicationRangeIndexable>,
|
|
158
543
|
roleAge: number,
|
|
159
|
-
startNodeIdentity?: PublicSignKey
|
|
160
|
-
): Set<string
|
|
544
|
+
startNodeIdentity?: PublicSignKey,
|
|
545
|
+
): Promise<Set<string>> => {
|
|
546
|
+
let now = +new Date();
|
|
547
|
+
|
|
161
548
|
// find a good starting point
|
|
162
|
-
let
|
|
549
|
+
let startNode: ReplicationRangeIndexable | undefined = undefined;
|
|
163
550
|
if (startNodeIdentity) {
|
|
164
551
|
// start at our node (local first)
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
552
|
+
let result = await peers.query(
|
|
553
|
+
new SearchRequest({
|
|
554
|
+
query: [
|
|
555
|
+
new StringMatch({ key: "hash", value: startNodeIdentity.hashcode() }),
|
|
556
|
+
],
|
|
557
|
+
fetch: 1,
|
|
558
|
+
}),
|
|
559
|
+
);
|
|
560
|
+
startNode = result.results[0]?.value;
|
|
561
|
+
|
|
562
|
+
if (startNode) {
|
|
563
|
+
if (!isMatured(startNode, now, roleAge)) {
|
|
564
|
+
const matured = await fetchOne(
|
|
565
|
+
getClosestAround(peers, startNode.start1, roleAge, now, true),
|
|
566
|
+
);
|
|
567
|
+
if (matured) {
|
|
568
|
+
startNode = matured;
|
|
569
|
+
}
|
|
168
570
|
}
|
|
169
|
-
walker = walker.next;
|
|
170
|
-
}
|
|
171
|
-
if (!walker) {
|
|
172
|
-
walker = peers.head;
|
|
173
571
|
}
|
|
572
|
+
}
|
|
573
|
+
let startLocation: number;
|
|
574
|
+
|
|
575
|
+
if (!startNode) {
|
|
576
|
+
startLocation = Math.random() * SEGMENT_COORDINATE_SCALE;
|
|
577
|
+
startNode = await fetchOne(
|
|
578
|
+
getClosestAround(peers, startLocation, roleAge, now, true),
|
|
579
|
+
);
|
|
174
580
|
} else {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
break;
|
|
179
|
-
}
|
|
180
|
-
walker = walker.next;
|
|
181
|
-
}
|
|
581
|
+
// TODO choose start location as the point with the longest range?
|
|
582
|
+
startLocation =
|
|
583
|
+
startNode.start1 ?? Math.random() * SEGMENT_COORDINATE_SCALE;
|
|
182
584
|
}
|
|
183
585
|
|
|
184
|
-
const startNode = walker;
|
|
586
|
+
/* const startNode = walker; */
|
|
185
587
|
if (!startNode) {
|
|
186
588
|
return new Set();
|
|
187
589
|
}
|
|
188
590
|
|
|
591
|
+
let results: ReplicationRangeIndexable[] = [];
|
|
592
|
+
|
|
593
|
+
let widthToCoverScaled = coveringWidth * SEGMENT_COORDINATE_SCALE;
|
|
594
|
+
const endLocation =
|
|
595
|
+
(startLocation + widthToCoverScaled) % SEGMENT_COORDINATE_SCALE;
|
|
596
|
+
const endIsWrapped = endLocation <= startLocation;
|
|
597
|
+
|
|
598
|
+
const endRect =
|
|
599
|
+
(await fetchOne(
|
|
600
|
+
getClosestAround(peers, endLocation, roleAge, now, true),
|
|
601
|
+
)) || (await fetchOne(getClosestAround(peers, endLocation, 0, now, true))); // (await getClosest('above', peers, nextLocation, roleAge, true, 1, true))[0]
|
|
602
|
+
|
|
603
|
+
if (!endRect) {
|
|
604
|
+
return new Set();
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
let current =
|
|
608
|
+
/* (await getClosestAround(peers, startLocation, roleAge, 1, true))[0] */ startNode ||
|
|
609
|
+
(await fetchOne(getClosestAround(peers, startLocation, 0, now, true))); //(await getClosest('above', peers, startLocation, roleAge, true, 1, true))[0]
|
|
610
|
+
let coveredLength = current.width;
|
|
611
|
+
let nextLocation = current.end2;
|
|
612
|
+
|
|
613
|
+
// push edges
|
|
614
|
+
results.push(endRect);
|
|
615
|
+
results.push(current);
|
|
616
|
+
/* const endIsSameAsStart = equals(endRect.id, current.id); */
|
|
617
|
+
|
|
618
|
+
const resolveNextContaining = async (
|
|
619
|
+
nextLocation: number,
|
|
620
|
+
roleAge: number,
|
|
621
|
+
) => {
|
|
622
|
+
let next = await fetchOne(
|
|
623
|
+
containingPoint(peers, nextLocation, roleAge, true, now, {
|
|
624
|
+
scaled: true,
|
|
625
|
+
sort: [new Sort({ key: "end2", direction: SortDirection.DESC })],
|
|
626
|
+
}),
|
|
627
|
+
); // get entersecting sort by largest end2
|
|
628
|
+
return next;
|
|
629
|
+
};
|
|
630
|
+
|
|
631
|
+
const resolveNextAbove = async (nextLocation: number, roleAge: number) => {
|
|
632
|
+
// if not get closest from above
|
|
633
|
+
let next = await fetchOne(
|
|
634
|
+
getClosest("above", peers, nextLocation, roleAge, true, now, true),
|
|
635
|
+
);
|
|
636
|
+
return next;
|
|
637
|
+
};
|
|
638
|
+
|
|
639
|
+
const resolveNext = async (
|
|
640
|
+
nextLocation: number,
|
|
641
|
+
roleAge: number,
|
|
642
|
+
): Promise<[ReplicationRangeIndexable, boolean]> => {
|
|
643
|
+
const containing = await resolveNextContaining(nextLocation, roleAge);
|
|
644
|
+
if (containing) {
|
|
645
|
+
return [containing, true];
|
|
646
|
+
}
|
|
647
|
+
return [await resolveNextAbove(nextLocation, roleAge), false];
|
|
648
|
+
};
|
|
649
|
+
|
|
650
|
+
// fill the middle
|
|
651
|
+
let wrappedOnce = current.end2 < current.end1;
|
|
652
|
+
|
|
653
|
+
let maturedCoveredLength = coveredLength;
|
|
654
|
+
/* let lastMatured = isMatured(startNode, now, roleAge) ? startNode : undefined;
|
|
655
|
+
*/
|
|
656
|
+
|
|
657
|
+
while (
|
|
658
|
+
maturedCoveredLength < widthToCoverScaled &&
|
|
659
|
+
coveredLength <= SEGMENT_COORDINATE_SCALE
|
|
660
|
+
) {
|
|
661
|
+
let nextCandidate = await resolveNext(nextLocation, roleAge);
|
|
662
|
+
/* let fromAbove = false; */
|
|
663
|
+
let matured = true;
|
|
664
|
+
|
|
665
|
+
if (!nextCandidate[0]) {
|
|
666
|
+
matured = false;
|
|
667
|
+
nextCandidate = await resolveNext(nextLocation, 0);
|
|
668
|
+
/* fromAbove = true; */
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
if (!nextCandidate[0]) {
|
|
672
|
+
break;
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
current = nextCandidate[0];
|
|
676
|
+
|
|
677
|
+
let distanceBefore = coveredLength;
|
|
678
|
+
|
|
679
|
+
if (current.end2 < nextLocation) {
|
|
680
|
+
wrappedOnce = true;
|
|
681
|
+
coveredLength += SEGMENT_COORDINATE_SCALE - nextLocation;
|
|
682
|
+
coveredLength += current.end2;
|
|
683
|
+
} else {
|
|
684
|
+
coveredLength += current.end1 - nextLocation;
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
let isLast =
|
|
688
|
+
distanceBefore < widthToCoverScaled &&
|
|
689
|
+
coveredLength >= widthToCoverScaled;
|
|
690
|
+
if (
|
|
691
|
+
(isLast &&
|
|
692
|
+
!nextCandidate[1]) /* || Math.min(current.start1, current.start2) > Math.min(endRect.start1, endRect.start2) */ /* (Math.min(current.start1, current.start2) > endLocation) */ ||
|
|
693
|
+
equals(endRect.id, current.id)
|
|
694
|
+
) {
|
|
695
|
+
/* if ((isLast && ((endIsWrapped && wrappedOnce) || (!endIsWrapped))) && (current.start1 > endLocation || equals(current.id, endRect.id))) { */
|
|
696
|
+
// this is the end!
|
|
697
|
+
/* if (lastMatured && lastMatured.distanceTo(endLocation) < current.distanceTo(endLocation)) {
|
|
698
|
+
breaks;
|
|
699
|
+
} */
|
|
700
|
+
break;
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
/* if (fromAbove && next && next.start1 > endRect.start1 && (endIsWrapped === false || wrappedOnce)) {
|
|
704
|
+
break;
|
|
705
|
+
} */
|
|
706
|
+
|
|
707
|
+
// this is a skip condition to not include too many rects
|
|
708
|
+
|
|
709
|
+
if (matured) {
|
|
710
|
+
maturedCoveredLength = coveredLength;
|
|
711
|
+
/* lastMatured = current; */
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
results.push(current);
|
|
715
|
+
/*
|
|
716
|
+
|
|
717
|
+
if (current.start1 > endLocation && (wrappedOnce || !endIsWrapped)) {
|
|
718
|
+
break;
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
*/
|
|
722
|
+
nextLocation = endIsWrapped
|
|
723
|
+
? wrappedOnce
|
|
724
|
+
? Math.min(current.end2, endLocation)
|
|
725
|
+
: current.end2
|
|
726
|
+
: Math.min(current.end2, endLocation);
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
const res = new Set(results.map((x) => x.hash));
|
|
730
|
+
startNodeIdentity && res.add(startNodeIdentity.hashcode());
|
|
731
|
+
return res;
|
|
732
|
+
|
|
189
733
|
//
|
|
190
|
-
const set: Set<string> = new Set();
|
|
734
|
+
/* const set: Set<string> = new Set();
|
|
191
735
|
let currentNode = startNode;
|
|
192
736
|
const t = +new Date();
|
|
193
|
-
|
|
737
|
+
|
|
194
738
|
let wrappedOnce = false;
|
|
195
|
-
const startPoint = startNode.
|
|
196
|
-
|
|
739
|
+
const startPoint = startNode.segment.offset;
|
|
740
|
+
|
|
197
741
|
const getNextPoint = (): [number, number, number, boolean] => {
|
|
198
742
|
let nextPoint =
|
|
199
|
-
currentNode.
|
|
200
|
-
|
|
743
|
+
currentNode.segment.offset + currentNode.segment.factor;
|
|
744
|
+
|
|
201
745
|
if (nextPoint > 1 || nextPoint < startPoint) {
|
|
202
746
|
wrappedOnce = true;
|
|
203
747
|
}
|
|
204
|
-
|
|
748
|
+
|
|
205
749
|
nextPoint = nextPoint % 1;
|
|
206
750
|
let distanceStart: number;
|
|
207
|
-
|
|
751
|
+
|
|
208
752
|
if (wrappedOnce) {
|
|
209
|
-
distanceStart = (1 - startPoint + currentNode.
|
|
753
|
+
distanceStart = (1 - startPoint + currentNode.segment.offset) % 1;
|
|
210
754
|
} else {
|
|
211
|
-
distanceStart = (currentNode.
|
|
755
|
+
distanceStart = (currentNode.segment.offset - startPoint) % 1;
|
|
212
756
|
}
|
|
213
|
-
|
|
214
|
-
const distanceEnd = distanceStart + currentNode.
|
|
215
|
-
|
|
757
|
+
|
|
758
|
+
const distanceEnd = distanceStart + currentNode.segment.factor;
|
|
759
|
+
|
|
216
760
|
return [nextPoint, distanceStart, distanceEnd, wrappedOnce];
|
|
217
761
|
};
|
|
218
|
-
|
|
219
|
-
const getNextMatured = (from:
|
|
220
|
-
let next = (from.next || peers.head)!;
|
|
762
|
+
|
|
763
|
+
const getNextMatured = async (from: ReplicatorRect) => {
|
|
764
|
+
let next = (await peers.query(new SearchRequest({ query: [new IntegerCompare({ key: ['segment', 'offset'], compare: Compare.Greater, value: from.segment.offset })], fetch: 1 })))?.results[0]?.value // (from.next || peers.head)!;
|
|
221
765
|
while (
|
|
222
|
-
|
|
223
|
-
|
|
766
|
+
next.hash !== from.hash &&
|
|
767
|
+
next.hash !== startNode.hash
|
|
224
768
|
) {
|
|
225
|
-
if (isMatured(next.
|
|
769
|
+
if (isMatured(next.segment, t, roleAge)) {
|
|
226
770
|
return next;
|
|
227
771
|
}
|
|
228
772
|
next = (next.next || peers.head)!;
|
|
229
773
|
}
|
|
230
774
|
return undefined;
|
|
231
|
-
};
|
|
775
|
+
}; */
|
|
232
776
|
|
|
233
777
|
/**
|
|
234
778
|
* The purpose of this loop is to cover at least coveringWidth
|
|
@@ -236,30 +780,30 @@ export const getCoverSet = (
|
|
|
236
780
|
* "query" all data in that range
|
|
237
781
|
*/
|
|
238
782
|
|
|
239
|
-
let isPastThePoint = false;
|
|
783
|
+
/* let isPastThePoint = false;
|
|
240
784
|
outer: while (currentNode) {
|
|
241
|
-
if (set.has(currentNode.
|
|
242
|
-
|
|
785
|
+
if (set.has(currentNode.hash)) break;
|
|
786
|
+
|
|
243
787
|
const [nextPoint, distanceStart, distanceEnd, wrapped] = getNextPoint();
|
|
244
|
-
|
|
788
|
+
|
|
245
789
|
if (distanceStart <= coveringWidth) {
|
|
246
|
-
set.add(currentNode.
|
|
790
|
+
set.add(currentNode.hash);
|
|
247
791
|
}
|
|
248
|
-
|
|
792
|
+
|
|
249
793
|
if (distanceEnd >= coveringWidth) {
|
|
250
794
|
break;
|
|
251
795
|
}
|
|
252
|
-
|
|
796
|
+
|
|
253
797
|
let next = currentNode.next || peers.head;
|
|
254
798
|
while (next) {
|
|
255
799
|
if (next.value.publicKey.equals(startNode.value.publicKey)) {
|
|
256
800
|
break outer;
|
|
257
801
|
}
|
|
258
|
-
|
|
802
|
+
|
|
259
803
|
const prevOffset = (next.prev || peers.tail)!.value.role.offset;
|
|
260
804
|
const nextOffset = next.value.role.offset;
|
|
261
805
|
const nextHasWrapped = nextOffset < prevOffset;
|
|
262
|
-
|
|
806
|
+
|
|
263
807
|
if (
|
|
264
808
|
(!wrapped && nextOffset > nextPoint) ||
|
|
265
809
|
(nextHasWrapped &&
|
|
@@ -268,21 +812,21 @@ export const getCoverSet = (
|
|
|
268
812
|
) {
|
|
269
813
|
isPastThePoint = true;
|
|
270
814
|
}
|
|
271
|
-
|
|
815
|
+
|
|
272
816
|
if (isPastThePoint) {
|
|
273
817
|
break; // include this next in the set;
|
|
274
818
|
}
|
|
275
|
-
|
|
819
|
+
|
|
276
820
|
const overlapsRange = containsPoint(next.value.role, nextPoint);
|
|
277
|
-
|
|
821
|
+
|
|
278
822
|
if (overlapsRange) {
|
|
279
823
|
// Find out if there is a better choice ahead of us
|
|
280
|
-
const nextNext = getNextMatured(next);
|
|
824
|
+
const nextNext = await getNextMatured(next);
|
|
281
825
|
if (
|
|
282
826
|
nextNext &&
|
|
283
|
-
|
|
284
|
-
nextNext.
|
|
285
|
-
nextNext.
|
|
827
|
+
nextNext.hash === currentNode.hash &&
|
|
828
|
+
nextNext.segment.offset < nextPoint &&
|
|
829
|
+
nextNext.segment.offset + nextNext.segment.factor > nextPoint
|
|
286
830
|
) {
|
|
287
831
|
// nextNext is better (continue to iterate)
|
|
288
832
|
} else {
|
|
@@ -292,17 +836,17 @@ export const getCoverSet = (
|
|
|
292
836
|
} else {
|
|
293
837
|
// (continue to iterate)
|
|
294
838
|
}
|
|
295
|
-
|
|
839
|
+
|
|
296
840
|
next = next.next || peers.head;
|
|
297
841
|
}
|
|
298
842
|
currentNode = next!;
|
|
299
|
-
}
|
|
843
|
+
} */
|
|
300
844
|
|
|
301
845
|
// collect 1 point around the boundary of the start and one at the end,
|
|
302
846
|
// preferrd matured and that we already have it
|
|
303
|
-
for (const point of [
|
|
304
|
-
startNode.
|
|
305
|
-
(startNode.
|
|
847
|
+
/* for (const point of [
|
|
848
|
+
startNode.segment.offset,
|
|
849
|
+
(startNode.segment.offset + coveringWidth) % 1
|
|
306
850
|
]) {
|
|
307
851
|
let done = false;
|
|
308
852
|
const unmatured: string[] = [];
|
|
@@ -310,17 +854,17 @@ export const getCoverSet = (
|
|
|
310
854
|
t,
|
|
311
855
|
roleAge,
|
|
312
856
|
peers,
|
|
313
|
-
isMatured(startNode.
|
|
857
|
+
isMatured(startNode.segment, t, roleAge) ? startNode : peers.head, // start at startNode is matured, else start at head (we only seek to find one matured node at the point)
|
|
314
858
|
(rect, matured) => {
|
|
315
859
|
if (matured) {
|
|
316
|
-
if (set.has(rect.
|
|
860
|
+
if (set.has(rect.hash)) {
|
|
317
861
|
// great!
|
|
318
862
|
} else {
|
|
319
|
-
set.add(rect.
|
|
863
|
+
set.add(rect.hash);
|
|
320
864
|
}
|
|
321
865
|
done = true;
|
|
322
866
|
} else {
|
|
323
|
-
unmatured.push(rect.
|
|
867
|
+
unmatured.push(rect.hash);
|
|
324
868
|
}
|
|
325
869
|
},
|
|
326
870
|
point,
|
|
@@ -331,5 +875,5 @@ export const getCoverSet = (
|
|
|
331
875
|
// TODO add more elements?
|
|
332
876
|
}
|
|
333
877
|
}
|
|
334
|
-
return set;
|
|
878
|
+
return set; */
|
|
335
879
|
};
|