perf: optimize init() and rebuild performance

- Remove detectAndRepairCorruption from init() hot path — was loading all
  metadata chunks sequentially on startup. Now available via checkHealth()
  and repairIndex() methods.
- Short-circuit warmCache on empty workspace — skip 4-6 wasted storage reads.
- Parallelize MetadataIndex.init() and getGraphIndex() via Promise.all().
- Defer metadata writes during rebuild to batch boundaries (every 5000
  entities) instead of flushing per-entity.
- Skip pre-reads for new entities in transactions — saves 2 storage
  round-trips per add() on cloud storage.
This commit is contained in:
David Snelling 2026-01-31 09:14:51 -08:00
parent cd875294ad
commit 35cb674157
3 changed files with 113 additions and 40 deletions

View file

@ -27,12 +27,15 @@ export class SaveNounMetadataOperation implements Operation {
constructor(
private readonly storage: StorageAdapter,
private readonly id: string,
private readonly metadata: NounMetadata
private readonly metadata: NounMetadata,
private readonly isNew: boolean = false
) {}
async execute(): Promise<RollbackAction> {
// Get existing metadata (for rollback)
const previousMetadata = await this.storage.getNounMetadata(this.id)
// Skip read for new entities — nothing to rollback to (saves 1 storage round-trip)
const previousMetadata = this.isNew
? null
: await this.storage.getNounMetadata(this.id)
// Save new metadata
await this.storage.saveNounMetadata(this.id, this.metadata)
@ -65,12 +68,15 @@ export class SaveNounOperation implements Operation {
constructor(
private readonly storage: StorageAdapter,
private readonly noun: HNSWNoun
private readonly noun: HNSWNoun,
private readonly isNew: boolean = false
) {}
async execute(): Promise<RollbackAction> {
// Get existing noun (for rollback)
const previousNoun = await this.storage.getNoun(this.noun.id)
// Skip read for new entities — nothing to rollback to (saves 1 storage round-trip)
const previousNoun = this.isNew
? null
: await this.storage.getNoun(this.noun.id)
// Save new noun
await this.storage.saveNoun(this.noun)