diff --git a/htools/Ganeti/Query/Filter.hs b/htools/Ganeti/Query/Filter.hs index d5e56f708b31feff70b95dc11a8565fe0d80632a..94f65c9a063486fe1531e9f011f152201e96f500 100644 --- a/htools/Ganeti/Query/Filter.hs +++ b/htools/Ganeti/Query/Filter.hs @@ -144,14 +144,28 @@ containsFilter (NumericValue val) lst = do -- | Verifies if a given item passes a filter. The runtime context -- might be missing, in which case most of the filters will consider -- this as passing the filter. +-- +-- Note: we use explicit recursion to reduce unneeded memory use; +-- 'any' and 'all' do not play nice with monadic values, resulting in +-- either too much memory use or in too many thunks being created. evaluateFilter :: ConfigData -> Maybe b -> a -> Filter (FieldGetter a b) -> ErrorResult Bool evaluateFilter _ _ _ EmptyFilter = Ok True -evaluateFilter c mb a (AndFilter flts) = - all id <$> mapM (evaluateFilter c mb a) flts -evaluateFilter c mb a (OrFilter flts) = - any id <$> mapM (evaluateFilter c mb a) flts +evaluateFilter c mb a (AndFilter flts) = helper flts + where helper [] = Ok True + helper (f:fs) = do + v <- evaluateFilter c mb a f + if v + then helper fs + else Ok False +evaluateFilter c mb a (OrFilter flts) = helper flts + where helper [] = Ok False + helper (f:fs) = do + v <- evaluateFilter c mb a f + if v + then Ok True + else helper fs evaluateFilter c mb a (NotFilter flt) = not <$> evaluateFilter c mb a flt evaluateFilter c mb a (TrueFilter getter) =