Aggregate Paginated Project Run Records
Problem statement
A project-runs API has already been queried page by page. The flattened responses are provided in pageRecords, in page order and then response order within each page.
Each row contains exactly five strings:
pageNumber: the positive decimal page number.runId: the run's unique identifier.projectId: the project that owns the run.status: one ofSUCCESS,FAILED, orCANCELED.durationMs: a nonnegative decimal duration in milliseconds.
Rows are ordered by increasing page number. A changing paginated data set can repeat the same runId. Process rows from left to right and treat the first occurrence of each runId as authoritative; ignore every later occurrence completely, even when its fields differ.
After deduplication, keep only rows whose status is exactly SUCCESS. For each projectId, compute its number of successful runs and the sum of their durations. Keep projects with at least minSuccessfulRuns successful runs.
Return one row per kept project in the form [projectId, successfulRunCount, totalDurationMs]. Serialize both numeric values as base-10 strings. Sort rows by total duration descending, then successful-run count descending, then project ID in ascending lexicographic order. Return an empty array when no project qualifies.
Function
aggregateProjectRuns(pageRecords: String[][], minSuccessfulRuns: int) → String[][]Examples
Example 1
pageRecords = [["1","r1","alpha","SUCCESS","120"],["1","r2","beta","FAILED","80"],["2","r3","alpha","SUCCESS","30"],["2","r2","beta","SUCCESS","999"],["2","r4","beta","SUCCESS","200"]]minSuccessfulRuns = 1return = [["beta","1","200"],["alpha","2","150"]]The first r2 record is authoritative and has status FAILED, so its later successful duplicate is ignored. Project alpha has two successful runs totaling 150 ms, while beta has one totaling 200 ms. The larger total duration places beta first.
Example 2
pageRecords = [["1","c1","core","SUCCESS","50"],["1","e1","edge","SUCCESS","20"],["2","c2","core","CANCELED","100"],["2","e2","edge","SUCCESS","30"],["3","d1","data","SUCCESS","50"]]minSuccessfulRuns = 2return = [["edge","2","50"]]Only edge reaches the threshold with two successful runs. The canceled core run does not contribute, so core and data each remain below the threshold.
Example 3
pageRecords = [["1","z1","zeta","SUCCESS","40"],["1","z2","zeta","SUCCESS","10"],["1","a1","alpha","SUCCESS","25"],["1","a2","alpha","SUCCESS","25"],["1","b1","beta","SUCCESS","50"]]minSuccessfulRuns = 1return = [["alpha","2","50"],["zeta","2","50"],["beta","1","50"]]All three projects total 50 ms. Projects with two successful runs precede beta, which has one. The remaining tie places alpha before zeta lexicographically.
Constraints
0 <= pageRecords.length <= 200000.- Every row has exactly five strings in the documented order.
pageNumberis a positive decimal integer, and rows are ordered by nondecreasing page number.runIdandprojectIdare non-empty printable ASCII strings of length at most64.statusis exactlySUCCESS,FAILED, orCANCELED.0 <= durationMs <= 10^9.1 <= minSuccessfulRuns <= 200000.- Every project's total successful duration is at most
2 * 10^14and requires 64-bit arithmetic.