File restore optimization - using snapshot timestamp and file paths (#28546)

* Use snapshot timestamp, remove request for paths at version

* Add timestamp to core Snapshot object

* Avoid mutating function argument

* Explain assumption about editable files

* snapshot.toRaw() in getContentAtVersion

* fix project-history acceptance test

* fix history_v1 test

* fix web tests

* Include the snapshot timestamp in stored chunks

---------

Co-authored-by: Eric Mc Sween <5454374+emcsween@users.noreply.github.com>
GitOrigin-RevId: 376a53e1f927cb56544e6782b47d80345655038c
This commit is contained in:
Domagoj Kriskovic
2025-09-24 08:06:02 +00:00
committed by Copybot
co-authored by Eric Mc Sween
parent 46715191e3
commit 005eba7502
9 changed files with 177 additions and 74 deletions
@@ -28,6 +28,7 @@ const withTmpDir = require('./with_tmp_dir')
const StreamSizeLimit = require('./stream_size_limit')
const { getProjectBlobsBatch } = require('../../storage/lib/blob_store')
const assert = require('../../storage/lib/assert')
const { getChunkMetadataForVersion } = require('../../storage/lib/chunk_store')
const pipeline = promisify(Stream.pipeline)
@@ -396,7 +397,28 @@ async function getSnapshotAtVersion(projectId, version) {
chunk.getChanges(),
chunk.getEndVersion() - version
)
snapshot.applyAll(changes)
if (changes.length > 0) {
snapshot.applyAll(changes)
} else {
// There are no changes in this chunk; we need to look at the previous chunk
// to get the snapshot's timestamp
let chunkMetadata
try {
chunkMetadata = await getChunkMetadataForVersion(projectId, version)
} catch (err) {
if (err instanceof Chunk.VersionNotFoundError) {
// The snapshot is the first snapshot of the first chunk, so we can't
// find a timestamp. This shouldn't happen often. Ignore the error and
// leave the timestamp empty.
} else {
throw err
}
}
snapshot.setTimestamp(chunkMetadata.endTimestamp)
}
return snapshot
}
@@ -108,6 +108,7 @@ describe('persistChanges', function () {
content: '',
},
},
timestamp: thirdChange.getTimestamp().toISOString(),
})
const history = new History(snapshot, [thirdChange])
const currentChunk = new Chunk(history, 2)