in src/data/source.ts [114:161]
async function joinData(allData: UrlFetchedSource[]): Promise<AllPings> {
const totalPings = allData.reduce((sum, d) => sum + d.data.crashid.length, 0);
const pings = emptyPings(
k => new IStringBuilder(totalPings, SIZE_HINTS[k]),
() => new Array(totalPings),
) as Pings<IStringBuilder<string>, IStringBuilder<string | null>>;
// Give the UI a chance to show status changes periodically.
const showStatusChanges = () => new Promise(resolve => setTimeout(resolve, 0));
let offset = 0;
for (const { source, data } of allData) {
source.setStatus({ message: "merging" });
await showStatusChanges();
// Populate the return data.
for (const [field, desc] of pingFields()) {
// Change indices as necessary.
if (desc.type === PingFieldType.IndexedString) {
const f = field as IndexedStringPingField;
pings[f].addData(offset, data[f] as any);
} else {
const src = data[field] as any[];
const dest = pings[field] as any[];
for (let i = 0; i < src.length; i++) {
dest[offset + i] = src[i];
}
}
}
offset += data.crashid.length;
source.setStatus({ success: true, message: `loaded ${data.crashid.length} pings` });
}
await showStatusChanges();
// Build the IStringBuilders
for (const [field, _] of pingFields().filter(([_, d]) => d.type === PingFieldType.IndexedString)) {
const f = field as IndexedStringPingField;
(pings as any)[f] = pings[f].build();
}
// XXX We don't currently use the minidump hashes, so clear them out to save memory.
// They take up enough memory that we might consider dynamically fetching
// them or truncating them.
(pings.minidump_sha256_hash as any) = [];
return pings as any;
}