@g9tm/syncdata 1.2.1
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/LICENSE.md +21 -0
- package/PARITY.md +71 -0
- package/README.md +71 -0
- package/THIRD-PARTY-NOTICES.md +31 -0
- package/dist/abstractions/digest.d.ts +27 -0
- package/dist/abstractions/digest.js +78 -0
- package/dist/abstractions/digest.js.map +1 -0
- package/dist/abstractions/enums.d.ts +42 -0
- package/dist/abstractions/enums.js +60 -0
- package/dist/abstractions/enums.js.map +1 -0
- package/dist/abstractions/errors.d.ts +72 -0
- package/dist/abstractions/errors.js +90 -0
- package/dist/abstractions/errors.js.map +1 -0
- package/dist/abstractions/guid.d.ts +24 -0
- package/dist/abstractions/guid.js +93 -0
- package/dist/abstractions/guid.js.map +1 -0
- package/dist/abstractions/key.d.ts +16 -0
- package/dist/abstractions/key.js +47 -0
- package/dist/abstractions/key.js.map +1 -0
- package/dist/abstractions/long.d.ts +103 -0
- package/dist/abstractions/long.js +351 -0
- package/dist/abstractions/long.js.map +1 -0
- package/dist/abstractions/parameters.d.ts +49 -0
- package/dist/abstractions/parameters.js +153 -0
- package/dist/abstractions/parameters.js.map +1 -0
- package/dist/brotli-js/decode.d.ts +8 -0
- package/dist/brotli-js/decode.js +2004 -0
- package/dist/brotli-js/decode.js.map +1 -0
- package/dist/brotli-js/index.d.ts +5 -0
- package/dist/brotli-js/index.js +19 -0
- package/dist/brotli-js/index.js.map +1 -0
- package/dist/client/engine.d.ts +110 -0
- package/dist/client/engine.js +1158 -0
- package/dist/client/engine.js.map +1 -0
- package/dist/client/model.d.ts +61 -0
- package/dist/client/model.js +154 -0
- package/dist/client/model.js.map +1 -0
- package/dist/client/progress.d.ts +101 -0
- package/dist/client/progress.js +251 -0
- package/dist/client/progress.js.map +1 -0
- package/dist/client/runs.d.ts +219 -0
- package/dist/client/runs.js +239 -0
- package/dist/client/runs.js.map +1 -0
- package/dist/client/storeTypes.d.ts +428 -0
- package/dist/client/storeTypes.js +256 -0
- package/dist/client/storeTypes.js.map +1 -0
- package/dist/client/transport.d.ts +19 -0
- package/dist/client/transport.js +2 -0
- package/dist/client/transport.js.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +35 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/abort.d.ts +21 -0
- package/dist/internal/abort.js +125 -0
- package/dist/internal/abort.js.map +1 -0
- package/dist/internal/base64.d.ts +8 -0
- package/dist/internal/base64.js +85 -0
- package/dist/internal/base64.js.map +1 -0
- package/dist/internal/dotnetFormat.d.ts +32 -0
- package/dist/internal/dotnetFormat.js +207 -0
- package/dist/internal/dotnetFormat.js.map +1 -0
- package/dist/internal/md5.d.ts +2 -0
- package/dist/internal/md5.js +97 -0
- package/dist/internal/md5.js.map +1 -0
- package/dist/internal/sha256.d.ts +20 -0
- package/dist/internal/sha256.js +153 -0
- package/dist/internal/sha256.js.map +1 -0
- package/dist/internal/utf8.d.ts +8 -0
- package/dist/internal/utf8.js +143 -0
- package/dist/internal/utf8.js.map +1 -0
- package/dist/node/index.d.ts +9 -0
- package/dist/node/index.js +35 -0
- package/dist/node/index.js.map +1 -0
- package/dist/node/sqliteDriver.d.ts +11 -0
- package/dist/node/sqliteDriver.js +252 -0
- package/dist/node/sqliteDriver.js.map +1 -0
- package/dist/protocol/dtos.d.ts +280 -0
- package/dist/protocol/dtos.js +33 -0
- package/dist/protocol/dtos.js.map +1 -0
- package/dist/protocol/protocol.d.ts +36 -0
- package/dist/protocol/protocol.js +63 -0
- package/dist/protocol/protocol.js.map +1 -0
- package/dist/protocol/rowBatch/columnLayout.d.ts +4 -0
- package/dist/protocol/rowBatch/columnLayout.js +309 -0
- package/dist/protocol/rowBatch/columnLayout.js.map +1 -0
- package/dist/protocol/rowBatch/format.d.ts +74 -0
- package/dist/protocol/rowBatch/format.js +163 -0
- package/dist/protocol/rowBatch/format.js.map +1 -0
- package/dist/protocol/rowBatch/reader.d.ts +119 -0
- package/dist/protocol/rowBatch/reader.js +459 -0
- package/dist/protocol/rowBatch/reader.js.map +1 -0
- package/dist/protocol/rowBatch/writer.d.ts +101 -0
- package/dist/protocol/rowBatch/writer.js +412 -0
- package/dist/protocol/rowBatch/writer.js.map +1 -0
- package/dist/protocol/wire.d.ts +32 -0
- package/dist/protocol/wire.js +329 -0
- package/dist/protocol/wire.js.map +1 -0
- package/dist/signalr/index.d.ts +2 -0
- package/dist/signalr/index.js +5 -0
- package/dist/signalr/index.js.map +1 -0
- package/dist/signalr/protocols.d.ts +17 -0
- package/dist/signalr/protocols.js +109 -0
- package/dist/signalr/protocols.js.map +1 -0
- package/dist/signalr/transport.d.ts +67 -0
- package/dist/signalr/transport.js +286 -0
- package/dist/signalr/transport.js.map +1 -0
- package/dist/sqlite/apply.d.ts +91 -0
- package/dist/sqlite/apply.js +657 -0
- package/dist/sqlite/apply.js.map +1 -0
- package/dist/sqlite/commands.d.ts +24 -0
- package/dist/sqlite/commands.js +167 -0
- package/dist/sqlite/commands.js.map +1 -0
- package/dist/sqlite/connection.d.ts +81 -0
- package/dist/sqlite/connection.js +322 -0
- package/dist/sqlite/connection.js.map +1 -0
- package/dist/sqlite/driver.d.ts +63 -0
- package/dist/sqlite/driver.js +9 -0
- package/dist/sqlite/driver.js.map +1 -0
- package/dist/sqlite/index.d.ts +6 -0
- package/dist/sqlite/index.js +7 -0
- package/dist/sqlite/index.js.map +1 -0
- package/dist/sqlite/internals.d.ts +63 -0
- package/dist/sqlite/internals.js +194 -0
- package/dist/sqlite/internals.js.map +1 -0
- package/dist/sqlite/options.d.ts +78 -0
- package/dist/sqlite/options.js +78 -0
- package/dist/sqlite/options.js.map +1 -0
- package/dist/sqlite/push.d.ts +9 -0
- package/dist/sqlite/push.js +272 -0
- package/dist/sqlite/push.js.map +1 -0
- package/dist/sqlite/query.d.ts +38 -0
- package/dist/sqlite/query.js +476 -0
- package/dist/sqlite/query.js.map +1 -0
- package/dist/sqlite/revocation.d.ts +28 -0
- package/dist/sqlite/revocation.js +337 -0
- package/dist/sqlite/revocation.js.map +1 -0
- package/dist/sqlite/sql.d.ts +60 -0
- package/dist/sqlite/sql.js +324 -0
- package/dist/sqlite/sql.js.map +1 -0
- package/dist/sqlite/store.d.ts +116 -0
- package/dist/sqlite/store.js +664 -0
- package/dist/sqlite/store.js.map +1 -0
- package/dist/sqlite/values.d.ts +29 -0
- package/dist/sqlite/values.js +288 -0
- package/dist/sqlite/values.js.map +1 -0
- package/dist/testing/index.d.ts +61 -0
- package/dist/testing/index.js +175 -0
- package/dist/testing/index.js.map +1 -0
- package/package.json +104 -0
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
// Twin of G9SyncData.Protocol/RowBatch/G9RowBatchColumnLayout.cs: the column-grouped body of G9RowBatch version 2
|
|
2
|
+
// (ADR-0040), converted to and from the row-wise layout of version 1. Only the order of the bytes changes, so the
|
|
3
|
+
// conversion is exact both ways.
|
|
4
|
+
import { G9ESyncColumnType } from '../../abstractions/enums.js';
|
|
5
|
+
import { G9SyncKey } from '../../abstractions/key.js';
|
|
6
|
+
import { G9EPushRowOp, G9ERowBatchOp, G9RowBatchFormat, G9RowBatchFormatError, isRowBatchOp, readInt32LE, readVarint, varintLength, writeInt32LE, } from './format.js';
|
|
7
|
+
const KEY_STREAM = 0;
|
|
8
|
+
function readSectionHeader(body, cursor) {
|
|
9
|
+
const start = cursor.pos;
|
|
10
|
+
const op = available(body, cursor.pos, 1)[0];
|
|
11
|
+
cursor.pos++;
|
|
12
|
+
if (!isRowBatchOp(op))
|
|
13
|
+
throw new G9RowBatchFormatError(`Unknown op ${op}.`);
|
|
14
|
+
readVarint(body, cursor);
|
|
15
|
+
const keyType = available(body, cursor.pos, 1)[0];
|
|
16
|
+
cursor.pos++;
|
|
17
|
+
if (!G9SyncKey.isSupportedKeyType(keyType))
|
|
18
|
+
throw new G9RowBatchFormatError(`Unsupported key type ${keyType}.`);
|
|
19
|
+
const columnCount = readVarint(body, cursor);
|
|
20
|
+
if (columnCount > 1024)
|
|
21
|
+
throw new G9RowBatchFormatError('Too many columns.');
|
|
22
|
+
const types = available(body, cursor.pos, columnCount);
|
|
23
|
+
cursor.pos += columnCount;
|
|
24
|
+
const rowCount = readInt32LE(available(body, cursor.pos, 4), 0);
|
|
25
|
+
cursor.pos += 4;
|
|
26
|
+
if (rowCount < 0)
|
|
27
|
+
throw new G9RowBatchFormatError('Negative row count.');
|
|
28
|
+
return { start, length: cursor.pos - start, op, keyType, types, rowCount };
|
|
29
|
+
}
|
|
30
|
+
function streamCount(header) {
|
|
31
|
+
switch (header.op) {
|
|
32
|
+
case G9ERowBatchOp.Upsert:
|
|
33
|
+
case G9ERowBatchOp.Backfill:
|
|
34
|
+
return 3 + header.types.length;
|
|
35
|
+
case G9ERowBatchOp.Tombstone:
|
|
36
|
+
case G9ERowBatchOp.MoveOut:
|
|
37
|
+
return 2;
|
|
38
|
+
case G9ERowBatchOp.KeyVersions:
|
|
39
|
+
return 3;
|
|
40
|
+
case G9ERowBatchOp.Push:
|
|
41
|
+
return 7 + header.types.length;
|
|
42
|
+
default:
|
|
43
|
+
throw new G9RowBatchFormatError(`Unknown op ${header.op}.`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function available(body, position, length) {
|
|
47
|
+
if (length < 0 || position + length > body.length)
|
|
48
|
+
throw new G9RowBatchFormatError('Row batch is truncated.');
|
|
49
|
+
return body.subarray(position, position + length);
|
|
50
|
+
}
|
|
51
|
+
function keyLength(body, position, keyType) {
|
|
52
|
+
if (keyType === G9ESyncColumnType.Guid)
|
|
53
|
+
return 16;
|
|
54
|
+
if (keyType === G9ESyncColumnType.Int32 || keyType === G9ESyncColumnType.Int64)
|
|
55
|
+
return varintLength(body, position);
|
|
56
|
+
return prefixedLength(body, position);
|
|
57
|
+
}
|
|
58
|
+
function valueLength(body, position, type) {
|
|
59
|
+
switch (type) {
|
|
60
|
+
case G9ESyncColumnType.Boolean:
|
|
61
|
+
return 1;
|
|
62
|
+
case G9ESyncColumnType.Int32:
|
|
63
|
+
case G9ESyncColumnType.Int64:
|
|
64
|
+
case G9ESyncColumnType.TimeSpan:
|
|
65
|
+
return varintLength(body, position);
|
|
66
|
+
case G9ESyncColumnType.Double:
|
|
67
|
+
return 8;
|
|
68
|
+
case G9ESyncColumnType.Decimal:
|
|
69
|
+
case G9ESyncColumnType.Guid:
|
|
70
|
+
return 16;
|
|
71
|
+
case G9ESyncColumnType.DateTime:
|
|
72
|
+
return 9;
|
|
73
|
+
case G9ESyncColumnType.DateTimeOffset:
|
|
74
|
+
return 10;
|
|
75
|
+
case G9ESyncColumnType.String:
|
|
76
|
+
case G9ESyncColumnType.Bytes:
|
|
77
|
+
return prefixedLength(body, position);
|
|
78
|
+
default:
|
|
79
|
+
throw new G9RowBatchFormatError(`Unknown column type ${type}.`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function prefixedLength(body, position) {
|
|
83
|
+
const cursor = { pos: position };
|
|
84
|
+
const length = readVarint(body, cursor);
|
|
85
|
+
if (length > 2147483647)
|
|
86
|
+
throw new G9RowBatchFormatError('Row batch value is too long.');
|
|
87
|
+
return cursor.pos - position + length;
|
|
88
|
+
}
|
|
89
|
+
function put(sink, stream, body, cursor, length) {
|
|
90
|
+
const field = available(body, cursor.pos, length);
|
|
91
|
+
if (sink.lengths) {
|
|
92
|
+
sink.lengths[stream] = sink.lengths[stream] + length;
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
const cursors = sink.cursors;
|
|
96
|
+
sink.output.set(field, cursors[stream]);
|
|
97
|
+
cursors[stream] = cursors[stream] + length;
|
|
98
|
+
}
|
|
99
|
+
cursor.pos += length;
|
|
100
|
+
}
|
|
101
|
+
function scanRow(rows, cursor, header, sink) {
|
|
102
|
+
put(sink, KEY_STREAM, rows, cursor, keyLength(rows, cursor.pos, header.keyType));
|
|
103
|
+
switch (header.op) {
|
|
104
|
+
case G9ERowBatchOp.Upsert:
|
|
105
|
+
case G9ERowBatchOp.Backfill:
|
|
106
|
+
put(sink, 1, rows, cursor, varintLength(rows, cursor.pos));
|
|
107
|
+
scanValues(rows, cursor, header, 2, sink);
|
|
108
|
+
break;
|
|
109
|
+
case G9ERowBatchOp.Tombstone:
|
|
110
|
+
case G9ERowBatchOp.MoveOut:
|
|
111
|
+
put(sink, 1, rows, cursor, varintLength(rows, cursor.pos));
|
|
112
|
+
break;
|
|
113
|
+
case G9ERowBatchOp.KeyVersions:
|
|
114
|
+
put(sink, 1, rows, cursor, varintLength(rows, cursor.pos));
|
|
115
|
+
put(sink, 2, rows, cursor, 8);
|
|
116
|
+
break;
|
|
117
|
+
case G9ERowBatchOp.Push: {
|
|
118
|
+
const op = available(rows, cursor.pos, 1)[0];
|
|
119
|
+
put(sink, 1, rows, cursor, 1);
|
|
120
|
+
put(sink, 2, rows, cursor, varintLength(rows, cursor.pos));
|
|
121
|
+
put(sink, 3, rows, cursor, varintLength(rows, cursor.pos));
|
|
122
|
+
put(sink, 4, rows, cursor, 8);
|
|
123
|
+
put(sink, 5, rows, cursor, varintLength(rows, cursor.pos));
|
|
124
|
+
if (op === G9EPushRowOp.Upsert)
|
|
125
|
+
scanValues(rows, cursor, header, 6, sink);
|
|
126
|
+
else if (op !== G9EPushRowOp.Delete)
|
|
127
|
+
throw new G9RowBatchFormatError(`Unknown push op ${op}.`);
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
function scanValues(rows, cursor, header, bitmapStream, sink) {
|
|
133
|
+
const count = header.types.length;
|
|
134
|
+
const bitmapBytes = (count + 7) >> 3;
|
|
135
|
+
const bitmap = cursor.pos;
|
|
136
|
+
put(sink, bitmapStream, rows, cursor, bitmapBytes);
|
|
137
|
+
for (let column = 0; column < count; column++) {
|
|
138
|
+
if ((rows[bitmap + (column >> 3)] & (1 << (column & 7))) !== 0)
|
|
139
|
+
continue;
|
|
140
|
+
put(sink, bitmapStream + 1 + column, rows, cursor, valueLength(rows, cursor.pos, header.types[column]));
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
class Output {
|
|
144
|
+
constructor(capacity) {
|
|
145
|
+
this.length = 0;
|
|
146
|
+
this.bytes = new Uint8Array(capacity);
|
|
147
|
+
}
|
|
148
|
+
ensure(additional) {
|
|
149
|
+
const required = this.length + additional;
|
|
150
|
+
if (required <= this.bytes.length)
|
|
151
|
+
return;
|
|
152
|
+
if (required > G9RowBatchFormat.MaxDecodedBytes)
|
|
153
|
+
throw new Error('Row batch exceeds the maximum body size.');
|
|
154
|
+
const next = new Uint8Array(Math.max(required, this.bytes.length * 2));
|
|
155
|
+
next.set(this.bytes.subarray(0, this.length));
|
|
156
|
+
this.bytes = next;
|
|
157
|
+
}
|
|
158
|
+
writeVarint(value) {
|
|
159
|
+
this.ensure(10);
|
|
160
|
+
let v = value;
|
|
161
|
+
while (v >= 128) {
|
|
162
|
+
this.bytes[this.length++] = (v % 128) | 0x80;
|
|
163
|
+
v = Math.floor(v / 128);
|
|
164
|
+
}
|
|
165
|
+
this.bytes[this.length++] = v;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
/** Converts a version 1 (row-wise) body to the version 2 (column-grouped) layout. */
|
|
169
|
+
export function fromRows(rows) {
|
|
170
|
+
const sections = readInt32LE(available(rows, 0, 4), 0);
|
|
171
|
+
const out = new Output(rows.length + 256);
|
|
172
|
+
writeInt32LE(out.bytes, 0, sections);
|
|
173
|
+
out.length = 4;
|
|
174
|
+
const cursor = { pos: 4 };
|
|
175
|
+
for (let s = 0; s < sections; s++) {
|
|
176
|
+
const header = readSectionHeader(rows, cursor);
|
|
177
|
+
const streams = streamCount(header);
|
|
178
|
+
out.ensure(header.length + streams * 10);
|
|
179
|
+
out.bytes.set(rows.subarray(header.start, header.start + header.length), out.length);
|
|
180
|
+
out.length += header.length;
|
|
181
|
+
// Pass 1: every stream's length.
|
|
182
|
+
const lengths = [];
|
|
183
|
+
for (let i = 0; i < streams; i++)
|
|
184
|
+
lengths.push(0);
|
|
185
|
+
const rowsStart = cursor.pos;
|
|
186
|
+
const counting = { lengths, cursors: null, output: null };
|
|
187
|
+
for (let row = 0; row < header.rowCount; row++)
|
|
188
|
+
scanRow(rows, cursor, header, counting);
|
|
189
|
+
for (let i = 0; i < streams; i++)
|
|
190
|
+
out.writeVarint(lengths[i]);
|
|
191
|
+
// Pass 2: copy each field to its stream.
|
|
192
|
+
let total = 0;
|
|
193
|
+
const cursors = [];
|
|
194
|
+
for (let i = 0; i < streams; i++) {
|
|
195
|
+
cursors.push(out.length + total);
|
|
196
|
+
total += lengths[i];
|
|
197
|
+
}
|
|
198
|
+
out.ensure(total);
|
|
199
|
+
cursor.pos = rowsStart;
|
|
200
|
+
const copying = { lengths: null, cursors, output: out.bytes };
|
|
201
|
+
for (let row = 0; row < header.rowCount; row++)
|
|
202
|
+
scanRow(rows, cursor, header, copying);
|
|
203
|
+
out.length += total;
|
|
204
|
+
}
|
|
205
|
+
if (cursor.pos !== rows.length)
|
|
206
|
+
throw new G9RowBatchFormatError('Row batch body has trailing bytes.');
|
|
207
|
+
return out.bytes.subarray(0, out.length);
|
|
208
|
+
}
|
|
209
|
+
/** Converts a version 2 (column-grouped) body back to the version 1 layout, which is never longer. */
|
|
210
|
+
export function toRows(columns) {
|
|
211
|
+
if (columns.length < 4)
|
|
212
|
+
throw new G9RowBatchFormatError('Row batch body is too short.');
|
|
213
|
+
const sections = readInt32LE(columns, 0);
|
|
214
|
+
if (sections < 0)
|
|
215
|
+
throw new G9RowBatchFormatError('Negative section count.');
|
|
216
|
+
const output = new Uint8Array(columns.length);
|
|
217
|
+
writeInt32LE(output, 0, sections);
|
|
218
|
+
const written = { pos: 4 };
|
|
219
|
+
const cursor = { pos: 4 };
|
|
220
|
+
for (let s = 0; s < sections; s++) {
|
|
221
|
+
const header = readSectionHeader(columns, cursor);
|
|
222
|
+
output.set(columns.subarray(header.start, header.start + header.length), written.pos);
|
|
223
|
+
written.pos += header.length;
|
|
224
|
+
const streams = streamCount(header);
|
|
225
|
+
const starts = [];
|
|
226
|
+
const ends = [];
|
|
227
|
+
let offset = 0;
|
|
228
|
+
for (let i = 0; i < streams; i++) {
|
|
229
|
+
const streamLength = readVarint(columns, cursor);
|
|
230
|
+
starts.push(offset);
|
|
231
|
+
offset += streamLength;
|
|
232
|
+
if (offset > columns.length)
|
|
233
|
+
throw new G9RowBatchFormatError('Row batch stream is truncated.');
|
|
234
|
+
ends.push(offset);
|
|
235
|
+
}
|
|
236
|
+
if (cursor.pos + offset > columns.length)
|
|
237
|
+
throw new G9RowBatchFormatError('Row batch stream is truncated.');
|
|
238
|
+
for (let i = 0; i < streams; i++) {
|
|
239
|
+
starts[i] = starts[i] + cursor.pos;
|
|
240
|
+
ends[i] = ends[i] + cursor.pos;
|
|
241
|
+
}
|
|
242
|
+
for (let row = 0; row < header.rowCount; row++)
|
|
243
|
+
copyRow(columns, starts, ends, header, output, written);
|
|
244
|
+
for (let i = 0; i < streams; i++) {
|
|
245
|
+
if (starts[i] !== ends[i])
|
|
246
|
+
throw new G9RowBatchFormatError('Row batch stream has bytes no row used.');
|
|
247
|
+
}
|
|
248
|
+
cursor.pos += offset;
|
|
249
|
+
}
|
|
250
|
+
if (cursor.pos !== columns.length)
|
|
251
|
+
throw new G9RowBatchFormatError('Row batch body has trailing bytes.');
|
|
252
|
+
return output.subarray(0, written.pos);
|
|
253
|
+
}
|
|
254
|
+
function copyRow(columns, cursors, ends, header, output, written) {
|
|
255
|
+
take(columns, cursors, ends, KEY_STREAM, keyLength(columns, cursors[KEY_STREAM], header.keyType), output, written);
|
|
256
|
+
switch (header.op) {
|
|
257
|
+
case G9ERowBatchOp.Upsert:
|
|
258
|
+
case G9ERowBatchOp.Backfill:
|
|
259
|
+
take(columns, cursors, ends, 1, varintLength(columns, cursors[1]), output, written);
|
|
260
|
+
copyValues(columns, cursors, ends, header, 2, output, written);
|
|
261
|
+
break;
|
|
262
|
+
case G9ERowBatchOp.Tombstone:
|
|
263
|
+
case G9ERowBatchOp.MoveOut:
|
|
264
|
+
take(columns, cursors, ends, 1, varintLength(columns, cursors[1]), output, written);
|
|
265
|
+
break;
|
|
266
|
+
case G9ERowBatchOp.KeyVersions:
|
|
267
|
+
take(columns, cursors, ends, 1, varintLength(columns, cursors[1]), output, written);
|
|
268
|
+
take(columns, cursors, ends, 2, 8, output, written);
|
|
269
|
+
break;
|
|
270
|
+
case G9ERowBatchOp.Push: {
|
|
271
|
+
if (cursors[1] >= ends[1])
|
|
272
|
+
throw new G9RowBatchFormatError('Row batch stream is truncated.');
|
|
273
|
+
const op = columns[cursors[1]];
|
|
274
|
+
take(columns, cursors, ends, 1, 1, output, written);
|
|
275
|
+
take(columns, cursors, ends, 2, varintLength(columns, cursors[2]), output, written);
|
|
276
|
+
take(columns, cursors, ends, 3, varintLength(columns, cursors[3]), output, written);
|
|
277
|
+
take(columns, cursors, ends, 4, 8, output, written);
|
|
278
|
+
take(columns, cursors, ends, 5, varintLength(columns, cursors[5]), output, written);
|
|
279
|
+
if (op === G9EPushRowOp.Upsert)
|
|
280
|
+
copyValues(columns, cursors, ends, header, 6, output, written);
|
|
281
|
+
else if (op !== G9EPushRowOp.Delete)
|
|
282
|
+
throw new G9RowBatchFormatError(`Unknown push op ${op}.`);
|
|
283
|
+
break;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
function copyValues(columns, cursors, ends, header, bitmapStream, output, written) {
|
|
288
|
+
const count = header.types.length;
|
|
289
|
+
const bitmapBytes = (count + 7) >> 3;
|
|
290
|
+
const bitmap = written.pos;
|
|
291
|
+
take(columns, cursors, ends, bitmapStream, bitmapBytes, output, written);
|
|
292
|
+
for (let column = 0; column < count; column++) {
|
|
293
|
+
if ((output[bitmap + (column >> 3)] & (1 << (column & 7))) !== 0)
|
|
294
|
+
continue;
|
|
295
|
+
const stream = bitmapStream + 1 + column;
|
|
296
|
+
take(columns, cursors, ends, stream, valueLength(columns, cursors[stream], header.types[column]), output, written);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
function take(columns, cursors, ends, stream, length, output, written) {
|
|
300
|
+
const start = cursors[stream];
|
|
301
|
+
if (length < 0 || start + length > ends[stream])
|
|
302
|
+
throw new G9RowBatchFormatError('Row batch stream is truncated.');
|
|
303
|
+
if (written.pos + length > output.length)
|
|
304
|
+
throw new G9RowBatchFormatError('Row batch body is inconsistent.');
|
|
305
|
+
output.set(columns.subarray(start, start + length), written.pos);
|
|
306
|
+
cursors[stream] = start + length;
|
|
307
|
+
written.pos += length;
|
|
308
|
+
}
|
|
309
|
+
//# sourceMappingURL=columnLayout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"columnLayout.js","sourceRoot":"","sources":["../../../src/protocol/rowBatch/columnLayout.ts"],"names":[],"mappings":"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","sourcesContent":["// Twin of G9SyncData.Protocol/RowBatch/G9RowBatchColumnLayout.cs: the column-grouped body of G9RowBatch version 2\n// (ADR-0040), converted to and from the row-wise layout of version 1. Only the order of the bytes changes, so the\n// conversion is exact both ways.\nimport { G9ESyncColumnType } from '../../abstractions/enums.js';\nimport { G9SyncKey } from '../../abstractions/key.js';\nimport {\n type Cursor,\n G9EPushRowOp,\n G9ERowBatchOp,\n G9RowBatchFormat,\n G9RowBatchFormatError,\n isRowBatchOp,\n readInt32LE,\n readVarint,\n varintLength,\n writeInt32LE,\n} from './format.js';\n\nconst KEY_STREAM = 0;\n\ninterface SectionHeader {\n start: number;\n length: number;\n op: number;\n keyType: number;\n types: Uint8Array;\n rowCount: number;\n}\n\nfunction readSectionHeader(body: Uint8Array, cursor: Cursor): SectionHeader {\n const start = cursor.pos;\n const op = available(body, cursor.pos, 1)[0] as number;\n cursor.pos++;\n if (!isRowBatchOp(op)) throw new G9RowBatchFormatError(`Unknown op ${op}.`);\n readVarint(body, cursor);\n const keyType = available(body, cursor.pos, 1)[0] as number;\n cursor.pos++;\n if (!G9SyncKey.isSupportedKeyType(keyType)) throw new G9RowBatchFormatError(`Unsupported key type ${keyType}.`);\n const columnCount = readVarint(body, cursor);\n if (columnCount > 1024) throw new G9RowBatchFormatError('Too many columns.');\n const types = available(body, cursor.pos, columnCount);\n cursor.pos += columnCount;\n const rowCount = readInt32LE(available(body, cursor.pos, 4), 0);\n cursor.pos += 4;\n if (rowCount < 0) throw new G9RowBatchFormatError('Negative row count.');\n return { start, length: cursor.pos - start, op, keyType, types, rowCount };\n}\n\nfunction streamCount(header: SectionHeader): number {\n switch (header.op) {\n case G9ERowBatchOp.Upsert:\n case G9ERowBatchOp.Backfill:\n return 3 + header.types.length;\n case G9ERowBatchOp.Tombstone:\n case G9ERowBatchOp.MoveOut:\n return 2;\n case G9ERowBatchOp.KeyVersions:\n return 3;\n case G9ERowBatchOp.Push:\n return 7 + header.types.length;\n default:\n throw new G9RowBatchFormatError(`Unknown op ${header.op}.`);\n }\n}\n\nfunction available(body: Uint8Array, position: number, length: number): Uint8Array {\n if (length < 0 || position + length > body.length) throw new G9RowBatchFormatError('Row batch is truncated.');\n return body.subarray(position, position + length);\n}\n\nfunction keyLength(body: Uint8Array, position: number, keyType: number): number {\n if (keyType === G9ESyncColumnType.Guid) return 16;\n if (keyType === G9ESyncColumnType.Int32 || keyType === G9ESyncColumnType.Int64) return varintLength(body, position);\n return prefixedLength(body, position);\n}\n\nfunction valueLength(body: Uint8Array, position: number, type: number): number {\n switch (type) {\n case G9ESyncColumnType.Boolean:\n return 1;\n case G9ESyncColumnType.Int32:\n case G9ESyncColumnType.Int64:\n case G9ESyncColumnType.TimeSpan:\n return varintLength(body, position);\n case G9ESyncColumnType.Double:\n return 8;\n case G9ESyncColumnType.Decimal:\n case G9ESyncColumnType.Guid:\n return 16;\n case G9ESyncColumnType.DateTime:\n return 9;\n case G9ESyncColumnType.DateTimeOffset:\n return 10;\n case G9ESyncColumnType.String:\n case G9ESyncColumnType.Bytes:\n return prefixedLength(body, position);\n default:\n throw new G9RowBatchFormatError(`Unknown column type ${type}.`);\n }\n}\n\nfunction prefixedLength(body: Uint8Array, position: number): number {\n const cursor = { pos: position };\n const length = readVarint(body, cursor);\n if (length > 2147483647) throw new G9RowBatchFormatError('Row batch value is too long.');\n return cursor.pos - position + length;\n}\n\n/** Counts stream lengths (pass 1) or copies fields to their stream cursors (pass 2). */\ninterface StreamSink {\n lengths: number[] | null;\n cursors: number[] | null;\n output: Uint8Array | null;\n}\n\nfunction put(sink: StreamSink, stream: number, body: Uint8Array, cursor: Cursor, length: number): void {\n const field = available(body, cursor.pos, length);\n if (sink.lengths) {\n sink.lengths[stream] = (sink.lengths[stream] as number) + length;\n } else {\n const cursors = sink.cursors as number[];\n (sink.output as Uint8Array).set(field, cursors[stream] as number);\n cursors[stream] = (cursors[stream] as number) + length;\n }\n cursor.pos += length;\n}\n\nfunction scanRow(rows: Uint8Array, cursor: Cursor, header: SectionHeader, sink: StreamSink): void {\n put(sink, KEY_STREAM, rows, cursor, keyLength(rows, cursor.pos, header.keyType));\n switch (header.op) {\n case G9ERowBatchOp.Upsert:\n case G9ERowBatchOp.Backfill:\n put(sink, 1, rows, cursor, varintLength(rows, cursor.pos));\n scanValues(rows, cursor, header, 2, sink);\n break;\n case G9ERowBatchOp.Tombstone:\n case G9ERowBatchOp.MoveOut:\n put(sink, 1, rows, cursor, varintLength(rows, cursor.pos));\n break;\n case G9ERowBatchOp.KeyVersions:\n put(sink, 1, rows, cursor, varintLength(rows, cursor.pos));\n put(sink, 2, rows, cursor, 8);\n break;\n case G9ERowBatchOp.Push: {\n const op = available(rows, cursor.pos, 1)[0] as number;\n put(sink, 1, rows, cursor, 1);\n put(sink, 2, rows, cursor, varintLength(rows, cursor.pos));\n put(sink, 3, rows, cursor, varintLength(rows, cursor.pos));\n put(sink, 4, rows, cursor, 8);\n put(sink, 5, rows, cursor, varintLength(rows, cursor.pos));\n if (op === G9EPushRowOp.Upsert) scanValues(rows, cursor, header, 6, sink);\n else if (op !== G9EPushRowOp.Delete) throw new G9RowBatchFormatError(`Unknown push op ${op}.`);\n break;\n }\n }\n}\n\nfunction scanValues(rows: Uint8Array, cursor: Cursor, header: SectionHeader, bitmapStream: number, sink: StreamSink): void {\n const count = header.types.length;\n const bitmapBytes = (count + 7) >> 3;\n const bitmap = cursor.pos;\n put(sink, bitmapStream, rows, cursor, bitmapBytes);\n for (let column = 0; column < count; column++) {\n if (((rows[bitmap + (column >> 3)] as number) & (1 << (column & 7))) !== 0) continue;\n put(sink, bitmapStream + 1 + column, rows, cursor, valueLength(rows, cursor.pos, header.types[column] as number));\n }\n}\n\nclass Output {\n bytes: Uint8Array;\n length = 0;\n\n constructor(capacity: number) {\n this.bytes = new Uint8Array(capacity);\n }\n\n ensure(additional: number): void {\n const required = this.length + additional;\n if (required <= this.bytes.length) return;\n if (required > G9RowBatchFormat.MaxDecodedBytes) throw new Error('Row batch exceeds the maximum body size.');\n const next = new Uint8Array(Math.max(required, this.bytes.length * 2));\n next.set(this.bytes.subarray(0, this.length));\n this.bytes = next;\n }\n\n writeVarint(value: number): void {\n this.ensure(10);\n let v = value;\n while (v >= 128) {\n this.bytes[this.length++] = (v % 128) | 0x80;\n v = Math.floor(v / 128);\n }\n this.bytes[this.length++] = v;\n }\n}\n\n/** Converts a version 1 (row-wise) body to the version 2 (column-grouped) layout. */\nexport function fromRows(rows: Uint8Array): Uint8Array {\n const sections = readInt32LE(available(rows, 0, 4), 0);\n const out = new Output(rows.length + 256);\n writeInt32LE(out.bytes, 0, sections);\n out.length = 4;\n const cursor: Cursor = { pos: 4 };\n for (let s = 0; s < sections; s++) {\n const header = readSectionHeader(rows, cursor);\n const streams = streamCount(header);\n out.ensure(header.length + streams * 10);\n out.bytes.set(rows.subarray(header.start, header.start + header.length), out.length);\n out.length += header.length;\n\n // Pass 1: every stream's length.\n const lengths: number[] = [];\n for (let i = 0; i < streams; i++) lengths.push(0);\n const rowsStart = cursor.pos;\n const counting: StreamSink = { lengths, cursors: null, output: null };\n for (let row = 0; row < header.rowCount; row++) scanRow(rows, cursor, header, counting);\n for (let i = 0; i < streams; i++) out.writeVarint(lengths[i] as number);\n\n // Pass 2: copy each field to its stream.\n let total = 0;\n const cursors: number[] = [];\n for (let i = 0; i < streams; i++) {\n cursors.push(out.length + total);\n total += lengths[i] as number;\n }\n out.ensure(total);\n cursor.pos = rowsStart;\n const copying: StreamSink = { lengths: null, cursors, output: out.bytes };\n for (let row = 0; row < header.rowCount; row++) scanRow(rows, cursor, header, copying);\n out.length += total;\n }\n if (cursor.pos !== rows.length) throw new G9RowBatchFormatError('Row batch body has trailing bytes.');\n return out.bytes.subarray(0, out.length);\n}\n\n/** Converts a version 2 (column-grouped) body back to the version 1 layout, which is never longer. */\nexport function toRows(columns: Uint8Array): Uint8Array {\n if (columns.length < 4) throw new G9RowBatchFormatError('Row batch body is too short.');\n const sections = readInt32LE(columns, 0);\n if (sections < 0) throw new G9RowBatchFormatError('Negative section count.');\n const output = new Uint8Array(columns.length);\n writeInt32LE(output, 0, sections);\n const written: Cursor = { pos: 4 };\n const cursor: Cursor = { pos: 4 };\n for (let s = 0; s < sections; s++) {\n const header = readSectionHeader(columns, cursor);\n output.set(columns.subarray(header.start, header.start + header.length), written.pos);\n written.pos += header.length;\n\n const streams = streamCount(header);\n const starts: number[] = [];\n const ends: number[] = [];\n let offset = 0;\n for (let i = 0; i < streams; i++) {\n const streamLength = readVarint(columns, cursor);\n starts.push(offset);\n offset += streamLength;\n if (offset > columns.length) throw new G9RowBatchFormatError('Row batch stream is truncated.');\n ends.push(offset);\n }\n if (cursor.pos + offset > columns.length) throw new G9RowBatchFormatError('Row batch stream is truncated.');\n for (let i = 0; i < streams; i++) {\n starts[i] = (starts[i] as number) + cursor.pos;\n ends[i] = (ends[i] as number) + cursor.pos;\n }\n for (let row = 0; row < header.rowCount; row++) copyRow(columns, starts, ends, header, output, written);\n for (let i = 0; i < streams; i++) {\n if (starts[i] !== ends[i]) throw new G9RowBatchFormatError('Row batch stream has bytes no row used.');\n }\n cursor.pos += offset;\n }\n if (cursor.pos !== columns.length) throw new G9RowBatchFormatError('Row batch body has trailing bytes.');\n return output.subarray(0, written.pos);\n}\n\nfunction copyRow(columns: Uint8Array, cursors: number[], ends: number[], header: SectionHeader, output: Uint8Array, written: Cursor): void {\n take(columns, cursors, ends, KEY_STREAM, keyLength(columns, cursors[KEY_STREAM] as number, header.keyType), output, written);\n switch (header.op) {\n case G9ERowBatchOp.Upsert:\n case G9ERowBatchOp.Backfill:\n take(columns, cursors, ends, 1, varintLength(columns, cursors[1] as number), output, written);\n copyValues(columns, cursors, ends, header, 2, output, written);\n break;\n case G9ERowBatchOp.Tombstone:\n case G9ERowBatchOp.MoveOut:\n take(columns, cursors, ends, 1, varintLength(columns, cursors[1] as number), output, written);\n break;\n case G9ERowBatchOp.KeyVersions:\n take(columns, cursors, ends, 1, varintLength(columns, cursors[1] as number), output, written);\n take(columns, cursors, ends, 2, 8, output, written);\n break;\n case G9ERowBatchOp.Push: {\n if ((cursors[1] as number) >= (ends[1] as number)) throw new G9RowBatchFormatError('Row batch stream is truncated.');\n const op = columns[cursors[1] as number] as number;\n take(columns, cursors, ends, 1, 1, output, written);\n take(columns, cursors, ends, 2, varintLength(columns, cursors[2] as number), output, written);\n take(columns, cursors, ends, 3, varintLength(columns, cursors[3] as number), output, written);\n take(columns, cursors, ends, 4, 8, output, written);\n take(columns, cursors, ends, 5, varintLength(columns, cursors[5] as number), output, written);\n if (op === G9EPushRowOp.Upsert) copyValues(columns, cursors, ends, header, 6, output, written);\n else if (op !== G9EPushRowOp.Delete) throw new G9RowBatchFormatError(`Unknown push op ${op}.`);\n break;\n }\n }\n}\n\nfunction copyValues(\n columns: Uint8Array,\n cursors: number[],\n ends: number[],\n header: SectionHeader,\n bitmapStream: number,\n output: Uint8Array,\n written: Cursor,\n): void {\n const count = header.types.length;\n const bitmapBytes = (count + 7) >> 3;\n const bitmap = written.pos;\n take(columns, cursors, ends, bitmapStream, bitmapBytes, output, written);\n for (let column = 0; column < count; column++) {\n if (((output[bitmap + (column >> 3)] as number) & (1 << (column & 7))) !== 0) continue;\n const stream = bitmapStream + 1 + column;\n take(columns, cursors, ends, stream, valueLength(columns, cursors[stream] as number, header.types[column] as number), output, written);\n }\n}\n\nfunction take(columns: Uint8Array, cursors: number[], ends: number[], stream: number, length: number, output: Uint8Array, written: Cursor): void {\n const start = cursors[stream] as number;\n if (length < 0 || start + length > (ends[stream] as number)) throw new G9RowBatchFormatError('Row batch stream is truncated.');\n if (written.pos + length > output.length) throw new G9RowBatchFormatError('Row batch body is inconsistent.');\n output.set(columns.subarray(start, start + length), written.pos);\n cursors[stream] = start + length;\n written.pos += length;\n}\n"]}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { G9Long } from '../../abstractions/long.js';
|
|
2
|
+
/** What the rows of a G9RowBatch section mean (`G9ERowBatchOp`). */
|
|
3
|
+
export declare const G9ERowBatchOp: {
|
|
4
|
+
/** Key, version, full negotiated column values. Insert or update. */
|
|
5
|
+
readonly Upsert: 1;
|
|
6
|
+
/** Key and version of a deleted row. */
|
|
7
|
+
readonly Tombstone: 2;
|
|
8
|
+
/** Key and version of a row that left the chunk's subscription. */
|
|
9
|
+
readonly MoveOut: 3;
|
|
10
|
+
/** Key, version and row hash (reconciliation listing). */
|
|
11
|
+
readonly KeyVersions: 4;
|
|
12
|
+
/** Client upload rows: key, op, local sequence, base version, dirty mask, HLC ms, values for upserts. */
|
|
13
|
+
readonly Push: 5;
|
|
14
|
+
/** Key, version and only the backfilled columns of rows the client already holds. */
|
|
15
|
+
readonly Backfill: 6;
|
|
16
|
+
};
|
|
17
|
+
export type G9ERowBatchOp = (typeof G9ERowBatchOp)[keyof typeof G9ERowBatchOp];
|
|
18
|
+
/** Operation of a push row (`G9EPushRowOp`). */
|
|
19
|
+
export declare const G9EPushRowOp: {
|
|
20
|
+
readonly Upsert: 1;
|
|
21
|
+
readonly Delete: 2;
|
|
22
|
+
};
|
|
23
|
+
export type G9EPushRowOp = (typeof G9EPushRowOp)[keyof typeof G9EPushRowOp];
|
|
24
|
+
/** Frame body compression (`G9ECompression`). */
|
|
25
|
+
export declare const G9ECompression: {
|
|
26
|
+
readonly None: 0;
|
|
27
|
+
readonly Brotli: 1;
|
|
28
|
+
};
|
|
29
|
+
export type G9ECompression = (typeof G9ECompression)[keyof typeof G9ECompression];
|
|
30
|
+
/** Layout constants (`G9RowBatchFormat`). */
|
|
31
|
+
export declare const G9RowBatchFormat: {
|
|
32
|
+
/** Row-wise body. */
|
|
33
|
+
readonly Version: 1;
|
|
34
|
+
/** Column-grouped body (ADR-0040). */
|
|
35
|
+
readonly ColumnVersion: 2;
|
|
36
|
+
readonly MaxVersion: 2;
|
|
37
|
+
readonly HeaderSize: 10;
|
|
38
|
+
readonly MaxBodyBytes: number;
|
|
39
|
+
/** The largest body any reader decodes: the writer's ceiling plus the column layout's allowance. */
|
|
40
|
+
readonly MaxDecodedBytes: number;
|
|
41
|
+
};
|
|
42
|
+
export declare function isRowBatchOp(op: number): op is G9ERowBatchOp;
|
|
43
|
+
/** True for ops whose rows carry column values. */
|
|
44
|
+
export declare function opHasValues(op: number): boolean;
|
|
45
|
+
/** A malformed frame (the .NET `FormatException`). */
|
|
46
|
+
export declare class G9RowBatchFormatError extends Error {
|
|
47
|
+
constructor(message: string);
|
|
48
|
+
}
|
|
49
|
+
export declare const VARINT_MAX_BYTES = 10;
|
|
50
|
+
/** A read position over a byte array. */
|
|
51
|
+
export interface Cursor {
|
|
52
|
+
pos: number;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Reads an unsigned LEB128 varint as a number. Exact up to 2^53; beyond that the nearest double (callers that need
|
|
56
|
+
* exactness use {@link readVarintLong}). Throws on a truncated or over-long varint.
|
|
57
|
+
*/
|
|
58
|
+
export declare function readVarint(bytes: Uint8Array, cursor: Cursor, end?: number): number;
|
|
59
|
+
/** Reads an unsigned LEB128 varint exactly, as the bits of an unsigned 64-bit value. */
|
|
60
|
+
export declare function readVarintLong(bytes: Uint8Array, cursor: Cursor, end?: number): G9Long;
|
|
61
|
+
/** A varint that must fit an int32 (a length, a count, an id). */
|
|
62
|
+
export declare function readVarintInt32(bytes: Uint8Array, cursor: Cursor, end?: number): number;
|
|
63
|
+
/** Skips a varint and returns its length in bytes. */
|
|
64
|
+
export declare function varintLength(bytes: Uint8Array, position: number, end?: number): number;
|
|
65
|
+
/** Zig-zag of a signed 64-bit value (`(v << 1) ^ (v >> 63)`), as unsigned bits. */
|
|
66
|
+
export declare function zigZag(value: G9Long): G9Long;
|
|
67
|
+
/** Inverse zig-zag (`(long)(v >> 1) ^ -(long)(v & 1)`). */
|
|
68
|
+
export declare function unZigZag(value: G9Long): G9Long;
|
|
69
|
+
/** Reads a zig-zag varint as a signed number (exact within ±2^53). */
|
|
70
|
+
export declare function readZigZagNumber(bytes: Uint8Array, cursor: Cursor, end?: number): number;
|
|
71
|
+
/** Reads a zig-zag varint exactly. */
|
|
72
|
+
export declare function readZigZagLong(bytes: Uint8Array, cursor: Cursor, end?: number): G9Long;
|
|
73
|
+
export declare function readInt32LE(bytes: Uint8Array, offset: number): number;
|
|
74
|
+
export declare function writeInt32LE(bytes: Uint8Array, offset: number, value: number): void;
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
// Twins of G9SyncData.Protocol/RowBatch/G9RowBatchTypes.cs and G9Varint.cs.
|
|
2
|
+
import { G9Long } from '../../abstractions/long.js';
|
|
3
|
+
/** What the rows of a G9RowBatch section mean (`G9ERowBatchOp`). */
|
|
4
|
+
export const G9ERowBatchOp = {
|
|
5
|
+
/** Key, version, full negotiated column values. Insert or update. */
|
|
6
|
+
Upsert: 1,
|
|
7
|
+
/** Key and version of a deleted row. */
|
|
8
|
+
Tombstone: 2,
|
|
9
|
+
/** Key and version of a row that left the chunk's subscription. */
|
|
10
|
+
MoveOut: 3,
|
|
11
|
+
/** Key, version and row hash (reconciliation listing). */
|
|
12
|
+
KeyVersions: 4,
|
|
13
|
+
/** Client upload rows: key, op, local sequence, base version, dirty mask, HLC ms, values for upserts. */
|
|
14
|
+
Push: 5,
|
|
15
|
+
/** Key, version and only the backfilled columns of rows the client already holds. */
|
|
16
|
+
Backfill: 6,
|
|
17
|
+
};
|
|
18
|
+
/** Operation of a push row (`G9EPushRowOp`). */
|
|
19
|
+
export const G9EPushRowOp = {
|
|
20
|
+
Upsert: 1,
|
|
21
|
+
Delete: 2,
|
|
22
|
+
};
|
|
23
|
+
/** Frame body compression (`G9ECompression`). */
|
|
24
|
+
export const G9ECompression = {
|
|
25
|
+
None: 0,
|
|
26
|
+
Brotli: 1,
|
|
27
|
+
};
|
|
28
|
+
/** Layout constants (`G9RowBatchFormat`). */
|
|
29
|
+
export const G9RowBatchFormat = {
|
|
30
|
+
/** Row-wise body. */
|
|
31
|
+
Version: 1,
|
|
32
|
+
/** Column-grouped body (ADR-0040). */
|
|
33
|
+
ColumnVersion: 2,
|
|
34
|
+
MaxVersion: 2,
|
|
35
|
+
HeaderSize: 10,
|
|
36
|
+
MaxBodyBytes: 512 * 1024 * 1024,
|
|
37
|
+
/** The largest body any reader decodes: the writer's ceiling plus the column layout's allowance. */
|
|
38
|
+
MaxDecodedBytes: 512 * 1024 * 1024 + 64 * 1024 * 1024,
|
|
39
|
+
};
|
|
40
|
+
export function isRowBatchOp(op) {
|
|
41
|
+
return op >= 1 && op <= 6;
|
|
42
|
+
}
|
|
43
|
+
/** True for ops whose rows carry column values. */
|
|
44
|
+
export function opHasValues(op) {
|
|
45
|
+
return op === G9ERowBatchOp.Upsert || op === G9ERowBatchOp.Backfill;
|
|
46
|
+
}
|
|
47
|
+
/** A malformed frame (the .NET `FormatException`). */
|
|
48
|
+
export class G9RowBatchFormatError extends Error {
|
|
49
|
+
constructor(message) {
|
|
50
|
+
super(message);
|
|
51
|
+
this.name = 'G9RowBatchFormatError';
|
|
52
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
export const VARINT_MAX_BYTES = 10;
|
|
56
|
+
/**
|
|
57
|
+
* Reads an unsigned LEB128 varint as a number. Exact up to 2^53; beyond that the nearest double (callers that need
|
|
58
|
+
* exactness use {@link readVarintLong}). Throws on a truncated or over-long varint.
|
|
59
|
+
*/
|
|
60
|
+
export function readVarint(bytes, cursor, end = bytes.length) {
|
|
61
|
+
let result = 0;
|
|
62
|
+
let multiplier = 1;
|
|
63
|
+
let shift = 0;
|
|
64
|
+
let pos = cursor.pos;
|
|
65
|
+
for (;;) {
|
|
66
|
+
if (pos >= end)
|
|
67
|
+
throw new G9RowBatchFormatError('Truncated varint.');
|
|
68
|
+
const b = bytes[pos++];
|
|
69
|
+
result += (b & 0x7f) * multiplier;
|
|
70
|
+
if ((b & 0x80) === 0) {
|
|
71
|
+
cursor.pos = pos;
|
|
72
|
+
return result;
|
|
73
|
+
}
|
|
74
|
+
shift += 7;
|
|
75
|
+
if (shift > 63)
|
|
76
|
+
throw new G9RowBatchFormatError('Varint is too long.');
|
|
77
|
+
multiplier *= 128;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/** Reads an unsigned LEB128 varint exactly, as the bits of an unsigned 64-bit value. */
|
|
81
|
+
export function readVarintLong(bytes, cursor, end = bytes.length) {
|
|
82
|
+
let lo = 0;
|
|
83
|
+
let hi = 0;
|
|
84
|
+
let shift = 0;
|
|
85
|
+
let pos = cursor.pos;
|
|
86
|
+
for (;;) {
|
|
87
|
+
if (pos >= end)
|
|
88
|
+
throw new G9RowBatchFormatError('Truncated varint.');
|
|
89
|
+
const b = bytes[pos++];
|
|
90
|
+
const bits = b & 0x7f;
|
|
91
|
+
if (shift < 28) {
|
|
92
|
+
lo |= bits << shift;
|
|
93
|
+
}
|
|
94
|
+
else if (shift === 28) {
|
|
95
|
+
lo |= (bits & 0x0f) << 28;
|
|
96
|
+
hi |= bits >>> 4;
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
hi |= bits << (shift - 32);
|
|
100
|
+
}
|
|
101
|
+
if ((b & 0x80) === 0) {
|
|
102
|
+
cursor.pos = pos;
|
|
103
|
+
return new G9Long(hi, lo);
|
|
104
|
+
}
|
|
105
|
+
shift += 7;
|
|
106
|
+
if (shift > 63)
|
|
107
|
+
throw new G9RowBatchFormatError('Varint is too long.');
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/** A varint that must fit an int32 (a length, a count, an id). */
|
|
111
|
+
export function readVarintInt32(bytes, cursor, end = bytes.length) {
|
|
112
|
+
const value = readVarint(bytes, cursor, end);
|
|
113
|
+
if (value > 2147483647)
|
|
114
|
+
throw new G9RowBatchFormatError('Varint is out of range.');
|
|
115
|
+
return value;
|
|
116
|
+
}
|
|
117
|
+
/** Skips a varint and returns its length in bytes. */
|
|
118
|
+
export function varintLength(bytes, position, end = bytes.length) {
|
|
119
|
+
let pos = position;
|
|
120
|
+
let shift = 0;
|
|
121
|
+
for (;;) {
|
|
122
|
+
if (pos >= end)
|
|
123
|
+
throw new G9RowBatchFormatError('Truncated varint.');
|
|
124
|
+
const b = bytes[pos++];
|
|
125
|
+
if ((b & 0x80) === 0)
|
|
126
|
+
return pos - position;
|
|
127
|
+
shift += 7;
|
|
128
|
+
if (shift > 63)
|
|
129
|
+
throw new G9RowBatchFormatError('Varint is too long.');
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/** Zig-zag of a signed 64-bit value (`(v << 1) ^ (v >> 63)`), as unsigned bits. */
|
|
133
|
+
export function zigZag(value) {
|
|
134
|
+
return value.shiftLeft(1).xor(value.shiftRight(63));
|
|
135
|
+
}
|
|
136
|
+
/** Inverse zig-zag (`(long)(v >> 1) ^ -(long)(v & 1)`). */
|
|
137
|
+
export function unZigZag(value) {
|
|
138
|
+
const shifted = value.shiftRightUnsigned(1);
|
|
139
|
+
return (value.lo & 1) === 0 ? shifted : shifted.xor(G9Long.MINUS_ONE);
|
|
140
|
+
}
|
|
141
|
+
/** Reads a zig-zag varint as a signed number (exact within ±2^53). */
|
|
142
|
+
export function readZigZagNumber(bytes, cursor, end) {
|
|
143
|
+
const start = cursor.pos;
|
|
144
|
+
const raw = readVarint(bytes, cursor, end);
|
|
145
|
+
if (raw <= 9007199254740991)
|
|
146
|
+
return raw % 2 === 0 ? raw / 2 : -(raw + 1) / 2;
|
|
147
|
+
cursor.pos = start;
|
|
148
|
+
return unZigZag(readVarintLong(bytes, cursor, end)).toNumber();
|
|
149
|
+
}
|
|
150
|
+
/** Reads a zig-zag varint exactly. */
|
|
151
|
+
export function readZigZagLong(bytes, cursor, end) {
|
|
152
|
+
return unZigZag(readVarintLong(bytes, cursor, end));
|
|
153
|
+
}
|
|
154
|
+
export function readInt32LE(bytes, offset) {
|
|
155
|
+
return bytes[offset] | (bytes[offset + 1] << 8) | (bytes[offset + 2] << 16) | (bytes[offset + 3] << 24);
|
|
156
|
+
}
|
|
157
|
+
export function writeInt32LE(bytes, offset, value) {
|
|
158
|
+
bytes[offset] = value & 0xff;
|
|
159
|
+
bytes[offset + 1] = (value >>> 8) & 0xff;
|
|
160
|
+
bytes[offset + 2] = (value >>> 16) & 0xff;
|
|
161
|
+
bytes[offset + 3] = (value >>> 24) & 0xff;
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../../src/protocol/rowBatch/format.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAEpD,oEAAoE;AACpE,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,qEAAqE;IACrE,MAAM,EAAE,CAAC;IACT,wCAAwC;IACxC,SAAS,EAAE,CAAC;IACZ,mEAAmE;IACnE,OAAO,EAAE,CAAC;IACV,0DAA0D;IAC1D,WAAW,EAAE,CAAC;IACd,yGAAyG;IACzG,IAAI,EAAE,CAAC;IACP,qFAAqF;IACrF,QAAQ,EAAE,CAAC;CACH,CAAC;AAGX,gDAAgD;AAChD,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,MAAM,EAAE,CAAC;IACT,MAAM,EAAE,CAAC;CACD,CAAC;AAGX,iDAAiD;AACjD,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,IAAI,EAAE,CAAC;IACP,MAAM,EAAE,CAAC;CACD,CAAC;AAGX,6CAA6C;AAC7C,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,qBAAqB;IACrB,OAAO,EAAE,CAAC;IACV,sCAAsC;IACtC,aAAa,EAAE,CAAC;IAChB,UAAU,EAAE,CAAC;IACb,UAAU,EAAE,EAAE;IACd,YAAY,EAAE,GAAG,GAAG,IAAI,GAAG,IAAI;IAC/B,oGAAoG;IACpG,eAAe,EAAE,GAAG,GAAG,IAAI,GAAG,IAAI,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI;CAC7C,CAAC;AAEX,MAAM,UAAU,YAAY,CAAC,EAAU;IACrC,OAAO,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AAC5B,CAAC;AAED,mDAAmD;AACnD,MAAM,UAAU,WAAW,CAAC,EAAU;IACpC,OAAO,EAAE,KAAK,aAAa,CAAC,MAAM,IAAI,EAAE,KAAK,aAAa,CAAC,QAAQ,CAAC;AACtE,CAAC;AAED,sDAAsD;AACtD,MAAM,OAAO,qBAAsB,SAAQ,KAAK;IAC9C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC;QACpC,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACpD,CAAC;CACF;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAG,EAAE,CAAC;AAOnC;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,KAAiB,EAAE,MAAc,EAAE,MAAc,KAAK,CAAC,MAAM;IACtF,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC;IACrB,SAAS,CAAC;QACR,IAAI,GAAG,IAAI,GAAG;YAAE,MAAM,IAAI,qBAAqB,CAAC,mBAAmB,CAAC,CAAC;QACrE,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,EAAE,CAAW,CAAC;QACjC,MAAM,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,UAAU,CAAC;QAClC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACrB,MAAM,CAAC,GAAG,GAAG,GAAG,CAAC;YACjB,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,KAAK,IAAI,CAAC,CAAC;QACX,IAAI,KAAK,GAAG,EAAE;YAAE,MAAM,IAAI,qBAAqB,CAAC,qBAAqB,CAAC,CAAC;QACvE,UAAU,IAAI,GAAG,CAAC;IACpB,CAAC;AACH,CAAC;AAED,wFAAwF;AACxF,MAAM,UAAU,cAAc,CAAC,KAAiB,EAAE,MAAc,EAAE,MAAc,KAAK,CAAC,MAAM;IAC1F,IAAI,EAAE,GAAG,CAAC,CAAC;IACX,IAAI,EAAE,GAAG,CAAC,CAAC;IACX,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC;IACrB,SAAS,CAAC;QACR,IAAI,GAAG,IAAI,GAAG;YAAE,MAAM,IAAI,qBAAqB,CAAC,mBAAmB,CAAC,CAAC;QACrE,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,EAAE,CAAW,CAAC;QACjC,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC;QACtB,IAAI,KAAK,GAAG,EAAE,EAAE,CAAC;YACf,EAAE,IAAI,IAAI,IAAI,KAAK,CAAC;QACtB,CAAC;aAAM,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;YACxB,EAAE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YAC1B,EAAE,IAAI,IAAI,KAAK,CAAC,CAAC;QACnB,CAAC;aAAM,CAAC;YACN,EAAE,IAAI,IAAI,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;QAC7B,CAAC;QACD,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACrB,MAAM,CAAC,GAAG,GAAG,GAAG,CAAC;YACjB,OAAO,IAAI,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QAC5B,CAAC;QACD,KAAK,IAAI,CAAC,CAAC;QACX,IAAI,KAAK,GAAG,EAAE;YAAE,MAAM,IAAI,qBAAqB,CAAC,qBAAqB,CAAC,CAAC;IACzE,CAAC;AACH,CAAC;AAED,kEAAkE;AAClE,MAAM,UAAU,eAAe,CAAC,KAAiB,EAAE,MAAc,EAAE,MAAc,KAAK,CAAC,MAAM;IAC3F,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;IAC7C,IAAI,KAAK,GAAG,UAAU;QAAE,MAAM,IAAI,qBAAqB,CAAC,yBAAyB,CAAC,CAAC;IACnF,OAAO,KAAK,CAAC;AACf,CAAC;AAED,sDAAsD;AACtD,MAAM,UAAU,YAAY,CAAC,KAAiB,EAAE,QAAgB,EAAE,MAAc,KAAK,CAAC,MAAM;IAC1F,IAAI,GAAG,GAAG,QAAQ,CAAC;IACnB,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,SAAS,CAAC;QACR,IAAI,GAAG,IAAI,GAAG;YAAE,MAAM,IAAI,qBAAqB,CAAC,mBAAmB,CAAC,CAAC;QACrE,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,EAAE,CAAW,CAAC;QACjC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC;YAAE,OAAO,GAAG,GAAG,QAAQ,CAAC;QAC5C,KAAK,IAAI,CAAC,CAAC;QACX,IAAI,KAAK,GAAG,EAAE;YAAE,MAAM,IAAI,qBAAqB,CAAC,qBAAqB,CAAC,CAAC;IACzE,CAAC;AACH,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,MAAM,CAAC,KAAa;IAClC,OAAO,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC;AACtD,CAAC;AAED,2DAA2D;AAC3D,MAAM,UAAU,QAAQ,CAAC,KAAa;IACpC,MAAM,OAAO,GAAG,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC;IAC5C,OAAO,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;AACxE,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,gBAAgB,CAAC,KAAiB,EAAE,MAAc,EAAE,GAAY;IAC9E,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC;IACzB,MAAM,GAAG,GAAG,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;IAC3C,IAAI,GAAG,IAAI,gBAAgB;QAAE,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;IAC7E,MAAM,CAAC,GAAG,GAAG,KAAK,CAAC;IACnB,OAAO,QAAQ,CAAC,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;AACjE,CAAC;AAED,sCAAsC;AACtC,MAAM,UAAU,cAAc,CAAC,KAAiB,EAAE,MAAc,EAAE,GAAY;IAC5E,OAAO,QAAQ,CAAC,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;AACtD,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAiB,EAAE,MAAc;IAC3D,OAAQ,KAAK,CAAC,MAAM,CAAY,GAAG,CAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAY,IAAI,CAAC,CAAC,GAAG,CAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAY,IAAI,EAAE,CAAC,GAAG,CAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAY,IAAI,EAAE,CAAC,CAAC;AAC1J,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAiB,EAAE,MAAc,EAAE,KAAa;IAC3E,KAAK,CAAC,MAAM,CAAC,GAAG,KAAK,GAAG,IAAI,CAAC;IAC7B,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC;IACzC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;IAC1C,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;AAC5C,CAAC","sourcesContent":["// Twins of G9SyncData.Protocol/RowBatch/G9RowBatchTypes.cs and G9Varint.cs.\nimport { G9Long } from '../../abstractions/long.js';\n\n/** What the rows of a G9RowBatch section mean (`G9ERowBatchOp`). */\nexport const G9ERowBatchOp = {\n /** Key, version, full negotiated column values. Insert or update. */\n Upsert: 1,\n /** Key and version of a deleted row. */\n Tombstone: 2,\n /** Key and version of a row that left the chunk's subscription. */\n MoveOut: 3,\n /** Key, version and row hash (reconciliation listing). */\n KeyVersions: 4,\n /** Client upload rows: key, op, local sequence, base version, dirty mask, HLC ms, values for upserts. */\n Push: 5,\n /** Key, version and only the backfilled columns of rows the client already holds. */\n Backfill: 6,\n} as const;\nexport type G9ERowBatchOp = (typeof G9ERowBatchOp)[keyof typeof G9ERowBatchOp];\n\n/** Operation of a push row (`G9EPushRowOp`). */\nexport const G9EPushRowOp = {\n Upsert: 1,\n Delete: 2,\n} as const;\nexport type G9EPushRowOp = (typeof G9EPushRowOp)[keyof typeof G9EPushRowOp];\n\n/** Frame body compression (`G9ECompression`). */\nexport const G9ECompression = {\n None: 0,\n Brotli: 1,\n} as const;\nexport type G9ECompression = (typeof G9ECompression)[keyof typeof G9ECompression];\n\n/** Layout constants (`G9RowBatchFormat`). */\nexport const G9RowBatchFormat = {\n /** Row-wise body. */\n Version: 1,\n /** Column-grouped body (ADR-0040). */\n ColumnVersion: 2,\n MaxVersion: 2,\n HeaderSize: 10,\n MaxBodyBytes: 512 * 1024 * 1024,\n /** The largest body any reader decodes: the writer's ceiling plus the column layout's allowance. */\n MaxDecodedBytes: 512 * 1024 * 1024 + 64 * 1024 * 1024,\n} as const;\n\nexport function isRowBatchOp(op: number): op is G9ERowBatchOp {\n return op >= 1 && op <= 6;\n}\n\n/** True for ops whose rows carry column values. */\nexport function opHasValues(op: number): boolean {\n return op === G9ERowBatchOp.Upsert || op === G9ERowBatchOp.Backfill;\n}\n\n/** A malformed frame (the .NET `FormatException`). */\nexport class G9RowBatchFormatError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'G9RowBatchFormatError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport const VARINT_MAX_BYTES = 10;\n\n/** A read position over a byte array. */\nexport interface Cursor {\n pos: number;\n}\n\n/**\n * Reads an unsigned LEB128 varint as a number. Exact up to 2^53; beyond that the nearest double (callers that need\n * exactness use {@link readVarintLong}). Throws on a truncated or over-long varint.\n */\nexport function readVarint(bytes: Uint8Array, cursor: Cursor, end: number = bytes.length): number {\n let result = 0;\n let multiplier = 1;\n let shift = 0;\n let pos = cursor.pos;\n for (;;) {\n if (pos >= end) throw new G9RowBatchFormatError('Truncated varint.');\n const b = bytes[pos++] as number;\n result += (b & 0x7f) * multiplier;\n if ((b & 0x80) === 0) {\n cursor.pos = pos;\n return result;\n }\n shift += 7;\n if (shift > 63) throw new G9RowBatchFormatError('Varint is too long.');\n multiplier *= 128;\n }\n}\n\n/** Reads an unsigned LEB128 varint exactly, as the bits of an unsigned 64-bit value. */\nexport function readVarintLong(bytes: Uint8Array, cursor: Cursor, end: number = bytes.length): G9Long {\n let lo = 0;\n let hi = 0;\n let shift = 0;\n let pos = cursor.pos;\n for (;;) {\n if (pos >= end) throw new G9RowBatchFormatError('Truncated varint.');\n const b = bytes[pos++] as number;\n const bits = b & 0x7f;\n if (shift < 28) {\n lo |= bits << shift;\n } else if (shift === 28) {\n lo |= (bits & 0x0f) << 28;\n hi |= bits >>> 4;\n } else {\n hi |= bits << (shift - 32);\n }\n if ((b & 0x80) === 0) {\n cursor.pos = pos;\n return new G9Long(hi, lo);\n }\n shift += 7;\n if (shift > 63) throw new G9RowBatchFormatError('Varint is too long.');\n }\n}\n\n/** A varint that must fit an int32 (a length, a count, an id). */\nexport function readVarintInt32(bytes: Uint8Array, cursor: Cursor, end: number = bytes.length): number {\n const value = readVarint(bytes, cursor, end);\n if (value > 2147483647) throw new G9RowBatchFormatError('Varint is out of range.');\n return value;\n}\n\n/** Skips a varint and returns its length in bytes. */\nexport function varintLength(bytes: Uint8Array, position: number, end: number = bytes.length): number {\n let pos = position;\n let shift = 0;\n for (;;) {\n if (pos >= end) throw new G9RowBatchFormatError('Truncated varint.');\n const b = bytes[pos++] as number;\n if ((b & 0x80) === 0) return pos - position;\n shift += 7;\n if (shift > 63) throw new G9RowBatchFormatError('Varint is too long.');\n }\n}\n\n/** Zig-zag of a signed 64-bit value (`(v << 1) ^ (v >> 63)`), as unsigned bits. */\nexport function zigZag(value: G9Long): G9Long {\n return value.shiftLeft(1).xor(value.shiftRight(63));\n}\n\n/** Inverse zig-zag (`(long)(v >> 1) ^ -(long)(v & 1)`). */\nexport function unZigZag(value: G9Long): G9Long {\n const shifted = value.shiftRightUnsigned(1);\n return (value.lo & 1) === 0 ? shifted : shifted.xor(G9Long.MINUS_ONE);\n}\n\n/** Reads a zig-zag varint as a signed number (exact within ±2^53). */\nexport function readZigZagNumber(bytes: Uint8Array, cursor: Cursor, end?: number): number {\n const start = cursor.pos;\n const raw = readVarint(bytes, cursor, end);\n if (raw <= 9007199254740991) return raw % 2 === 0 ? raw / 2 : -(raw + 1) / 2;\n cursor.pos = start;\n return unZigZag(readVarintLong(bytes, cursor, end)).toNumber();\n}\n\n/** Reads a zig-zag varint exactly. */\nexport function readZigZagLong(bytes: Uint8Array, cursor: Cursor, end?: number): G9Long {\n return unZigZag(readVarintLong(bytes, cursor, end));\n}\n\nexport function readInt32LE(bytes: Uint8Array, offset: number): number {\n return (bytes[offset] as number) | ((bytes[offset + 1] as number) << 8) | ((bytes[offset + 2] as number) << 16) | ((bytes[offset + 3] as number) << 24);\n}\n\nexport function writeInt32LE(bytes: Uint8Array, offset: number, value: number): void {\n bytes[offset] = value & 0xff;\n bytes[offset + 1] = (value >>> 8) & 0xff;\n bytes[offset + 2] = (value >>> 16) & 0xff;\n bytes[offset + 3] = (value >>> 24) & 0xff;\n}\n"]}
|