Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ import {
getOperationScopeFromPath
} from "./resolve-arm-resources-converter.js";
import { AzureMgmtEmitterOptions } from "./options.js";
import { getSharedSegmentCount, isPrefix } from "./utils.js";
import { getSegmentCount, getSharedSegmentCount } from "./utils.js";
import { getAllSdkClients, traverseClient } from "./sdk-client-utils.js";

export async function updateClients(
Expand Down Expand Up @@ -187,12 +187,20 @@ export function buildArmProviderSchema(
0,
existingPath.lastIndexOf("/")
);
if (isPrefix(existingParentPath, operationPath)) {
const parentSegmentCount = getSegmentCount(existingParentPath);
const sharedCount = getSharedSegmentCount(
existingParentPath,
operationPath
);
if (
sharedCount === parentSegmentCount &&
sharedCount <= getSegmentCount(operationPath)
) {
Comment on lines +190 to +198
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inside the for (const [existingKey] ...) loop, getSegmentCount(operationPath) is recomputed for every candidate check. Since operationPath doesn’t change within the loop, compute its segment count once before iterating (or at least once per processMethod call) and reuse it to avoid repeated split/filter work in this hot path.

Copilot uses AI. Check for mistakes.
// Score based on how many segments match (longer prefix = better match)
const score = existingParentPath
.split("/")
.filter((s) => s.length > 0).length;
prefixMatchCandidates.push({ existingPath, matchScore: score });
prefixMatchCandidates.push({
existingPath,
matchScore: parentSegmentCount
});
}
}
}
Expand Down Expand Up @@ -390,17 +398,20 @@ export function buildArmProviderSchema(
const potentialParentPath = otherMetadata.resourceIdPattern;

// The child path should start with the parent path followed by a "/"
const parentSegmentCount = getSegmentCount(potentialParentPath);
const childSegmentCount = getSegmentCount(thisPath);
const sharedCount = getSharedSegmentCount(
potentialParentPath,
thisPath
);
// potentialParentPath is a strict prefix of thisPath when all parent segments match
// and the child has more segments
if (
isPrefix(potentialParentPath, thisPath) &&
!isPrefix(thisPath, potentialParentPath)
sharedCount === parentSegmentCount &&
parentSegmentCount < childSegmentCount
) {
// Use getSharedSegmentCount to get the segment count without redundant splitting
const segmentCount = getSharedSegmentCount(
potentialParentPath,
thisPath
);
if (segmentCount > longestParentSegmentCount) {
longestParentSegmentCount = segmentCount;
if (sharedCount > longestParentSegmentCount) {
longestParentSegmentCount = sharedCount;
longestParentPath = potentialParentPath;
}
}
Expand Down
17 changes: 12 additions & 5 deletions eng/packages/http-client-csharp-mgmt/emitter/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,26 @@ export function isVariableSegment(segment: string): boolean {
return segment.startsWith("{") && segment.endsWith("}");
}

/**
* Returns the number of non-empty segments in a path
* @param path the path
* @returns
*/
export function getSegmentCount(path: string): number {
return path.split("/").filter((s) => s.length > 0).length;
}

/**
* Returns true if left path is a prefix of right path
* @param left the first path
* @param right the second path
* @returns
*/
export function isPrefix(left: string, right: string): boolean {
const leftSegments = left.split("/").filter((s) => s.length > 0);
const rightSegments = right.split("/").filter((s) => s.length > 0);
const leftCount = getSegmentCount(left);
const rightCount = getSegmentCount(right);
const sharedCount = getSharedSegmentCount(left, right);
return (
sharedCount === leftSegments.length && sharedCount <= rightSegments.length
);
return sharedCount === leftCount && sharedCount <= rightCount;
}

/**
Expand Down
Loading