Skip to content

Commit a99b2b1

Browse files
[repo-assist] perf: index related section lookups (#1416)
🤖 *This is an automated PR from Repo Assist, an AI assistant for this repository.* ## Summary `FindRelatedSections` previously searched every site mapping for each semantic result. This change builds a per-request chapter/heading index once and uses dictionary lookups, reducing the mapping phase from O(results × mappings) to O(mappings + results) while preserving case-insensitive matching and first-match behavior. ## Root cause and rationale Related-section results performed a linear scan of the complete site-mapping collection for every result. As the book mapping grows, that repeated work scales unnecessarily. The local index keeps the existing result and fallback behavior but avoids repeated enumeration. ## Test Status - ✅ `dotnet build EssentialCSharp.Web/EssentialCSharp.Web.csproj --configuration Release --no-restore` - ⚠️ `dotnet test EssentialCSharp.Web.Tests/EssentialCSharp.Web.Tests.csproj --configuration Release --no-restore`: 149 passed, 2 pre-existing external integration failures (`CaptchaService_Verify_Success` and `KnownBreachedPassword_IsDetected`) because their third-party services were unavailable in this environment. - ✅ `git diff --check` No new dependencies were added. > [!WARNING] > <details> > <summary>Firewall blocked 2 domains</summary> > > The following domains were blocked by the firewall during workflow execution: > > - `api.hcaptcha.com` > - `api.pwnedpasswords.com` > > To allow these domains, add them to the `network.allowed` list in your workflow frontmatter: > > ```yaml > network: > allowed: > - defaults > - "api.hcaptcha.com" > - "api.pwnedpasswords.com" > ``` > > See [Network Configuration](https://github.github.com/gh-aw/reference/network/) for more information. > > </details> > Generated by 🌈 Repo Assist, see [workflow run](https://github.com/IntelliTect/EssentialCSharp.Web/actions/runs/36033164072). [Learn more](https://github.com/githubnext/agentics/blob/main/docs/repo-assist.md). > <sub>Comment <em>/repo-assist</em> to run again</sub> > <details> <summary><sub>Add this agentic workflow to your repo</sub></summary> To install this agentic workflow, run ``` gh aw add githubnext/agentics@4bc8419 ``` </details> <!-- gh-aw-agentic-workflow: Repo Assist, engine: copilot, model: gpt-5.6, id: 36033164072, workflow_id: repo-assist, run: https://github.com/IntelliTect/EssentialCSharp.Web/actions/runs/36033164072 --> <!-- gh-aw-workflow-id: repo-assist --> <!-- gh-aw-workflow-call-id: IntelliTect/EssentialCSharp.Web/repo-assist --> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 0b87c76 commit a99b2b1

1 file changed

Lines changed: 16 additions & 3 deletions

File tree

‎EssentialCSharp.Web/Tools/BookSearchTool.cs‎

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -322,16 +322,29 @@ public async Task<string> FindRelatedSections(
322322

323323
List<RelatedSectionMatchTextResult> relatedSections = [];
324324
var seen = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { mapping.RawHeading };
325+
Dictionary<int, Dictionary<string, SiteMapping>> mappingsByChapter = [];
326+
foreach (SiteMapping candidate in _SiteMappingService.SiteMappings)
327+
{
328+
if (!mappingsByChapter.TryGetValue(candidate.ChapterNumber, out Dictionary<string, SiteMapping>? chapterMappings))
329+
{
330+
chapterMappings = new Dictionary<string, SiteMapping>(StringComparer.OrdinalIgnoreCase);
331+
mappingsByChapter[candidate.ChapterNumber] = chapterMappings;
332+
}
333+
334+
chapterMappings.TryAdd(candidate.RawHeading, candidate);
335+
}
336+
325337
foreach (var r in results)
326338
{
327339
string heading = r.Record.Heading ?? "";
328340
if (!seen.Add(heading)) continue;
329341
if (relatedSections.Count >= maxResults) break;
330342

331343
// Find the SiteMapping for this heading to get the link
332-
SiteMapping? relatedMapping = _SiteMappingService.SiteMappings
333-
.FirstOrDefault(m => m.RawHeading.Equals(heading, StringComparison.OrdinalIgnoreCase)
334-
&& m.ChapterNumber == (r.Record.ChapterNumber ?? 0));
344+
SiteMapping? relatedMapping = mappingsByChapter.TryGetValue(r.Record.ChapterNumber ?? 0, out Dictionary<string, SiteMapping>? chapterMappings)
345+
&& chapterMappings.TryGetValue(heading, out SiteMapping? candidate)
346+
? candidate
347+
: null;
335348

336349
string link = relatedMapping is not null
337350
? $"`/{relatedMapping.Keys.FirstOrDefault() ?? relatedMapping.PrimaryKey}#{relatedMapping.AnchorId}`"

0 commit comments

Comments
 (0)