Repository navigation
Conversation
…porter When a component is imported with its dependency graph, the importer only needs to know whether a version has flattened edges. It called getFlattenedEdges(), which parses the edges JSON and builds a ComponentID for each end of each edge, to read the length of the result. Version.hasFlattenedEdges() now answers from the first bytes of the Source, with the same fallbacks as getFlattenedEdges(), and the three importer sites use it. The parsing was 2.8 s of the 16 s of CPU of a 272-component lane import; the import went from 32.6 s to 28.6 s, and from a local bare scope from 13.8 s to 11.0 s.
4d71709 to
073f186
Compare
PR Summary by QodoAvoid parsing flattened edges during dependency-graph imports
AI Description
Diagram
High-Level Assessment
Files changed (3)
|
Code Review by Qodo
1. Corrupt edge data passes import unnoticed
|
The flattened edges of every imported version were parsed only to test whether they exist.
Current behavior
preferDependencyGraph, the default ofbit importandbit lane import), the importer does not fetch its flattened dependencies:multipleCompsDefsToVersionDeps,bitIdsToVersionDepsand the missing-dependencies check inimportManyonly need to know whether the version has flattened edges.Version.getFlattenedEdges(), which loads the edgesSourceof the version, parses its JSON and builds aComponentIDfor each end of each edge. A version of a component with hundreds of dependencies has thousands of edges (7,604 forteambit.component/snapping). The result is then used only for.length.Versionreads_flattenedEdgessynchronously, and theVersionDependenciesobjects read the flattened dependencies, not the edges.Fix
Version.hasFlattenedEdges(repo)answers the question without parsing: it loads theSourceand checks whether its content is an empty JSON array by reading its first bytes, with the same fallbacks asgetFlattenedEdges()(the edges saved in theVersionobject itself when theSourceis missing, the already loaded edges when present). The three importer sites use it.getFlattenedEdges()is unchanged for the callers that need the edges (the snap graph, the dependents import).Tests
Whole-command time, same machine, dev binary of the worktree, no profiler. Each round runs every build once, in a rotated order, with the builds swapped in place (no recompilation between runs); five rounds. For the bit.cloud import, the time that bit.cloud takes to start each response is subtracted: it is 0.4 s or 11 s at random for every build (the request is the same), and it hides the client time.
bit lane importof a 273-component lane of a private scope from bit.cloud (5,480 objects), client timeENOENTerror of the bit.cloud scope)bit lane importof a 178-component lane from a local bare scope (3,469 objects), no networkThe change removes the same work in every run: the phase from the last object written to
importMany, completed!in the debug log goes from 4.1–4.5 s to 1.4–1.8 s on the bit.cloud import. On master, the slow writes of the fetched objects (#10880, #10884) dominate the import, so the ranges of the first comparison overlap on bit.cloud; with them in place, the ranges do not overlap in either flow. The object stores written by the builds are identical: the same files with the same bytes.The spec in
version.spec.tscheckshasFlattenedEdges()againstgetFlattenedEdges()for aSourcewith edges, an emptySourcewith whitespace, a missingSourcewith and without edges saved in theVersion, and after the edges were loaded. It passes on master as well for the shared cases: the change keeps the behavior and changes only the time.