searchSessionFile function
Future<SessionSearchOutcome>
searchSessionFile(
- FileSystem fs,
- String sessionPath,
- SessionSearchQuery query, {
- Duration timeBudget = sessionSearchTimeBudget,
- int blockBytes = sessionSearchScanBlockBytes,
Searches a whole session file chain — the production path behind the
session_search tool. Streams every segment (rotations included, per
listSessionSegmentPaths) under the query's continuation token and a
wall-clock timeBudget (E4/E5); never loads the file into memory.
Map mode and branch scope pay one extra read-only census pass first
(structure only — see searchRecords): the real pass then keeps its
ordinal table bounded and caps true branch hits with full knowledge.
Implementation
Future<SessionSearchOutcome> searchSessionFile(
FileSystem fs,
String sessionPath,
SessionSearchQuery query, {
Duration timeBudget = sessionSearchTimeBudget,
int blockBytes = sessionSearchScanBlockBytes,
}) async {
final deadline = DateTime.now().add(timeBudget);
final segments = await listSessionSegmentPaths(fs, sessionPath);
final needsCensus =
query.mode == SessionSearchMode.map ||
(query.mode == SessionSearchMode.search &&
query.scope == SessionSearchScope.branch);
var ordinalWanted = const <String>{};
var branchIds = const <String>{};
if (needsCensus) {
final census = _ScanAccumulator(
query,
deadline: deadline,
censusOnly: true,
);
for (final segment in segments) {
await _scanSessionSegment(fs, segment, census, blockBytes: blockBytes);
if (census.stopped) break;
}
ordinalWanted = census._ordinalWanted;
branchIds = census._walkChain(census._activeLeaf);
}
final accumulator = _ScanAccumulator(
query,
deadline: deadline,
ordinalWanted: ordinalWanted,
branchIds: branchIds,
);
for (final segment in segments) {
await _scanSessionSegment(fs, segment, accumulator, blockBytes: blockBytes);
if (accumulator.stopped) break;
}
return accumulator.finish();
}