@peerbit/shared-log 8.0.7 → 9.0.0-2bc15a6
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/replication.ts
CHANGED
|
@@ -1,26 +1,255 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
2
|
+
BinaryReader,
|
|
3
3
|
deserialize,
|
|
4
|
-
serialize,
|
|
5
4
|
field,
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
serialize,
|
|
6
|
+
variant,
|
|
7
|
+
vec,
|
|
8
8
|
} from "@dao-xyz/borsh";
|
|
9
|
+
import { PublicSignKey, equals, randomBytes } from "@peerbit/crypto";
|
|
10
|
+
import { type Index, id } from "@peerbit/indexer-interface";
|
|
9
11
|
import { TransportMessage } from "./message.js";
|
|
10
|
-
import {
|
|
11
|
-
import { PublicSignKey } from "@peerbit/crypto";
|
|
12
|
-
import yallist from "yallist";
|
|
12
|
+
import { SEGMENT_COORDINATE_SCALE } from "./role.js";
|
|
13
13
|
|
|
14
14
|
export type ReplicationLimits = { min: MinReplicas; max?: MinReplicas };
|
|
15
|
+
/*
|
|
16
|
+
export class ReplicatorRect {
|
|
17
|
+
|
|
18
|
+
@id({ type: Uint8Array })
|
|
19
|
+
id: Uint8Array;
|
|
20
|
+
|
|
21
|
+
@field({ type: 'string' })
|
|
22
|
+
hash: string;
|
|
23
|
+
|
|
24
|
+
@field({ type: vec(ReplicationSegment) })
|
|
25
|
+
segments: ReplicationSegment[];
|
|
26
|
+
|
|
27
|
+
constructor(properties: { hash: string; segments: ReplicationSegment[] }) {
|
|
28
|
+
this.id = randomBytes(32);
|
|
29
|
+
this.hash = properties.hash;
|
|
30
|
+
this.segments = properties.segments;
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
*/
|
|
15
34
|
|
|
16
|
-
export
|
|
17
|
-
|
|
18
|
-
|
|
35
|
+
export enum ReplicationIntent {
|
|
36
|
+
Explicit = 0,
|
|
37
|
+
Automatic = 1,
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export const getSegmentsFromOffsetAndRange = (
|
|
41
|
+
offset: number,
|
|
42
|
+
factor: number,
|
|
43
|
+
): [[number, number], [number, number]] => {
|
|
44
|
+
let start1 = offset;
|
|
45
|
+
let end1Unscaled = offset + factor; // only add factor if it is not 1 to prevent numerical issues (like (0.9 + 1) % 1 => 0.8999999)
|
|
46
|
+
let end1 = Math.min(end1Unscaled, 1);
|
|
47
|
+
return [
|
|
48
|
+
[start1, end1],
|
|
49
|
+
end1Unscaled > 1
|
|
50
|
+
? [0, (factor !== 1 ? offset + factor : offset) % 1]
|
|
51
|
+
: [start1, end1],
|
|
52
|
+
];
|
|
19
53
|
};
|
|
20
54
|
|
|
55
|
+
export class ReplicationRange {
|
|
56
|
+
@field({ type: Uint8Array })
|
|
57
|
+
private id: Uint8Array;
|
|
58
|
+
|
|
59
|
+
@field({ type: "u64" })
|
|
60
|
+
timestamp: bigint;
|
|
61
|
+
|
|
62
|
+
@field({ type: "u32" })
|
|
63
|
+
private _offset: number;
|
|
64
|
+
|
|
65
|
+
@field({ type: "u32" })
|
|
66
|
+
private _factor: number;
|
|
67
|
+
|
|
68
|
+
constructor(properties: {
|
|
69
|
+
id: Uint8Array;
|
|
70
|
+
offset: number;
|
|
71
|
+
factor: number;
|
|
72
|
+
timestamp: bigint;
|
|
73
|
+
}) {
|
|
74
|
+
const { id, offset, factor, timestamp } = properties;
|
|
75
|
+
this.id = id;
|
|
76
|
+
this._offset = Math.round(offset * SEGMENT_COORDINATE_SCALE);
|
|
77
|
+
this._factor = Math.round(factor * SEGMENT_COORDINATE_SCALE);
|
|
78
|
+
this.timestamp = timestamp;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
get factor(): number {
|
|
82
|
+
return this._factor / SEGMENT_COORDINATE_SCALE;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
get offset(): number {
|
|
86
|
+
return this._offset / SEGMENT_COORDINATE_SCALE;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
toReplicationRangeIndexable(key: PublicSignKey): ReplicationRangeIndexable {
|
|
90
|
+
return new ReplicationRangeIndexable({
|
|
91
|
+
id: this.id,
|
|
92
|
+
publicKeyHash: key.hashcode(),
|
|
93
|
+
offset: this.offset,
|
|
94
|
+
length: this.factor,
|
|
95
|
+
timestamp: this.timestamp,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export class ReplicationRangeIndexable {
|
|
101
|
+
@id({ type: Uint8Array })
|
|
102
|
+
id: Uint8Array;
|
|
103
|
+
|
|
104
|
+
@field({ type: "string" })
|
|
105
|
+
hash: string;
|
|
106
|
+
|
|
107
|
+
@field({ type: "u64" })
|
|
108
|
+
timestamp: bigint;
|
|
109
|
+
|
|
110
|
+
@field({ type: "u32" })
|
|
111
|
+
start1: number;
|
|
112
|
+
|
|
113
|
+
@field({ type: "u32" })
|
|
114
|
+
end1: number;
|
|
115
|
+
|
|
116
|
+
@field({ type: "u32" })
|
|
117
|
+
start2: number;
|
|
118
|
+
|
|
119
|
+
@field({ type: "u32" })
|
|
120
|
+
end2: number;
|
|
121
|
+
|
|
122
|
+
@field({ type: "u32" })
|
|
123
|
+
width: number;
|
|
124
|
+
|
|
125
|
+
@field({ type: "u8" })
|
|
126
|
+
replicationIntent: ReplicationIntent;
|
|
127
|
+
|
|
128
|
+
constructor(
|
|
129
|
+
properties: {
|
|
130
|
+
id?: Uint8Array;
|
|
131
|
+
|
|
132
|
+
offset: number;
|
|
133
|
+
length: number;
|
|
134
|
+
replicationIntent?: ReplicationIntent;
|
|
135
|
+
timestamp?: bigint;
|
|
136
|
+
} & ({ publicKeyHash: string } | { publicKey: PublicSignKey }),
|
|
137
|
+
) {
|
|
138
|
+
this.id = properties.id ?? randomBytes(32);
|
|
139
|
+
this.hash =
|
|
140
|
+
(properties as { publicKeyHash: string }).publicKeyHash ||
|
|
141
|
+
(properties as { publicKey: PublicSignKey }).publicKey.hashcode();
|
|
142
|
+
this.transform({ length: properties.length, offset: properties.offset });
|
|
143
|
+
this.replicationIntent =
|
|
144
|
+
properties.replicationIntent ?? ReplicationIntent.Explicit;
|
|
145
|
+
this.timestamp = properties.timestamp || BigInt(0);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
private transform(properties: { offset: number; length: number }) {
|
|
149
|
+
const ranges = getSegmentsFromOffsetAndRange(
|
|
150
|
+
properties.offset,
|
|
151
|
+
properties.length,
|
|
152
|
+
);
|
|
153
|
+
this.start1 = Math.round(ranges[0][0] * SEGMENT_COORDINATE_SCALE);
|
|
154
|
+
this.end1 = Math.round(ranges[0][1] * SEGMENT_COORDINATE_SCALE);
|
|
155
|
+
this.start2 = Math.round(ranges[1][0] * SEGMENT_COORDINATE_SCALE);
|
|
156
|
+
this.end2 = Math.round(ranges[1][1] * SEGMENT_COORDINATE_SCALE);
|
|
157
|
+
|
|
158
|
+
this.width =
|
|
159
|
+
this.end1 -
|
|
160
|
+
this.start1 +
|
|
161
|
+
(this.end2 < this.end1 ? this.end2 - this.start2 : 0);
|
|
162
|
+
|
|
163
|
+
if (
|
|
164
|
+
this.start1 > 0xffffffff ||
|
|
165
|
+
this.end1 > 0xffffffff ||
|
|
166
|
+
this.start2 > 0xffffffff ||
|
|
167
|
+
this.end2 > 0xffffffff ||
|
|
168
|
+
this.width > 0xffffffff
|
|
169
|
+
) {
|
|
170
|
+
throw new Error("Segment coordinate out of bounds");
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
contains(point: number) {
|
|
175
|
+
return (
|
|
176
|
+
(point >= this.start1 && point < this.end1) ||
|
|
177
|
+
(point >= this.start2 && point < this.end2)
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
overlaps(other: ReplicationRangeIndexable, checkOther = true): boolean {
|
|
182
|
+
if (
|
|
183
|
+
this.contains(other.start1) ||
|
|
184
|
+
this.contains(other.start2) ||
|
|
185
|
+
this.contains(other.end1) ||
|
|
186
|
+
this.contains(other.end2)
|
|
187
|
+
) {
|
|
188
|
+
return true;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if (checkOther) {
|
|
192
|
+
return other.overlaps(this, false);
|
|
193
|
+
}
|
|
194
|
+
return false;
|
|
195
|
+
}
|
|
196
|
+
toReplicationRange() {
|
|
197
|
+
return new ReplicationRange({
|
|
198
|
+
id: this.id,
|
|
199
|
+
offset: this.start1 / SEGMENT_COORDINATE_SCALE,
|
|
200
|
+
factor: this.width / SEGMENT_COORDINATE_SCALE,
|
|
201
|
+
timestamp: this.timestamp,
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
distanceTo(point: number) {
|
|
206
|
+
let wrappedPoint = SEGMENT_COORDINATE_SCALE - point;
|
|
207
|
+
return Math.min(
|
|
208
|
+
Math.abs(this.start1 - point),
|
|
209
|
+
Math.abs(this.end2 - point),
|
|
210
|
+
Math.abs(this.start1 - wrappedPoint),
|
|
211
|
+
Math.abs(this.end2 - wrappedPoint),
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
get wrapped() {
|
|
215
|
+
return this.end2 < this.end1;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
get widthNormalized() {
|
|
219
|
+
return this.width / SEGMENT_COORDINATE_SCALE;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
equals(other: ReplicationRangeIndexable) {
|
|
223
|
+
if (
|
|
224
|
+
equals(this.id, other.id) &&
|
|
225
|
+
this.hash === other.hash &&
|
|
226
|
+
this.timestamp === other.timestamp &&
|
|
227
|
+
this.replicationIntent === other.replicationIntent &&
|
|
228
|
+
this.start1 === other.start1 &&
|
|
229
|
+
this.end1 === other.end1 &&
|
|
230
|
+
this.start2 === other.start2 &&
|
|
231
|
+
this.end2 === other.end2 &&
|
|
232
|
+
this.width === other.width
|
|
233
|
+
) {
|
|
234
|
+
return true;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
toString() {
|
|
241
|
+
let roundToTwoDecimals = (num: number) => Math.round(num * 100) / 100;
|
|
242
|
+
|
|
243
|
+
if (Math.abs(this.start1 - this.start2) < 0.0001) {
|
|
244
|
+
return `([${roundToTwoDecimals(this.start1 / SEGMENT_COORDINATE_SCALE)}, ${roundToTwoDecimals(this.end1 / SEGMENT_COORDINATE_SCALE)}])`;
|
|
245
|
+
}
|
|
246
|
+
return `([${roundToTwoDecimals(this.start1 / SEGMENT_COORDINATE_SCALE)}, ${roundToTwoDecimals(this.end1 / SEGMENT_COORDINATE_SCALE)}] [${roundToTwoDecimals(this.start2 / SEGMENT_COORDINATE_SCALE)}, ${roundToTwoDecimals(this.end2 / SEGMENT_COORDINATE_SCALE)}])`;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
21
250
|
interface SharedLog {
|
|
22
251
|
replicas: Partial<ReplicationLimits>;
|
|
23
|
-
|
|
252
|
+
replicationIndex: Index<ReplicationRangeIndexable> | undefined;
|
|
24
253
|
}
|
|
25
254
|
|
|
26
255
|
export class MinReplicas {
|
|
@@ -38,26 +267,49 @@ export class AbsoluteReplicas extends MinReplicas {
|
|
|
38
267
|
super();
|
|
39
268
|
this._value = value;
|
|
40
269
|
}
|
|
270
|
+
|
|
41
271
|
getValue(_log: SharedLog): number {
|
|
42
272
|
return this._value;
|
|
43
273
|
}
|
|
44
274
|
}
|
|
45
275
|
|
|
46
276
|
@variant([1, 0])
|
|
47
|
-
export class
|
|
277
|
+
export class RequestReplicationInfoMessage extends TransportMessage {
|
|
48
278
|
constructor() {
|
|
49
279
|
super();
|
|
50
280
|
}
|
|
51
281
|
}
|
|
52
282
|
|
|
53
283
|
@variant([1, 1])
|
|
54
|
-
export class
|
|
55
|
-
@field({ type:
|
|
56
|
-
|
|
284
|
+
export class ResponseReplicationInfoMessage extends TransportMessage {
|
|
285
|
+
@field({ type: vec(ReplicationRange) })
|
|
286
|
+
segments: ReplicationRange[];
|
|
287
|
+
|
|
288
|
+
constructor(properties: { segments: ReplicationRange[] }) {
|
|
289
|
+
super();
|
|
290
|
+
this.segments = properties.segments;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
@variant([1, 2])
|
|
295
|
+
export class StartedReplicating extends TransportMessage {
|
|
296
|
+
@field({ type: vec(ReplicationRange) })
|
|
297
|
+
segments: ReplicationRange[];
|
|
298
|
+
|
|
299
|
+
constructor(properties: { segments: ReplicationRange[] }) {
|
|
300
|
+
super();
|
|
301
|
+
this.segments = properties.segments;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
@variant([1, 3])
|
|
306
|
+
export class StoppedReplicating extends TransportMessage {
|
|
307
|
+
@field({ type: vec(Uint8Array) })
|
|
308
|
+
segmentIds: Uint8Array[];
|
|
57
309
|
|
|
58
|
-
constructor(properties: {
|
|
310
|
+
constructor(properties: { segmentIds: Uint8Array[] }) {
|
|
59
311
|
super();
|
|
60
|
-
this.
|
|
312
|
+
this.segmentIds = properties.segmentIds;
|
|
61
313
|
}
|
|
62
314
|
}
|
|
63
315
|
|
|
@@ -98,7 +350,7 @@ export const maxReplicas = (
|
|
|
98
350
|
log: SharedLog,
|
|
99
351
|
entries:
|
|
100
352
|
| { meta: { data?: Uint8Array } }[]
|
|
101
|
-
| IterableIterator<{ meta: { data?: Uint8Array } }
|
|
353
|
+
| IterableIterator<{ meta: { data?: Uint8Array } }>,
|
|
102
354
|
) => {
|
|
103
355
|
let max = 0;
|
|
104
356
|
for (const entry of entries) {
|
|
@@ -112,7 +364,7 @@ export const maxReplicas = (
|
|
|
112
364
|
|
|
113
365
|
export const hashToUniformNumber = (hash: Uint8Array) => {
|
|
114
366
|
const seedNumber = new BinaryReader(
|
|
115
|
-
hash.subarray(hash.length - 4, hash.length)
|
|
367
|
+
hash.subarray(hash.length - 4, hash.length),
|
|
116
368
|
).u32();
|
|
117
369
|
return seedNumber / 0xffffffff; // bounded between 0 and 1
|
|
118
370
|
};
|
package/src/role.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { field, variant, vec } from "@dao-xyz/borsh";
|
|
1
|
+
/* import { field, variant, vec } from "@dao-xyz/borsh"; */
|
|
2
2
|
|
|
3
|
-
export const overlaps = (x1: number, x2: number, y1: number, y2: number) => {
|
|
3
|
+
/* export const overlaps = (x1: number, x2: number, y1: number, y2: number) => {
|
|
4
4
|
if (x1 <= y2 && y1 <= x2) {
|
|
5
5
|
return true;
|
|
6
6
|
}
|
|
7
7
|
return false;
|
|
8
|
-
};
|
|
8
|
+
}; */
|
|
9
9
|
|
|
10
|
-
export abstract class Role {
|
|
11
|
-
abstract equals(other: Role);
|
|
10
|
+
/* export abstract class Role {
|
|
11
|
+
abstract equals(other: Role): boolean;
|
|
12
12
|
}
|
|
13
|
-
|
|
13
|
+
|
|
14
14
|
export const NO_TYPE_VARIANT = new Uint8Array([0]);
|
|
15
15
|
|
|
16
16
|
@variant(0)
|
|
@@ -29,103 +29,83 @@ export class Observer extends Role {
|
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
export const REPLICATOR_TYPE_VARIANT = new Uint8Array([2])
|
|
32
|
+
export const REPLICATOR_TYPE_VARIANT = new Uint8Array([2]);*/
|
|
33
|
+
|
|
34
|
+
export const SEGMENT_COORDINATE_SCALE = 4294967295;
|
|
35
|
+
/* export class ReplicationSegment {
|
|
33
36
|
|
|
34
|
-
export class ReplicationSegment {
|
|
35
37
|
@field({ type: "u64" })
|
|
36
38
|
timestamp: bigint;
|
|
37
39
|
|
|
38
40
|
@field({ type: "u32" })
|
|
39
|
-
|
|
41
|
+
start: number;
|
|
42
|
+
|
|
43
|
+
@field({ type: 'u32' })
|
|
44
|
+
end: number;
|
|
45
|
+
|
|
40
46
|
|
|
41
|
-
@field({ type: "u32" })
|
|
42
|
-
private offsetNominator: number;
|
|
43
47
|
|
|
44
48
|
constructor(properties: {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
timestamp
|
|
49
|
+
start: number;
|
|
50
|
+
end: number;
|
|
51
|
+
timestamp: bigint;
|
|
48
52
|
}) {
|
|
49
|
-
const {
|
|
50
|
-
if (factor > 1 || factor < 0) {
|
|
51
|
-
throw new Error("Expecting factor to be between 0 and 1, got: " + factor);
|
|
52
|
-
}
|
|
53
|
+
const { start, end, timestamp } = properties;
|
|
53
54
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
if (offset > 1 || offset < 0) {
|
|
58
|
-
throw new Error("Expecting offset to be between 0 and 1, got: " + offset);
|
|
55
|
+
if (start > end) {
|
|
56
|
+
throw new Error("Range 'start' needs to be lower or equal to 'end'")
|
|
59
57
|
}
|
|
60
|
-
this.
|
|
58
|
+
this.start = Math.round(start * SEGMENT_COORDINATE_SCALE);
|
|
59
|
+
this.end = Math.round(end * SEGMENT_COORDINATE_SCALE);
|
|
60
|
+
this.timestamp = timestamp
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
get factor(): number {
|
|
64
|
-
return this.factorNominator / 4294967295;
|
|
65
|
-
}
|
|
66
63
|
|
|
67
|
-
get offset(): number {
|
|
68
|
-
return this.offsetNominator / 4294967295;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
overlaps(other: ReplicationSegment) {
|
|
72
|
-
let x1 = this.offset;
|
|
73
|
-
let x2 = this.offset + this.factor;
|
|
74
|
-
let y1 = other.offset;
|
|
75
|
-
let y2 = other.offset + other.factor;
|
|
76
|
-
if (overlaps(x1, x2, y1, y2)) {
|
|
77
|
-
return true;
|
|
78
|
-
}
|
|
79
64
|
|
|
80
|
-
if (x2 > 1 || y2 > 1) {
|
|
81
|
-
if (x2 > 1) {
|
|
82
|
-
x1 = 0;
|
|
83
|
-
x2 = x2 % 1;
|
|
84
|
-
}
|
|
85
|
-
if (y2 > 1) {
|
|
86
|
-
y1 = 0;
|
|
87
|
-
y2 = y2 % 1;
|
|
88
|
-
}
|
|
89
|
-
if (overlaps(x1, x2, y1, y2)) {
|
|
90
|
-
return true;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
return false;
|
|
94
|
-
}
|
|
95
65
|
}
|
|
66
|
+
*/
|
|
67
|
+
|
|
68
|
+
/* abstract class Capacity { }
|
|
96
69
|
|
|
97
70
|
@variant(2)
|
|
98
71
|
export class Replicator extends Role {
|
|
99
|
-
@field({ type: vec(ReplicationSegment) })
|
|
100
|
-
segments: ReplicationSegment[];
|
|
101
72
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
timestamp?: bigint;
|
|
105
|
-
offset: number;
|
|
106
|
-
}) {
|
|
107
|
-
super();
|
|
108
|
-
const segment: ReplicationSegment = new ReplicationSegment(properties);
|
|
109
|
-
this.segments = [segment];
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
get factor(): number {
|
|
113
|
-
return this.segments[0]!.factor;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
get offset(): number {
|
|
117
|
-
return this.segments[0]!.offset;
|
|
118
|
-
}
|
|
73
|
+
@field({ type: vec(Capacity) })
|
|
74
|
+
capacity: Capacity[];
|
|
119
75
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
76
|
+
constructor(properties?: { capacity: Capacity[] }) {
|
|
77
|
+
super();
|
|
78
|
+
this.capacity = properties?.capacity || [];
|
|
79
|
+
} */
|
|
80
|
+
|
|
81
|
+
/* constructor(properties: {
|
|
82
|
+
timestamp?: bigint;
|
|
83
|
+
factor: number;
|
|
84
|
+
offset: number;
|
|
85
|
+
}) {
|
|
86
|
+
super();
|
|
87
|
+
let timestamp = properties.timestamp || BigInt(+new Date);
|
|
88
|
+
let ranges = getSegmentsFromOffsetAndRange(properties.offset, properties.factor);
|
|
89
|
+
this.segments = ranges.map(x => new ReplicationSegment({ start: x[0], end: x[1], timestamp }));
|
|
90
|
+
}
|
|
91
|
+
*/
|
|
92
|
+
/* get factor(): number {
|
|
93
|
+
return this.segments[0]!.factor;
|
|
94
|
+
}
|
|
123
95
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
other instanceof Replicator &&
|
|
127
|
-
other.factor === this.factor &&
|
|
128
|
-
other.offset === this.offset
|
|
129
|
-
);
|
|
130
|
-
}
|
|
96
|
+
get offset(): number {
|
|
97
|
+
return this.segments[0]!.offset;
|
|
131
98
|
}
|
|
99
|
+
|
|
100
|
+
get timestamp(): bigint {
|
|
101
|
+
return this.segments[0]!.timestamp;
|
|
102
|
+
} */
|
|
103
|
+
|
|
104
|
+
/* equals(other: Role) {
|
|
105
|
+
return (
|
|
106
|
+
other instanceof Replicator &&
|
|
107
|
+
other.factor === this.factor &&
|
|
108
|
+
other.offset === this.offset
|
|
109
|
+
);
|
|
110
|
+
} */
|
|
111
|
+
/* } */
|