turbodata 0.1.0
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 +201 -0
- package/NOTICE +27 -0
- package/README.md +215 -0
- package/dist/compression.d.ts +8 -0
- package/dist/compression.d.ts.map +1 -0
- package/dist/compression.js +19 -0
- package/dist/compression.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/io.d.ts +37 -0
- package/dist/io.d.ts.map +1 -0
- package/dist/io.js +174 -0
- package/dist/io.js.map +1 -0
- package/dist/iterators/message_heap.d.ts +17 -0
- package/dist/iterators/message_heap.d.ts.map +1 -0
- package/dist/iterators/message_heap.js +83 -0
- package/dist/iterators/message_heap.js.map +1 -0
- package/dist/iterators/preloaded_topics_group_iterator.d.ts +38 -0
- package/dist/iterators/preloaded_topics_group_iterator.d.ts.map +1 -0
- package/dist/iterators/preloaded_topics_group_iterator.js +109 -0
- package/dist/iterators/preloaded_topics_group_iterator.js.map +1 -0
- package/dist/iterators/topics_group_iterator.d.ts +45 -0
- package/dist/iterators/topics_group_iterator.d.ts.map +1 -0
- package/dist/iterators/topics_group_iterator.js +132 -0
- package/dist/iterators/topics_group_iterator.js.map +1 -0
- package/dist/loaded_bytes.d.ts +12 -0
- package/dist/loaded_bytes.d.ts.map +1 -0
- package/dist/loaded_bytes.js +43 -0
- package/dist/loaded_bytes.js.map +1 -0
- package/dist/msgpack.d.ts +10 -0
- package/dist/msgpack.d.ts.map +1 -0
- package/dist/msgpack.js +44 -0
- package/dist/msgpack.js.map +1 -0
- package/dist/multi_reader.d.ts +56 -0
- package/dist/multi_reader.d.ts.map +1 -0
- package/dist/multi_reader.js +281 -0
- package/dist/multi_reader.js.map +1 -0
- package/dist/read_fetcher.d.ts +9 -0
- package/dist/read_fetcher.d.ts.map +1 -0
- package/dist/read_fetcher.js +59 -0
- package/dist/read_fetcher.js.map +1 -0
- package/dist/read_options.d.ts +40 -0
- package/dist/read_options.d.ts.map +1 -0
- package/dist/read_options.js +16 -0
- package/dist/read_options.js.map +1 -0
- package/dist/read_planner.d.ts +37 -0
- package/dist/read_planner.d.ts.map +1 -0
- package/dist/read_planner.js +110 -0
- package/dist/read_planner.js.map +1 -0
- package/dist/read_source.d.ts +19 -0
- package/dist/read_source.d.ts.map +1 -0
- package/dist/read_source.js +15 -0
- package/dist/read_source.js.map +1 -0
- package/dist/read_strategy.d.ts +52 -0
- package/dist/read_strategy.d.ts.map +1 -0
- package/dist/read_strategy.js +70 -0
- package/dist/read_strategy.js.map +1 -0
- package/dist/reader.d.ts +209 -0
- package/dist/reader.d.ts.map +1 -0
- package/dist/reader.js +649 -0
- package/dist/reader.js.map +1 -0
- package/dist/sample.d.ts +41 -0
- package/dist/sample.d.ts.map +1 -0
- package/dist/sample.js +528 -0
- package/dist/sample.js.map +1 -0
- package/dist/sort_and_filter.d.ts +25 -0
- package/dist/sort_and_filter.d.ts.map +1 -0
- package/dist/sort_and_filter.js +126 -0
- package/dist/sort_and_filter.js.map +1 -0
- package/dist/sources/blob.d.ts +8 -0
- package/dist/sources/blob.d.ts.map +1 -0
- package/dist/sources/blob.js +38 -0
- package/dist/sources/blob.js.map +1 -0
- package/dist/sources/http.d.ts +17 -0
- package/dist/sources/http.d.ts.map +1 -0
- package/dist/sources/http.js +90 -0
- package/dist/sources/http.js.map +1 -0
- package/dist/types.d.ts +75 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +29 -0
- package/dist/types.js.map +1 -0
- package/package.json +61 -0
- package/src/compression.ts +28 -0
- package/src/index.ts +70 -0
- package/src/io.ts +214 -0
- package/src/iterators/message_heap.ts +104 -0
- package/src/iterators/preloaded_topics_group_iterator.ts +143 -0
- package/src/iterators/topics_group_iterator.ts +180 -0
- package/src/loaded_bytes.ts +61 -0
- package/src/msgpack.ts +46 -0
- package/src/multi_reader.ts +337 -0
- package/src/read_fetcher.ts +74 -0
- package/src/read_options.ts +58 -0
- package/src/read_planner.ts +153 -0
- package/src/read_source.ts +33 -0
- package/src/read_strategy.ts +111 -0
- package/src/reader.ts +910 -0
- package/src/sample.ts +715 -0
- package/src/sort_and_filter.ts +167 -0
- package/src/sources/blob.ts +52 -0
- package/src/sources/http.ts +121 -0
- package/src/types.ts +110 -0
package/dist/sample.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { Decompressor } from "./compression.js";
|
|
2
|
+
import type { ReadSource } from "./read_source.js";
|
|
3
|
+
import type { ReadStrategy } from "./read_strategy.js";
|
|
4
|
+
import { type Summary } from "./types.js";
|
|
5
|
+
/** One engine-level query: floor message of `topic` at each `timestamps[j]`. */
|
|
6
|
+
export interface SampleSpec {
|
|
7
|
+
topic: string;
|
|
8
|
+
/** Assumed strictly increasing (the Reader validates this). */
|
|
9
|
+
timestamps: bigint[];
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* One coded video frame surfaced in a SampleHit's GOP prefix or incremental
|
|
13
|
+
* tail. Structurally identical to the public turbodata Frame.
|
|
14
|
+
*/
|
|
15
|
+
export interface SampleFrame {
|
|
16
|
+
timestamp: bigint;
|
|
17
|
+
isKeyFrame: boolean;
|
|
18
|
+
data: Uint8Array;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* One engine-level result. `found` is false when no message with ts <= the
|
|
22
|
+
* requested timestamp exists for the topic. `data` is an owned copy.
|
|
23
|
+
*
|
|
24
|
+
* For video-decodable video topics, `data` stays empty and the frame bytes
|
|
25
|
+
* live in `frames` (target = last element); `isVideo` is true and
|
|
26
|
+
* `resetDecoder` flags GOP boundaries. See the public SampleResult contract.
|
|
27
|
+
*/
|
|
28
|
+
export interface SampleHit {
|
|
29
|
+
found: boolean;
|
|
30
|
+
timestamp: bigint;
|
|
31
|
+
data: Uint8Array;
|
|
32
|
+
isVideo: boolean;
|
|
33
|
+
frames: SampleFrame[];
|
|
34
|
+
resetDecoder: boolean;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Resolve floor messages for the given specs. Returns hits shaped like the
|
|
38
|
+
* input: out[i][j] corresponds to specs[i].timestamps[j].
|
|
39
|
+
*/
|
|
40
|
+
export declare function sampleMessages(rs: ReadSource, summary: Summary, specs: SampleSpec[], strategy: ReadStrategy, decompress: Decompressor, videoDecodable?: boolean): Promise<SampleHit[][]>;
|
|
41
|
+
//# sourceMappingURL=sample.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sample.d.ts","sourceRoot":"","sources":["../src/sample.ts"],"names":[],"mappings":"AAiCA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAKrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAIL,KAAK,OAAO,EAEb,MAAM,YAAY,CAAC;AAEpB,gFAAgF;AAChF,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,+DAA+D;IAC/D,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;IACpB,IAAI,EAAE,UAAU,CAAC;CAClB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,UAAU,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,YAAY,EAAE,OAAO,CAAC;CACvB;AAwDD;;;GAGG;AACH,wBAAsB,cAAc,CAClC,EAAE,EAAE,UAAU,EACd,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,UAAU,EAAE,EACnB,QAAQ,EAAE,YAAY,EACtB,UAAU,EAAE,YAAY,EACxB,cAAc,UAAQ,GACrB,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAmHxB"}
|
package/dist/sample.js
ADDED
|
@@ -0,0 +1,528 @@
|
|
|
1
|
+
// Copyright 2026 Wanjia He
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
import { BinaryReader, readIndexChunk } from "./io.js";
|
|
15
|
+
import { LoadedBytes } from "./loaded_bytes.js";
|
|
16
|
+
import { fetchAll } from "./read_fetcher.js";
|
|
17
|
+
import { plan } from "./read_planner.js";
|
|
18
|
+
import { META_KEY_COMPRESSED, META_KEY_VIDEO, } from "./types.js";
|
|
19
|
+
const EMPTY = new Uint8Array(0);
|
|
20
|
+
/** Compose the (group, chunk) cache key. */
|
|
21
|
+
function chunkKey(group, chunk) {
|
|
22
|
+
return `${group},${chunk}`;
|
|
23
|
+
}
|
|
24
|
+
function cmpBigint(a, b) {
|
|
25
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Resolve floor messages for the given specs. Returns hits shaped like the
|
|
29
|
+
* input: out[i][j] corresponds to specs[i].timestamps[j].
|
|
30
|
+
*/
|
|
31
|
+
export async function sampleMessages(rs, summary, specs, strategy, decompress, videoDecodable = false) {
|
|
32
|
+
if (specs.length === 0) {
|
|
33
|
+
return [];
|
|
34
|
+
}
|
|
35
|
+
const states = specs.map((spec) => {
|
|
36
|
+
const qs = {
|
|
37
|
+
spec,
|
|
38
|
+
groupIdx: 0,
|
|
39
|
+
topicId: 0,
|
|
40
|
+
isCompressed: false,
|
|
41
|
+
isVideo: false,
|
|
42
|
+
results: spec.timestamps.map(() => ({
|
|
43
|
+
found: false,
|
|
44
|
+
timestamp: 0n,
|
|
45
|
+
data: EMPTY,
|
|
46
|
+
isVideo: false,
|
|
47
|
+
frames: [],
|
|
48
|
+
resetDecoder: false,
|
|
49
|
+
})),
|
|
50
|
+
pending: [],
|
|
51
|
+
resolved: [],
|
|
52
|
+
};
|
|
53
|
+
resolveTopic(qs, summary, videoDecodable);
|
|
54
|
+
return qs;
|
|
55
|
+
});
|
|
56
|
+
// Assign initial candidates: per query, walk the strictly-increasing
|
|
57
|
+
// timestamps alongside the group's IndexChunkInfoList with one forward
|
|
58
|
+
// cursor. The candidate is the chunk with the largest StartTimestamp <= T.
|
|
59
|
+
for (const qs of states) {
|
|
60
|
+
const chunks = summary.topicsInfos[qs.groupIdx].indexChunkInfoList;
|
|
61
|
+
if (chunks.length === 0) {
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
let c = -1;
|
|
65
|
+
for (let t = 0; t < qs.spec.timestamps.length; t++) {
|
|
66
|
+
const T = qs.spec.timestamps[t];
|
|
67
|
+
while (c + 1 < chunks.length && chunks[c + 1].startTimestamp <= T) {
|
|
68
|
+
c++;
|
|
69
|
+
}
|
|
70
|
+
if (c < 0) {
|
|
71
|
+
continue; // T precedes every chunk; results[t].found stays false.
|
|
72
|
+
}
|
|
73
|
+
qs.pending.push({ tIdx: t, chunkIdx: c });
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
const cache = new Map();
|
|
77
|
+
// ---- Phase A ----
|
|
78
|
+
while (states.some((qs) => qs.pending.length > 0)) {
|
|
79
|
+
const needs = gatherChunkNeeds(summary, states, cache);
|
|
80
|
+
if (needs.length > 0) {
|
|
81
|
+
await fetchAndDecodeIndexChunks(rs, strategy, decompress, needs, cache);
|
|
82
|
+
}
|
|
83
|
+
let anyProgress = false;
|
|
84
|
+
for (const qs of states) {
|
|
85
|
+
if (qs.pending.length === 0) {
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
const still = [];
|
|
89
|
+
let i = 0;
|
|
90
|
+
while (i < qs.pending.length) {
|
|
91
|
+
// Group the contiguous run of pending items sharing one candidate chunk.
|
|
92
|
+
let j = i;
|
|
93
|
+
while (j < qs.pending.length &&
|
|
94
|
+
qs.pending[j].chunkIdx === qs.pending[i].chunkIdx) {
|
|
95
|
+
j++;
|
|
96
|
+
}
|
|
97
|
+
const c = qs.pending[i].chunkIdx;
|
|
98
|
+
const cc = cache.get(chunkKey(qs.groupIdx, c));
|
|
99
|
+
if (cc === undefined) {
|
|
100
|
+
for (let k = i; k < j; k++) {
|
|
101
|
+
still.push(qs.pending[k]);
|
|
102
|
+
}
|
|
103
|
+
i = j;
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
anyProgress = true;
|
|
107
|
+
const fallback = resolveItemsInChunk(qs, c, cc, qs.pending.slice(i, j));
|
|
108
|
+
for (const f of fallback) {
|
|
109
|
+
still.push(f);
|
|
110
|
+
}
|
|
111
|
+
i = j;
|
|
112
|
+
}
|
|
113
|
+
qs.pending = still;
|
|
114
|
+
}
|
|
115
|
+
if (!anyProgress && states.some((qs) => qs.pending.length > 0)) {
|
|
116
|
+
// gatherChunkNeeds should always surface a fetchable chunk for any
|
|
117
|
+
// pending item; reaching here would indicate an internal bug.
|
|
118
|
+
throw new Error("sample: phase A made no progress with pending items remaining");
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// ---- Phase B ----
|
|
122
|
+
await runPhaseB(rs, strategy, decompress, states, cache);
|
|
123
|
+
// Mark every result of a video query (including not-found ones) so callers
|
|
124
|
+
// can branch on isVideo. Mirrors the py/go engine's collect step.
|
|
125
|
+
for (const qs of states) {
|
|
126
|
+
if (qs.isVideo) {
|
|
127
|
+
for (const h of qs.results) {
|
|
128
|
+
h.isVideo = true;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return states.map((qs) => qs.results);
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Locate the topic's group index, topic id, compression flag, and (when video
|
|
136
|
+
* decoding is requested) video flag in the summary. Assumes the caller
|
|
137
|
+
* validated that the topic exists.
|
|
138
|
+
*/
|
|
139
|
+
function resolveTopic(qs, summary, videoDecodable) {
|
|
140
|
+
for (let gi = 0; gi < summary.topicsInfos.length; gi++) {
|
|
141
|
+
const ti = summary.topicsInfos[gi];
|
|
142
|
+
for (const tm of ti.topicMetadatas) {
|
|
143
|
+
if (tm.name === qs.spec.topic) {
|
|
144
|
+
qs.groupIdx = gi;
|
|
145
|
+
qs.topicId = tm.id;
|
|
146
|
+
qs.isCompressed =
|
|
147
|
+
ti.topicMetadatas[0].metadata.get(META_KEY_COMPRESSED) === true;
|
|
148
|
+
// Video decoding is opt-in. Without it, a video topic is sampled like
|
|
149
|
+
// any other topic (its floor frame in `data`).
|
|
150
|
+
qs.isVideo =
|
|
151
|
+
videoDecodable &&
|
|
152
|
+
ti.topicMetadatas[0].metadata.get(META_KEY_VIDEO) === true;
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
/** Returns the not-yet-cached candidate chunks, sorted by file offset. */
|
|
159
|
+
function gatherChunkNeeds(summary, states, cache) {
|
|
160
|
+
const seen = new Set();
|
|
161
|
+
const out = [];
|
|
162
|
+
for (const qs of states) {
|
|
163
|
+
for (const p of qs.pending) {
|
|
164
|
+
const key = chunkKey(qs.groupIdx, p.chunkIdx);
|
|
165
|
+
if (cache.has(key) || seen.has(key)) {
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
seen.add(key);
|
|
169
|
+
const ti = summary.topicsInfos[qs.groupIdx];
|
|
170
|
+
const list = ti.indexChunkInfoList;
|
|
171
|
+
const info = list[p.chunkIdx];
|
|
172
|
+
// The on-disk length of index chunk c: the gap to the next chunk's
|
|
173
|
+
// offset, or (for the last chunk) the group's total index length closes
|
|
174
|
+
// it. Mirrors go IndexChunkLen / py _gather_chunk_needs.
|
|
175
|
+
let length;
|
|
176
|
+
if (p.chunkIdx < list.length - 1) {
|
|
177
|
+
length = list[p.chunkIdx + 1].offset - info.offset;
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
length = ti.totalLen - info.offset + list[0].offset;
|
|
181
|
+
}
|
|
182
|
+
out.push({ key, offset: info.offset, length });
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
out.sort((a, b) => cmpBigint(a.offset, b.offset));
|
|
186
|
+
return out;
|
|
187
|
+
}
|
|
188
|
+
async function fetchAndDecodeIndexChunks(rs, strategy, decompress, needs, cache) {
|
|
189
|
+
const ranges = needs.map((n) => ({
|
|
190
|
+
offset: n.offset,
|
|
191
|
+
length: n.length,
|
|
192
|
+
}));
|
|
193
|
+
const { ops, locations } = plan(ranges, strategy);
|
|
194
|
+
const bufs = await fetchAll(rs, ops, strategy.maxConcurrency);
|
|
195
|
+
const loaded = new LoadedBytes(ranges, locations, bufs);
|
|
196
|
+
for (const n of needs) {
|
|
197
|
+
const raw = loaded.get(n.offset);
|
|
198
|
+
if (raw === undefined) {
|
|
199
|
+
throw new Error(`sample: missing index chunk at offset ${n.offset}`);
|
|
200
|
+
}
|
|
201
|
+
const ic = readIndexChunk(new BinaryReader(decompress(raw)));
|
|
202
|
+
cache.set(n.key, buildChunkCache(ic));
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Derive per-message lengths for every topic in a decoded index chunk. Flatten
|
|
207
|
+
* all topics' MessageIndexes, sort by offset (== timestamp order within a
|
|
208
|
+
* chunk), take successive offset deltas (UncompressedLen closing the last),
|
|
209
|
+
* then project the lengths back onto each topic's MessageIndexes by index.
|
|
210
|
+
*/
|
|
211
|
+
function buildChunkCache(ic) {
|
|
212
|
+
const items = [];
|
|
213
|
+
for (const ti of ic.topicIndexes) {
|
|
214
|
+
for (let i = 0; i < ti.messageIndexes.length; i++) {
|
|
215
|
+
items.push({
|
|
216
|
+
topicId: ti.id,
|
|
217
|
+
offset: ti.messageIndexes[i].offsetInChunk,
|
|
218
|
+
idx: i,
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
items.sort((a, b) => cmpBigint(a.offset, b.offset));
|
|
223
|
+
const perTopicLens = new Map();
|
|
224
|
+
for (const ti of ic.topicIndexes) {
|
|
225
|
+
perTopicLens.set(ti.id, new Array(ti.messageIndexes.length).fill(0n));
|
|
226
|
+
}
|
|
227
|
+
for (let i = 0; i < items.length - 1; i++) {
|
|
228
|
+
const it = items[i];
|
|
229
|
+
perTopicLens.get(it.topicId)[it.idx] = items[i + 1].offset - it.offset;
|
|
230
|
+
}
|
|
231
|
+
if (items.length > 0) {
|
|
232
|
+
const last = items[items.length - 1];
|
|
233
|
+
perTopicLens.get(last.topicId)[last.idx] = ic.uncompressedLen - last.offset;
|
|
234
|
+
}
|
|
235
|
+
return { ic, perTopicLens };
|
|
236
|
+
}
|
|
237
|
+
function findTopicIndex(ic, topicId) {
|
|
238
|
+
for (const ti of ic.topicIndexes) {
|
|
239
|
+
if (ti.id === topicId) {
|
|
240
|
+
return ti;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
return undefined;
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Resolve a contiguous run of pending items that all share candidate chunk c.
|
|
247
|
+
* Items are in strictly-increasing T order, so a single forward cursor over
|
|
248
|
+
* the topic's MessageIndexes assigns each its floor. Items the cursor can't
|
|
249
|
+
* satisfy (topic absent, or its first message in this chunk is > T) become
|
|
250
|
+
* fallbacks against c-1; at c == 0 they are marked not-found.
|
|
251
|
+
*/
|
|
252
|
+
function resolveItemsInChunk(qs, c, cache, items) {
|
|
253
|
+
const fallback = [];
|
|
254
|
+
const ti = findTopicIndex(cache.ic, qs.topicId);
|
|
255
|
+
if (ti === undefined || ti.messageIndexes.length === 0) {
|
|
256
|
+
for (const p of items) {
|
|
257
|
+
if (c === 0) {
|
|
258
|
+
qs.results[p.tIdx].found = false;
|
|
259
|
+
}
|
|
260
|
+
else {
|
|
261
|
+
fallback.push({ tIdx: p.tIdx, chunkIdx: c - 1 });
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
return fallback;
|
|
265
|
+
}
|
|
266
|
+
const mis = ti.messageIndexes;
|
|
267
|
+
const lens = cache.perTopicLens.get(qs.topicId);
|
|
268
|
+
// For video, kfPos tracks the position within keyFrameIndexes of the most
|
|
269
|
+
// recent key frame index <= k. Items in this run are in increasing T (hence
|
|
270
|
+
// increasing k) order, so the cursor only moves forward.
|
|
271
|
+
let kfPos = 0;
|
|
272
|
+
let k = 0;
|
|
273
|
+
for (const p of items) {
|
|
274
|
+
const T = qs.spec.timestamps[p.tIdx];
|
|
275
|
+
while (k + 1 < mis.length && mis[k + 1].timestamp <= T) {
|
|
276
|
+
k++;
|
|
277
|
+
}
|
|
278
|
+
if (mis[k].timestamp > T) {
|
|
279
|
+
if (c === 0) {
|
|
280
|
+
qs.results[p.tIdx].found = false;
|
|
281
|
+
}
|
|
282
|
+
else {
|
|
283
|
+
fallback.push({ tIdx: p.tIdx, chunkIdx: c - 1 });
|
|
284
|
+
}
|
|
285
|
+
continue;
|
|
286
|
+
}
|
|
287
|
+
const item = {
|
|
288
|
+
tIdx: p.tIdx,
|
|
289
|
+
groupIdx: qs.groupIdx,
|
|
290
|
+
chunkIdx: c,
|
|
291
|
+
msgOffInChunk: mis[k].offsetInChunk,
|
|
292
|
+
msgLen: lens[k],
|
|
293
|
+
timestamp: mis[k].timestamp,
|
|
294
|
+
keyframeMsgIdx: 0,
|
|
295
|
+
targetMsgIdx: 0,
|
|
296
|
+
};
|
|
297
|
+
if (qs.isVideo) {
|
|
298
|
+
const kfs = ti.keyFrameIndexes;
|
|
299
|
+
if (kfs.length === 0 || kfs[0] > k) {
|
|
300
|
+
// No anchor key frame for this target in this chunk: violates the
|
|
301
|
+
// writer's GOP-integrity invariant. Treat as not found rather than
|
|
302
|
+
// emit an undecodable single frame.
|
|
303
|
+
qs.results[p.tIdx].found = false;
|
|
304
|
+
continue;
|
|
305
|
+
}
|
|
306
|
+
while (kfPos + 1 < kfs.length && kfs[kfPos + 1] <= k) {
|
|
307
|
+
kfPos++;
|
|
308
|
+
}
|
|
309
|
+
item.keyframeMsgIdx = kfs[kfPos];
|
|
310
|
+
item.targetMsgIdx = k;
|
|
311
|
+
}
|
|
312
|
+
qs.resolved.push(item);
|
|
313
|
+
}
|
|
314
|
+
return fallback;
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Issue every resolved item's data read in one concurrent wave and copy the
|
|
318
|
+
* floor bytes into result slots. Compressed groups register one range per
|
|
319
|
+
* unique chunk (decompressed once, then sliced per message). Uncompressed
|
|
320
|
+
* groups register one range per unique message offset; plan() coalesces
|
|
321
|
+
* neighbors per the strategy.
|
|
322
|
+
*/
|
|
323
|
+
async function runPhaseB(rs, strategy, decompress, states, cache) {
|
|
324
|
+
const seenChunk = new Set();
|
|
325
|
+
// Multiple query timestamps in one spec can floor to the same message;
|
|
326
|
+
// dedup by absolute offset so we don't register (and read) it twice. The
|
|
327
|
+
// offset is globally unique per message, and a given offset always has the
|
|
328
|
+
// same length, so LoadedBytes keying by offset stays consistent.
|
|
329
|
+
const seenMsg = new Set();
|
|
330
|
+
// Video: dedupe per (group, chunk, keyframe). All queries that share a GOP
|
|
331
|
+
// register a single range from the keyframe to the furthest target across
|
|
332
|
+
// those queries; shorter-target queries slice less of the same loaded bytes.
|
|
333
|
+
// Maps the (group, chunk, keyframe) key -> [startInChunk, endInChunkExcl].
|
|
334
|
+
const videoExtents = new Map();
|
|
335
|
+
const ranges = [];
|
|
336
|
+
for (const qs of states) {
|
|
337
|
+
for (const r of qs.resolved) {
|
|
338
|
+
const cc = cache.get(chunkKey(r.groupIdx, r.chunkIdx));
|
|
339
|
+
const ic = cc.ic;
|
|
340
|
+
if (qs.isCompressed) {
|
|
341
|
+
const k = chunkKey(r.groupIdx, r.chunkIdx);
|
|
342
|
+
if (seenChunk.has(k)) {
|
|
343
|
+
continue;
|
|
344
|
+
}
|
|
345
|
+
seenChunk.add(k);
|
|
346
|
+
ranges.push({ offset: ic.chunkOffset, length: ic.chunkLen });
|
|
347
|
+
}
|
|
348
|
+
else if (qs.isVideo) {
|
|
349
|
+
// Video groups are single-topic by writer invariant.
|
|
350
|
+
const ti = ic.topicIndexes[0];
|
|
351
|
+
const mis = ti.messageIndexes;
|
|
352
|
+
const lens = cc.perTopicLens.get(qs.topicId);
|
|
353
|
+
const start = mis[r.keyframeMsgIdx].offsetInChunk;
|
|
354
|
+
const endExcl = mis[r.targetMsgIdx].offsetInChunk + lens[r.targetMsgIdx];
|
|
355
|
+
const vk = `${r.groupIdx},${r.chunkIdx},${r.keyframeMsgIdx}`;
|
|
356
|
+
const ve = videoExtents.get(vk);
|
|
357
|
+
if (ve !== undefined) {
|
|
358
|
+
if (endExcl > ve.endExcl) {
|
|
359
|
+
ve.endExcl = endExcl;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
else {
|
|
363
|
+
videoExtents.set(vk, {
|
|
364
|
+
groupIdx: r.groupIdx,
|
|
365
|
+
chunkIdx: r.chunkIdx,
|
|
366
|
+
start,
|
|
367
|
+
endExcl,
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
else {
|
|
372
|
+
const off = ic.chunkOffset + r.msgOffInChunk;
|
|
373
|
+
if (seenMsg.has(off)) {
|
|
374
|
+
continue;
|
|
375
|
+
}
|
|
376
|
+
seenMsg.add(off);
|
|
377
|
+
ranges.push({ offset: off, length: r.msgLen });
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
for (const ve of videoExtents.values()) {
|
|
382
|
+
const ic = cache.get(chunkKey(ve.groupIdx, ve.chunkIdx)).ic;
|
|
383
|
+
ranges.push({
|
|
384
|
+
offset: ic.chunkOffset + ve.start,
|
|
385
|
+
length: ve.endExcl - ve.start,
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
if (ranges.length === 0) {
|
|
389
|
+
return;
|
|
390
|
+
}
|
|
391
|
+
ranges.sort((a, b) => cmpBigint(a.offset, b.offset));
|
|
392
|
+
const { ops, locations } = plan(ranges, strategy);
|
|
393
|
+
const bufs = await fetchAll(rs, ops, strategy.maxConcurrency);
|
|
394
|
+
const loaded = new LoadedBytes(ranges, locations, bufs);
|
|
395
|
+
// Compressed: group resolved items by chunk so each chunk decompresses once.
|
|
396
|
+
const byChunk = new Map();
|
|
397
|
+
for (const qs of states) {
|
|
398
|
+
if (!qs.isCompressed) {
|
|
399
|
+
continue;
|
|
400
|
+
}
|
|
401
|
+
for (const r of qs.resolved) {
|
|
402
|
+
const k = chunkKey(r.groupIdx, r.chunkIdx);
|
|
403
|
+
let arr = byChunk.get(k);
|
|
404
|
+
if (arr === undefined) {
|
|
405
|
+
arr = [];
|
|
406
|
+
byChunk.set(k, arr);
|
|
407
|
+
}
|
|
408
|
+
arr.push({ qs, r });
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
for (const [k, group] of byChunk) {
|
|
412
|
+
const ic = cache.get(k).ic;
|
|
413
|
+
const compressed = loaded.get(ic.chunkOffset);
|
|
414
|
+
const decompressed = decompress(compressed);
|
|
415
|
+
for (const { qs, r } of group) {
|
|
416
|
+
const start = Number(r.msgOffInChunk);
|
|
417
|
+
const end = start + Number(r.msgLen);
|
|
418
|
+
// .slice copies, so the result owns its bytes.
|
|
419
|
+
qs.results[r.tIdx] = {
|
|
420
|
+
found: true,
|
|
421
|
+
timestamp: r.timestamp,
|
|
422
|
+
data: decompressed.slice(start, end),
|
|
423
|
+
isVideo: false,
|
|
424
|
+
frames: [],
|
|
425
|
+
resetDecoder: false,
|
|
426
|
+
};
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
// Uncompressed non-video: per-message copy.
|
|
430
|
+
for (const qs of states) {
|
|
431
|
+
if (qs.isCompressed || qs.isVideo) {
|
|
432
|
+
continue;
|
|
433
|
+
}
|
|
434
|
+
for (const r of qs.resolved) {
|
|
435
|
+
const ic = cache.get(chunkKey(r.groupIdx, r.chunkIdx)).ic;
|
|
436
|
+
const raw = loaded.get(ic.chunkOffset + r.msgOffInChunk);
|
|
437
|
+
qs.results[r.tIdx] = {
|
|
438
|
+
found: true,
|
|
439
|
+
timestamp: r.timestamp,
|
|
440
|
+
data: new Uint8Array(raw), // copy: detach from the shared op buffer.
|
|
441
|
+
isVideo: false,
|
|
442
|
+
frames: [],
|
|
443
|
+
resetDecoder: false,
|
|
444
|
+
};
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
// Video: incremental frames + resetDecoder.
|
|
448
|
+
for (const qs of states) {
|
|
449
|
+
if (!qs.isVideo) {
|
|
450
|
+
continue;
|
|
451
|
+
}
|
|
452
|
+
materializeVideo(qs, cache, loaded);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
/**
|
|
456
|
+
* Walk one query's resolved items in target-timestamp order and emit
|
|
457
|
+
* incremental frames + resetDecoder per the public SampleResult contract.
|
|
458
|
+
* Mirrors py _materialize_video.
|
|
459
|
+
*/
|
|
460
|
+
function materializeVideo(qs, cache, loaded) {
|
|
461
|
+
if (qs.resolved.length === 0) {
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
464
|
+
// Resolved items can arrive out of tIdx order if Phase A required fallbacks;
|
|
465
|
+
// sort so the row's processing order matches the caller's.
|
|
466
|
+
const resolved = [...qs.resolved].sort((a, b) => a.tIdx - b.tIdx);
|
|
467
|
+
// Decoder-state continuity is per-row, scoped to a single GOP (= same chunk
|
|
468
|
+
// + same keyframeMsgIdx).
|
|
469
|
+
let havePrev = false;
|
|
470
|
+
let prevGroupIdx = 0;
|
|
471
|
+
let prevChunkIdx = 0;
|
|
472
|
+
let prevKeyframeIdx = 0;
|
|
473
|
+
let prevTargetMsgIdx = 0;
|
|
474
|
+
for (const r of resolved) {
|
|
475
|
+
const cc = cache.get(chunkKey(r.groupIdx, r.chunkIdx));
|
|
476
|
+
const ti = cc.ic.topicIndexes[0];
|
|
477
|
+
const mis = ti.messageIndexes;
|
|
478
|
+
const lens = cc.perTopicLens.get(qs.topicId);
|
|
479
|
+
const sameGop = havePrev &&
|
|
480
|
+
prevGroupIdx === r.groupIdx &&
|
|
481
|
+
prevChunkIdx === r.chunkIdx &&
|
|
482
|
+
prevKeyframeIdx === r.keyframeMsgIdx;
|
|
483
|
+
let startIdx;
|
|
484
|
+
let reset;
|
|
485
|
+
if (!sameGop) {
|
|
486
|
+
startIdx = r.keyframeMsgIdx;
|
|
487
|
+
reset = true;
|
|
488
|
+
}
|
|
489
|
+
else {
|
|
490
|
+
startIdx = prevTargetMsgIdx + 1;
|
|
491
|
+
reset = false;
|
|
492
|
+
}
|
|
493
|
+
// The Phase B range starts at the GOP's keyframe in this chunk and is long
|
|
494
|
+
// enough to cover the furthest target across queries in this GOP.
|
|
495
|
+
const raw = loaded.get(cc.ic.chunkOffset + mis[r.keyframeMsgIdx].offsetInChunk);
|
|
496
|
+
const baseInChunk = mis[r.keyframeMsgIdx].offsetInChunk;
|
|
497
|
+
const frames = [];
|
|
498
|
+
if (startIdx <= r.targetMsgIdx) {
|
|
499
|
+
for (let i = startIdx; i <= r.targetMsgIdx; i++) {
|
|
500
|
+
const frameStart = Number(mis[i].offsetInChunk - baseInChunk);
|
|
501
|
+
const frameLen = Number(lens[i]);
|
|
502
|
+
frames.push({
|
|
503
|
+
timestamp: mis[i].timestamp,
|
|
504
|
+
// keyframeMsgIdx is the greatest key frame index <= targetMsgIdx, so
|
|
505
|
+
// it is the only key frame in range.
|
|
506
|
+
isKeyFrame: i === r.keyframeMsgIdx,
|
|
507
|
+
data: raw.slice(frameStart, frameStart + frameLen),
|
|
508
|
+
});
|
|
509
|
+
}
|
|
510
|
+
// data stays empty for video; target is the last frame.
|
|
511
|
+
qs.results[r.tIdx].timestamp = frames[frames.length - 1].timestamp;
|
|
512
|
+
}
|
|
513
|
+
else {
|
|
514
|
+
// Same target as the previous in-row result: nothing new to feed.
|
|
515
|
+
qs.results[r.tIdx].timestamp = mis[r.targetMsgIdx].timestamp;
|
|
516
|
+
}
|
|
517
|
+
qs.results[r.tIdx].found = true;
|
|
518
|
+
qs.results[r.tIdx].data = EMPTY;
|
|
519
|
+
qs.results[r.tIdx].frames = frames;
|
|
520
|
+
qs.results[r.tIdx].resetDecoder = reset;
|
|
521
|
+
havePrev = true;
|
|
522
|
+
prevGroupIdx = r.groupIdx;
|
|
523
|
+
prevChunkIdx = r.chunkIdx;
|
|
524
|
+
prevKeyframeIdx = r.keyframeMsgIdx;
|
|
525
|
+
prevTargetMsgIdx = r.targetMsgIdx;
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
//# sourceMappingURL=sample.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sample.js","sourceRoot":"","sources":["../src/sample.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { IndexChunk, TopicIndex } from "./types.js";
|
|
2
|
+
export interface MessageRef {
|
|
3
|
+
timestamp: bigint;
|
|
4
|
+
topicId: number;
|
|
5
|
+
offsetInChunk: bigint;
|
|
6
|
+
}
|
|
7
|
+
export declare function sortAndFilter(topicIndexes: TopicIndex[], totalLen: bigint, topicIds: Set<number>, startTimestamp: bigint, endTimestamp: bigint, videoDecodable?: boolean): {
|
|
8
|
+
msgs: MessageRef[];
|
|
9
|
+
lens: bigint[];
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Timestamp of the latest key frame whose timestamp is <= startTimestamp, or
|
|
13
|
+
* startTimestamp unchanged if no such key frame exists in this chunk. Mirrors
|
|
14
|
+
* py key_frame_start / go keyFrameStart.
|
|
15
|
+
*
|
|
16
|
+
* Video-decodable groups always hold exactly one topic. keyFrameIndexes are
|
|
17
|
+
* ascending positions into that topic's timestamp-ordered messageIndexes.
|
|
18
|
+
*/
|
|
19
|
+
export declare function keyFrameStart(topicIndexes: TopicIndex[], startTimestamp: bigint): bigint;
|
|
20
|
+
/** Convenience: sort+filter directly from a decoded IndexChunk. */
|
|
21
|
+
export declare function sortAndFilterChunk(chunk: IndexChunk, topicIds: Set<number>, startTimestamp: bigint, endTimestamp: bigint): {
|
|
22
|
+
msgs: MessageRef[];
|
|
23
|
+
lens: bigint[];
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=sort_and_filter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sort_and_filter.d.ts","sourceRoot":"","sources":["../src/sort_and_filter.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,UAAU,EAAgB,UAAU,EAAE,MAAM,YAAY,CAAC;AAEvE,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;CACvB;AAOD,wBAAgB,aAAa,CAC3B,YAAY,EAAE,UAAU,EAAE,EAC1B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,EACrB,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,MAAM,EACpB,cAAc,UAAQ,GACrB;IAAE,IAAI,EAAE,UAAU,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,CAgFxC;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,YAAY,EAAE,UAAU,EAAE,EAC1B,cAAc,EAAE,MAAM,GACrB,MAAM,CAcR;AAED,mEAAmE;AACnE,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,EACrB,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,MAAM,GACnB;IAAE,IAAI,EAAE,UAAU,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,CAQxC"}
|