@@ -762,27 +762,79 @@ func needsInternalLocationsForMatches(rule dataplane.PathRule) bool {
762762// for example, {/foo: {exact: {}, prefix: {}}}.
763763type pathAndTypeMap map [string ]map [dataplane.PathType ]struct {}
764764
765- // To calculate the maximum number of locations, we need to take into account the following:
766- // 1. Each match rule for a path rule will have one location.
767- // 2. Each path rule may have an additional location if it contains non-path-only matches.
768- // 3. Each prefix path rule may have an additional location if it doesn't contain trailing slash.
769- // 4. There may be an additional location for the default root path.
770- // 5. There may be an additional location per parent location for the inference extension.
771- // We also return a map of all paths and their types.
772765func getMaxLocationCountAndPathMap (pathRules []dataplane.PathRule ) (int , pathAndTypeMap ) {
773- maxLocs := 1
766+ // To calculate the maximum number of locations, we need to take into account the following:
767+ // 1. Each path rule will have at least one external location.
768+ // 2. Each path rule may have an additional external location if it's a non-slashed prefix path.
769+ // 3. There may be an additional location for the default root path.
770+ // 4. For inference backends:
771+ // - Single backend without matches: 2 locations (external EPP + internal proxy pass)
772+ // - Single backend with matches: 3 locations (external redirect + internal EPP + internal proxy pass)
773+ // - Multiple backends without matches: 1 external + (2 * numBackends) internal locations
774+ // - Multiple backends with matches: 1 external + 1 split clients + (2 * numBackends) internal locations
775+ // 5. For non-inference backends with matches:
776+ // - Each match rule gets an internal location
777+ // We also return a map of all paths and their types.
778+
779+ maxLocs := 0
774780 pathsAndTypes := make (pathAndTypeMap )
781+
775782 for _ , rule := range pathRules {
776- maxLocs += (len (rule .MatchRules ) * 2 ) + 2
783+ // External locations calculation
784+ maxLocs ++ // Base external location for the path
785+
786+ // Add the path to the map
777787 if pathsAndTypes [rule .Path ] == nil {
778- pathsAndTypes [rule .Path ] = map [dataplane.PathType ]struct {}{
779- rule .PathType : {},
788+ pathsAndTypes [rule .Path ] = make (map [dataplane.PathType ]struct {})
789+ }
790+ pathsAndTypes [rule.Path ][rule.PathType ] = struct {}{}
791+
792+ // Check if we need an additional external location for non-slashed prefix paths
793+ if isNonSlashedPrefixPath (rule .PathType , rule .Path ) {
794+ maxLocs ++ // Additional external location for exact match
795+ }
796+
797+ // Determine if we need internal locations for matches
798+ needsInternalMatches := needsInternalLocationsForMatches (rule )
799+
800+ // Internal locations calculation
801+ for _ , matchRule := range rule .MatchRules {
802+ if ! rule .HasInferenceBackends {
803+ // Non-inference backends with matches need internal locations
804+ if needsInternalMatches {
805+ maxLocs ++ // Internal match location per match rule
806+ }
807+ } else {
808+ // Inference backends calculation
809+ numBackends := len (matchRule .BackendGroup .Backends )
810+
811+ if needsInternalMatches {
812+ // Has HTTP matching conditions
813+ if numBackends > 1 {
814+ // Multiple backends with matches: split clients + 2 locations per backend
815+ maxLocs ++ // Internal split clients location
816+ maxLocs += numBackends * 2 // EPP + proxy pass per backend
817+ } else {
818+ // Single backend with matches: EPP + proxy pass
819+ maxLocs += 2
820+ }
821+ } else {
822+ // No HTTP matching conditions
823+ if numBackends > 1 {
824+ // Multiple backends without matches: 2 locations per backend (no split clients for external)
825+ maxLocs += numBackends * 2 // EPP + proxy pass per backend
826+ } else {
827+ // Single backend without matches: proxy pass only (external becomes EPP)
828+ maxLocs ++ // Just the internal proxy pass location
829+ }
830+ }
780831 }
781- } else {
782- pathsAndTypes [rule.Path ][rule.PathType ] = struct {}{}
783832 }
784833 }
785834
835+ // Add 1 for potential default root location
836+ maxLocs ++
837+
786838 return maxLocs , pathsAndTypes
787839}
788840
0 commit comments