sliftutils 1.4.60 → 1.4.62
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/package.json
CHANGED
package/spec.txt
CHANGED
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
Compact face_frames3
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
When detecting faces in the JavaScript code and the Python code. Let's make it so that we only store the face frames for the top 10 characters. We can show the store the embeddings for all of them, But for the face frames collection only store the top 10 faces. The other ones will just be blank, and that should be fine. Also, let's make sure when we're storing them the max dimension is 128 pixels and the quality is only 80.
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
Then go verify on the other site fixing up the bad data. It should be quite fast because there's so much overlap, but we will find out.
|
|
5
|
+
Create a companion large data storage thing. which updates the data less frequently, Where we reference it with unique IDs so we don't have to merge as much and it doesn't have to be as strict. This should allow our large databases to be merged faster, even though they are pretty fast to merge at the moment, but they probably will get slower if we make them 10 times bigger.
|
|
@@ -658,17 +658,25 @@ export class BulkDatabaseBase<T extends { key: string }> {
|
|
|
658
658
|
// expanded console.group so a merge takes one collapsible block, not a
|
|
659
659
|
// screenful (and never the per-file name dump it used to spew).
|
|
660
660
|
const steps: string[] = [];
|
|
661
|
-
|
|
661
|
+
// Each step records the time spent since the previous step in blue at the front, so callers can
|
|
662
|
+
// just describe what they did and not bother measuring/formatting elapsed times themselves.
|
|
663
|
+
let lastStepMs = mergeStartMs;
|
|
664
|
+
const log = (line: string) => {
|
|
665
|
+
const now = Date.now();
|
|
666
|
+
let lineFormatted = `${blue(formatTime(now - lastStepMs))} ${line}`;
|
|
667
|
+
// DO NOT REMOVE THIS LOG! Obviously, we should be logging as we run, or else we don't get progress. Why would we stop getting progress? Progress is almost more important than showing a summary at the end...
|
|
668
|
+
console.log(lineFormatted);
|
|
669
|
+
steps.push(lineFormatted);
|
|
670
|
+
lastStepMs = now;
|
|
671
|
+
};
|
|
672
|
+
log(`${magenta("read")}: ${inputs.length} input file(s), ${fmtBytes(inTotal)}`);
|
|
662
673
|
|
|
663
674
|
const newNames: string[] = [];
|
|
664
675
|
const mergeResult = await runPlannedMerge({
|
|
665
676
|
sources: readers,
|
|
666
677
|
sourceNames: readerNames,
|
|
667
678
|
collectionName: this.name,
|
|
668
|
-
log
|
|
669
|
-
console.log(line);
|
|
670
|
-
steps.push(line);
|
|
671
|
-
},
|
|
679
|
+
log,
|
|
672
680
|
writeFile: async (data) => {
|
|
673
681
|
const fname = newFileName(timestamp);
|
|
674
682
|
await storage.set(fname, encodeCompressedBlocks(data));
|
|
@@ -688,7 +696,7 @@ export class BulkDatabaseBase<T extends { key: string }> {
|
|
|
688
696
|
|
|
689
697
|
const outputs = await Promise.all(outNames.map(async n => ({ name: n, size: (await storage.getInfo(n).catch(() => undefined))?.size ?? 0 })));
|
|
690
698
|
const outTotal = outputs.reduce((a, f) => a + f.size, 0);
|
|
691
|
-
|
|
699
|
+
log(`${magenta("wrote")}: ${outputs.length} output file(s), ${fmtBytes(outTotal)}${carriedDeletes ? `, ${carriedDeletes} tombstones carried` : ""}`);
|
|
692
700
|
|
|
693
701
|
console.group(`${blue(this.name)} ${magenta("merge")}: ${fmtBytes(inTotal)} → ${fmtBytes(outTotal)} (${inputs.length}→${outputs.length} files) in ${formatTime(Date.now() - mergeStartMs)}`);
|
|
694
702
|
for (const line of steps) console.log(line);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { formatNumber
|
|
2
|
-
import { blue,
|
|
1
|
+
import { formatNumber } from "socket-function/src/formatting/format";
|
|
2
|
+
import { blue, magenta } from "socket-function/src/formatting/logColors";
|
|
3
3
|
import {
|
|
4
4
|
BaseBulkDatabaseReader,
|
|
5
5
|
ColumnIndex,
|
|
@@ -98,8 +98,6 @@ export async function runPlannedMerge(config: {
|
|
|
98
98
|
const log = config.log ?? (line => console.log(`${blue(config.collectionName)} ${line}`));
|
|
99
99
|
|
|
100
100
|
// ─────────────────────────────────────────── Phase 1: plan ───────────────────────────────────────────
|
|
101
|
-
const planStart = Date.now();
|
|
102
|
-
|
|
103
101
|
// Aggregate keyTimes + deleteTimes across all sources (max per key).
|
|
104
102
|
const deleteTime = new Map<string, number>();
|
|
105
103
|
const keyTime = new Map<string, number>();
|
|
@@ -222,8 +220,7 @@ export async function runPlannedMerge(config: {
|
|
|
222
220
|
// Build per-file plans: offsets/types/copy-runs per column.
|
|
223
221
|
const plans = fileKeyRanges.map(range => buildOutputPlan(range, liveKeys, cellsPerKey, allColumns, keyTime));
|
|
224
222
|
|
|
225
|
-
|
|
226
|
-
log(`mapping done — ${formatNumber(liveKeys.length)} live keys, ${plans.length} output file(s), ${formatNumber(carriedDeletes.size)} tombstones carried, in ${red(formatTime(planTime))}`);
|
|
223
|
+
log(`${magenta("plan")}: ${formatNumber(liveKeys.length)} live keys, ${plans.length} output file(s), ${formatNumber(carriedDeletes.size)} tombstones carried`);
|
|
227
224
|
|
|
228
225
|
// ───────────────────────────────────────── Phase 2: execute ──────────────────────────────────────────
|
|
229
226
|
// Group output files into batches that fit within targetBatchBytes so we read inputs once per batch
|
|
@@ -244,17 +241,15 @@ export async function runPlannedMerge(config: {
|
|
|
244
241
|
}
|
|
245
242
|
|
|
246
243
|
const outputs: PlannedMergeOutput[] = [];
|
|
247
|
-
const execStart = Date.now();
|
|
248
244
|
for (let bi = 0; bi < batches.length; bi++) {
|
|
249
245
|
const batch = batches[bi];
|
|
250
246
|
const batchBytes = batch.reduce((a, p) => a + p.estimatedFileBytes, 0);
|
|
251
|
-
log(
|
|
247
|
+
log(`${magenta("batch")} ${bi + 1}/${batches.length}: ${batch.length} output file(s), ~${fmtBytes(batchBytes)} budget`);
|
|
252
248
|
const batchOutputs = await executeBatch(batch, indexesPerSource, config.sources, config.sourceNames, config.writeFile, log);
|
|
253
249
|
outputs.push(...batchOutputs);
|
|
254
250
|
}
|
|
255
|
-
const execTime = Date.now() - execStart;
|
|
256
251
|
const writtenBytes = outputs.reduce((a, o) => a + o.size, 0);
|
|
257
|
-
log(
|
|
252
|
+
log(`${magenta("execute")}: ${outputs.length} file(s), ${fmtBytes(writtenBytes)} written`);
|
|
258
253
|
|
|
259
254
|
return { outputs, carriedDeletes };
|
|
260
255
|
}
|
|
@@ -387,14 +382,12 @@ async function executeBatch(
|
|
|
387
382
|
const outputs: PlannedMergeOutput[] = [];
|
|
388
383
|
for (let fi = 0; fi < plans.length; fi++) {
|
|
389
384
|
const plan = plans[fi];
|
|
390
|
-
const start = Date.now();
|
|
391
385
|
const valueColumns = blobsPerFile[fi].map(b => ({ name: b.name, blob: b.blob }));
|
|
392
386
|
const fileBuf = assemblePlannedFile({ valueColumns, keys: plan.keys, times: plan.times });
|
|
393
387
|
const { name, size } = await writeFile(fileBuf);
|
|
394
|
-
const elapsed = Date.now() - start;
|
|
395
388
|
const sourcesNamed = new Map<string, number>();
|
|
396
389
|
for (const [si, n] of plan.sourceCounts) sourcesNamed.set(sourceNames[si], n);
|
|
397
|
-
log(
|
|
390
|
+
log(`${magenta("output")}: ${formatNumber(plan.keys.length)} rows from ${plan.sourceCounts.size} input(s), ${fmtBytes(size)}`);
|
|
398
391
|
outputs.push({ name, minKey: plan.minKey, maxKey: plan.maxKey, rowCount: plan.keys.length, size, sources: sourcesNamed });
|
|
399
392
|
}
|
|
400
393
|
return outputs;
|