@@ -19,9 +19,19 @@ import utilobject "github.com/kubewharf/kelemetry/pkg/util/object"
1919type LinkSelector interface {
2020 // Whether to follow the given link.
2121 //
22- // If link should be followed, return a non-nil LinkSelector.
23- // The returned object will be used to recursively follow links in the linked object.
24- Admit (parent utilobject.Key , child utilobject.Key , parentIsSource bool , linkClass string ) LinkSelector
22+ // The first output indicates whether the selector admits this link.
23+ // The second output is the selector state that transitive links should use for admission.
24+ // The second output may still be useful even if the first output is false when it is part of a UnionLinkSelector.
25+ // A nil state "fuses" the selector, i.e. always return false for further transitive links.
26+ Admit (parent utilobject.Key , child utilobject.Key , parentIsSource bool , linkClass string ) (_admit bool , _nextState LinkSelector )
27+ }
28+
29+ func nilableLinkSelectorAdmit (selector LinkSelector , parent utilobject.Key , child utilobject.Key , parentIsSource bool , linkClass string ) (bool , LinkSelector ) {
30+ if selector == nil {
31+ return false , nil
32+ }
33+
34+ return selector .Admit (parent , child , parentIsSource , linkClass )
2535}
2636
2737type ConstantLinkSelector bool
@@ -31,12 +41,12 @@ func (selector ConstantLinkSelector) Admit(
3141 child utilobject.Key ,
3242 parentIsSource bool ,
3343 linkClass string ,
34- ) LinkSelector {
44+ ) ( _admit bool , _nextState LinkSelector ) {
3545 if selector {
36- return selector
46+ return true , selector
3747 }
3848
39- return nil
49+ return false , selector
4050}
4151
4252type IntersectLinkSelector []LinkSelector
@@ -46,17 +56,17 @@ func (selector IntersectLinkSelector) Admit(
4656 childKey utilobject.Key ,
4757 parentIsSource bool ,
4858 linkClass string ,
49- ) LinkSelector {
50- newChildren := make ([] LinkSelector , len ( selector ))
51-
52- for i , child := range selector {
53- newChildren [ i ] = child . Admit ( parentKey , childKey , parentIsSource , linkClass )
54- if newChildren [ i ] == nil {
55- return nil
56- }
59+ ) ( _admit bool , _nextState LinkSelector ) {
60+ admit := true
61+ nextMemberStates := make ([] LinkSelector , len ( selector ))
62+
63+ for i , member := range selector {
64+ memberAdmit , nextMemberState := nilableLinkSelectorAdmit ( member , parentKey , childKey , parentIsSource , linkClass )
65+ admit = admit && memberAdmit
66+ nextMemberStates [ i ] = nextMemberState
5767 }
5868
59- return IntersectLinkSelector (newChildren )
69+ return admit , IntersectLinkSelector (nextMemberStates )
6070}
6171
6272type UnionLinkSelector []LinkSelector
@@ -66,22 +76,15 @@ func (selector UnionLinkSelector) Admit(
6676 childKey utilobject.Key ,
6777 parentIsSource bool ,
6878 linkClass string ,
69- ) LinkSelector {
70- newChildren := make ([]LinkSelector , len (selector ))
71-
72- ok := false
73- for i , child := range selector {
74- if child != nil {
75- newChildren [i ] = child .Admit (parentKey , childKey , parentIsSource , linkClass )
76- if newChildren [i ] != nil {
77- ok = true
78- }
79- }
80- }
79+ ) (_admit bool , _nextState LinkSelector ) {
80+ admit := false
81+ nextMemberStates := make ([]LinkSelector , len (selector ))
8182
82- if ok {
83- return UnionLinkSelector (newChildren )
83+ for i , member := range selector {
84+ memberAdmit , nextMemberState := nilableLinkSelectorAdmit (member , parentKey , childKey , parentIsSource , linkClass )
85+ admit = admit || memberAdmit
86+ nextMemberStates [i ] = nextMemberState
8487 }
8588
86- return nil
89+ return admit , UnionLinkSelector ( nextMemberStates )
8790}
0 commit comments