@@ -834,45 +834,56 @@ func (s *Silences) CountState(states ...types.SilenceState) (int, error) {
834834 return len (sils ), nil
835835}
836836
837+ // query executes the given query and returns the resulting silences.
837838func (s * Silences ) query (q * query , now time.Time ) ([]* pb.Silence , int , error ) {
838- // If we have no ID constraint, all silences are our base set. This and
839- // the use of post-filter functions is the trivial solution for now.
840839 var res []* pb.Silence
840+ var err error
841841
842+ // appendIfFiltersMatch appends the given silence to the result set
843+ // if it matches all filters in the query. In case of a filter error, the error is returned.
844+ appendIfFiltersMatch := func (res []* pb.Silence , sil * pb.Silence ) ([]* pb.Silence , error ) {
845+ for _ , f := range q .filters {
846+ matches , err := f (sil , s , now )
847+ // In case of error return it immediately and don't process further filters.
848+ if err != nil {
849+ return res , err
850+ }
851+ // If one filter doesn't match, return the result unchanged, immediately.
852+ if ! matches {
853+ return res , nil
854+ }
855+ }
856+ // All filters matched, append the silence to the result.
857+ return append (res , cloneSilence (sil )), nil
858+ }
859+
860+ // Take a read lock on Silences: we can read but not modify the Silences struct.
842861 s .mtx .RLock ()
843862 defer s .mtx .RUnlock ()
844863
864+ // If we have IDs, only consider the silences with the given IDs, if they exist.
845865 if q .ids != nil {
846866 for _ , id := range q .ids {
847- if s , ok := s .st [id ]; ok {
848- res = append (res , s .Silence )
867+ if sil , ok := s .st [id ]; ok {
868+ // append the silence to the results if it satisfies the query.
869+ res , err = appendIfFiltersMatch (res , sil .Silence )
870+ if err != nil {
871+ return nil , s .version , err
872+ }
849873 }
850874 }
851875 } else {
876+ // No IDs given, consider all silences.
852877 for _ , sil := range s .st {
853- res = append (res , sil .Silence )
854- }
855- }
856-
857- var resf []* pb.Silence
858- for _ , sil := range res {
859- remove := false
860- for _ , f := range q .filters {
861- ok , err := f (sil , s , now )
878+ // append the silence to the results if it satisfies the query.
879+ res , err = appendIfFiltersMatch (res , sil .Silence )
862880 if err != nil {
863881 return nil , s .version , err
864882 }
865- if ! ok {
866- remove = true
867- break
868- }
869- }
870- if ! remove {
871- resf = append (resf , cloneSilence (sil ))
872883 }
873884 }
874885
875- return resf , s .version , nil
886+ return res , s .version , nil
876887}
877888
878889// loadSnapshot loads a snapshot generated by Snapshot() into the state.
0 commit comments