perf(mobile): summarize diff review counts in one pass (#17460)

This commit is contained in:
Neil
2026-08-30 23:04:47 -07:00
committed by GitHub
parent 7e5cc79e93
commit 55efba2ac0
3 changed files with 87 additions and 5 deletions
@@ -5,7 +5,9 @@ import type { MobileGitStatusEntry } from '../source-control/mobile-git-status'
import {
buildMobileDiffReviewQueue,
createMobileDiffReviewFileKey,
filterMobileDiffReviewQueue
filterMobileDiffReviewQueue,
summarizeMobileDiffReviewQueue,
type MobileDiffReviewQueueItem
} from './mobile-diff-review-queue'
const emptyReviewState: MobileDiffReviewState = { version: 1, files: {} }
@@ -117,4 +119,61 @@ describe('mobile diff review queue', () => {
'b.ts'
])
})
it('summarizes review counts in one pass without rereading item fields', () => {
const entryCount = 1_000
const reads = { isReviewed: 0, scope: 0, canStage: 0 }
let expectedReviewedCount = 0
let expectedReviewedUnstagedItems = 0
let expectedReviewedUnstagedCount = 0
const queue = Array.from({ length: entryCount }, (_, index) => {
const isReviewed = index % 2 === 0
const scope = index % 3 === 0 ? 'unstaged' : 'staged'
const canStage = index % 5 === 0
if (isReviewed) {
expectedReviewedCount += 1
if (scope === 'unstaged') {
expectedReviewedUnstagedItems += 1
if (canStage) {
expectedReviewedUnstagedCount += 1
}
}
}
const item = {} as MobileDiffReviewQueueItem
Object.defineProperties(item, {
isReviewed: {
enumerable: true,
get: () => {
reads.isReviewed += 1
return isReviewed
}
},
scope: {
enumerable: true,
get: () => {
reads.scope += 1
return scope
}
},
canStage: {
enumerable: true,
get: () => {
reads.canStage += 1
return canStage
}
}
})
return item
})
expect(summarizeMobileDiffReviewQueue(queue)).toEqual({
reviewedCount: expectedReviewedCount,
reviewedUnstagedCount: expectedReviewedUnstagedCount
})
expect(reads).toEqual({
isReviewed: entryCount,
scope: expectedReviewedCount,
canStage: expectedReviewedUnstagedItems
})
})
})
@@ -272,3 +272,25 @@ export function filterMobileDiffReviewQueue(
return [...queue]
}
}
export type MobileDiffReviewQueueSummary = {
reviewedCount: number
reviewedUnstagedCount: number
}
export function summarizeMobileDiffReviewQueue(
queue: readonly MobileDiffReviewQueueItem[]
): MobileDiffReviewQueueSummary {
let reviewedCount = 0
let reviewedUnstagedCount = 0
for (const item of queue) {
if (!item.isReviewed) {
continue
}
reviewedCount += 1
if (item.scope === 'unstaged' && item.canStage) {
reviewedUnstagedCount += 1
}
}
return { reviewedCount, reviewedUnstagedCount }
}
@@ -9,6 +9,7 @@ import {
buildMobileDiffReviewQueue,
filterMobileDiffReviewQueue,
mobileDiffReviewCommentMatchesItem,
summarizeMobileDiffReviewQueue,
type MobileDiffReviewQueueFilter,
type MobileDiffReviewQueueItem
} from './mobile-diff-review-queue'
@@ -133,12 +134,12 @@ export function useMobileDiffReviewController(input: ControllerInput) {
const filteredQueue = useMemo(() => filterMobileDiffReviewQueue(queue, filter), [filter, queue])
const currentItem = filteredQueue[currentIndex] ?? null
const reviewedCount = queue.filter((item) => item.isReviewed).length
const { reviewedCount, reviewedUnstagedCount } = useMemo(
() => summarizeMobileDiffReviewQueue(queue),
[queue]
)
const unsentComments =
screenState.kind === 'ready' ? getUnsentMobileDiffComments(screenState.comments) : []
const reviewedUnstagedCount = queue.filter(
(item) => item.scope === 'unstaged' && item.isReviewed && item.canStage
).length
useEffect(() => {
seededInitialTargetRef.current = false