From d038fbbc1a6a0df579df6dedd3d18ff48a5c8229 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Thu, 1 Oct 2026 10:41:29 +0000 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=20Bolt:=20Optimize=20pin=20lookups=20?= =?UTF-8?q?to=20O(1)=20in=20territory=20workspace?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaced array find operations with a memoized Map for O(1) lookups in `routeStops` and `selectedPin`. `routeStops` previously had an O(N*M) time complexity loop where `Array.map` contained an `Array.find` inside a React useMemo hook, which could block the main thread. This change reduces re-renders and computation time from O(N*M) to O(N+M) for route stops. Co-authored-by: brycejohnson1417 <257422776+brycejohnson1417@users.noreply.github.com> --- .jules/bolt.md | 3 +++ components/territory/territory-workspace.tsx | 13 ++++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 .jules/bolt.md diff --git a/.jules/bolt.md b/.jules/bolt.md new file mode 100644 index 0000000..470eab8 --- /dev/null +++ b/.jules/bolt.md @@ -0,0 +1,3 @@ +## 2024-10-01 - O(N*M) Lookup Optimization +**Learning:** Found O(N*M) time complexity loop where `Array.map` contained an `Array.find` inside a React useMemo hook (`routeStopIds.map((id) => pins.find(...))`). When replacing array lookups with memoized Maps (`useMemo`) in React components, do not use the memoized Map within imperative external bindings or global test hooks (e.g., `window.__TEST_HOOKS`, `window.__MAP_APP_TEST`) initialized outside the React render cycle, as this can introduce stale closures. Retain the original array lookups (e.g., `array.find()`) for those specific external bindings. +**Action:** Replace `Array.map` with `Array.find` using a `Map` created via `useMemo` for O(1) lookups in the component, but retain `pins.find` in `window.__MAP_APP_TEST`. diff --git a/components/territory/territory-workspace.tsx b/components/territory/territory-workspace.tsx index 6d2ff49..259abd4 100644 --- a/components/territory/territory-workspace.tsx +++ b/components/territory/territory-workspace.tsx @@ -570,13 +570,20 @@ export function TerritoryWorkspace({ orgSlug, initialDashboard, territoryConfig const mobileViewAutoSwitchedRef = useRef(initialPreferListView); const pins = data.pins; - const selectedPin = useMemo(() => pins.find((pin) => pin.id === selectedId) ?? null, [pins, selectedId]); + const pinsById = useMemo(() => { + const map = new Map(); + for (const pin of pins) { + map.set(pin.id, pin); + } + return map; + }, [pins]); + const selectedPin = useMemo(() => (selectedId ? pinsById.get(selectedId) ?? null : null), [pinsById, selectedId]); const routeStops = useMemo( () => routePlanningEnabled - ? routeStopIds.map((id) => pins.find((pin) => pin.id === id)).filter((pin): pin is TerritoryAccountPin => Boolean(pin)) + ? routeStopIds.map((id) => pinsById.get(id)).filter((pin): pin is TerritoryAccountPin => Boolean(pin)) : [], - [pins, routePlanningEnabled, routeStopIds], + [pinsById, routePlanningEnabled, routeStopIds], ); const mappablePinCount = useMemo(() => pins.filter(hasUsableCoordinates).length, [pins]); const activeFilterCount = Object.values(filters).filter(Boolean).length;