From 1536c2a3538da9f6322351f5276c0453a7a34e24 Mon Sep 17 00:00:00 2001 From: Huabing Zhao Date: Tue, 26 Nov 2024 11:31:23 +0000 Subject: [PATCH] optmize service search Signed-off-by: Huabing Zhao --- internal/cmd/egctl/translate_test.go | 9 +++++++-- internal/gatewayapi/backendtlspolicy.go | 3 ++- internal/gatewayapi/resource/resource.go | 19 ++++++++++++++----- .../resource/zz_generated.deepcopy.go | 17 +++++++++++++++++ internal/gatewayapi/translator_test.go | 9 ++++++--- 5 files changed, 46 insertions(+), 11 deletions(-) diff --git a/internal/cmd/egctl/translate_test.go b/internal/cmd/egctl/translate_test.go index 20cf76d0162..e87167ce305 100644 --- a/internal/cmd/egctl/translate_test.go +++ b/internal/cmd/egctl/translate_test.go @@ -22,6 +22,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/yaml" + "github.com/envoyproxy/gateway/internal/gatewayapi/resource" "github.com/envoyproxy/gateway/internal/utils/field" "github.com/envoyproxy/gateway/internal/utils/file" ) @@ -368,8 +369,12 @@ func TestTranslate(t *testing.T) { // want.GatewayClass.Status.SupportedFeatures = status.GatewaySupportedFeatures // } - opts := cmpopts.IgnoreFields(metav1.Condition{}, "LastTransitionTime") - require.Empty(t, cmp.Diff(want, got, opts)) + opts := []cmp.Option{ + cmpopts.IgnoreFields(metav1.Condition{}, "LastTransitionTime"), + cmpopts.IgnoreFields(resource.Resources{}, "serviceMap"), + } + + require.Empty(t, cmp.Diff(want, got, opts...)) }) } } diff --git a/internal/gatewayapi/backendtlspolicy.go b/internal/gatewayapi/backendtlspolicy.go index 48b53d065ce..98a195c5d01 100644 --- a/internal/gatewayapi/backendtlspolicy.go +++ b/internal/gatewayapi/backendtlspolicy.go @@ -162,7 +162,8 @@ func backendTLSTargetMatched(policy gwapiv1a3.BackendTLSPolicy, target gwapiv1a2 func getTargetBackendReferenceWithPortName( backendRef gwapiv1a2.BackendObjectReference, backendNamespace string, - resources *resource.Resources) gwapiv1a2.LocalPolicyTargetReferenceWithSectionName { + resources *resource.Resources, +) gwapiv1a2.LocalPolicyTargetReferenceWithSectionName { ref := getTargetBackendReference(backendRef) if ref.SectionName == nil { return ref diff --git a/internal/gatewayapi/resource/resource.go b/internal/gatewayapi/resource/resource.go index 97468511fa8..749e2efeef6 100644 --- a/internal/gatewayapi/resource/resource.go +++ b/internal/gatewayapi/resource/resource.go @@ -13,6 +13,7 @@ import ( corev1 "k8s.io/api/core/v1" discoveryv1 "k8s.io/api/discovery/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/types" gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" gwapiv1a3 "sigs.k8s.io/gateway-api/apis/v1alpha3" @@ -64,6 +65,8 @@ type Resources struct { ExtensionServerPolicies []unstructured.Unstructured `json:"extensionServerPolicies,omitempty" yaml:"extensionServerPolicies,omitempty"` Backends []*egv1a1.Backend `json:"backends,omitempty" yaml:"backends,omitempty"` HTTPRouteFilters []*egv1a1.HTTPRouteFilter `json:"httpFilters,omitempty" yaml:"httpFilters,omitempty"` + + serviceMap map[types.NamespacedName]*corev1.Service } func NewResources() *Resources { @@ -111,14 +114,20 @@ func (r *Resources) GetEnvoyProxy(namespace, name string) *egv1a1.EnvoyProxy { return nil } +// GetService returns the Service with the given namespace and name. +// This function creates a HashMap of Services for faster lookup when it's called for the first time. +// Subsequent calls will use the HashMap for lookup. +// Note: +// - This function is not thread-safe. +// - This function should be called after all the Services are added to the Resources. func (r *Resources) GetService(namespace, name string) *corev1.Service { - for _, svc := range r.Services { - if svc.Namespace == namespace && svc.Name == name { - return svc + if r.serviceMap == nil { + r.serviceMap = make(map[types.NamespacedName]*corev1.Service) + for _, svc := range r.Services { + r.serviceMap[types.NamespacedName{Namespace: svc.Namespace, Name: svc.Name}] = svc } } - - return nil + return r.serviceMap[types.NamespacedName{Namespace: namespace, Name: name}] } func (r *Resources) GetServiceImport(namespace, name string) *mcsapiv1a1.ServiceImport { diff --git a/internal/gatewayapi/resource/zz_generated.deepcopy.go b/internal/gatewayapi/resource/zz_generated.deepcopy.go index 06925b1467d..3caecc292c8 100644 --- a/internal/gatewayapi/resource/zz_generated.deepcopy.go +++ b/internal/gatewayapi/resource/zz_generated.deepcopy.go @@ -14,6 +14,7 @@ import ( corev1 "k8s.io/api/core/v1" discoveryv1 "k8s.io/api/discovery/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/gateway-api/apis/v1" "sigs.k8s.io/gateway-api/apis/v1alpha2" "sigs.k8s.io/gateway-api/apis/v1alpha3" @@ -290,6 +291,22 @@ func (in *Resources) DeepCopyInto(out *Resources) { } } } + if in.serviceMap != nil { + in, out := &in.serviceMap, &out.serviceMap + *out = make(map[types.NamespacedName]*corev1.Service, len(*in)) + for key, val := range *in { + var outVal *corev1.Service + if val == nil { + (*out)[key] = nil + } else { + inVal := (*in)[key] + in, out := &inVal, &outVal + *out = new(corev1.Service) + (*in).DeepCopyInto(*out) + } + (*out)[key] = outVal + } + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Resources. diff --git a/internal/gatewayapi/translator_test.go b/internal/gatewayapi/translator_test.go index 61e0025fbdd..96a88bfdec9 100644 --- a/internal/gatewayapi/translator_test.go +++ b/internal/gatewayapi/translator_test.go @@ -320,11 +320,11 @@ func TestTranslate(t *testing.T) { opts := []cmp.Option{ cmpopts.IgnoreFields(metav1.Condition{}, "LastTransitionTime"), + cmpopts.IgnoreFields(resource.Resources{}, "serviceMap"), cmp.Transformer("ClearXdsEqual", xdsWithoutEqual), cmpopts.IgnoreTypes(ir.PrivateBytes{}), cmpopts.EquateEmpty(), } - require.Empty(t, cmp.Diff(want, got, opts...)) }) } @@ -519,8 +519,11 @@ func TestTranslateWithExtensionKinds(t *testing.T) { want := &TranslateResult{} mustUnmarshal(t, output, want) - opts := cmpopts.IgnoreFields(metav1.Condition{}, "LastTransitionTime") - require.Empty(t, cmp.Diff(want, got, opts)) + opts := []cmp.Option{ + cmpopts.IgnoreFields(metav1.Condition{}, "LastTransitionTime"), + cmpopts.IgnoreFields(resource.Resources{}, "serviceMap"), + } + require.Empty(t, cmp.Diff(want, got, opts...)) }) } }