LCOV - code coverage report
Current view: top level - index/query - AndPredicate.java (source / functions) Hit Total Coverage
Test: _coverage_report.dat Lines: 58 59 98.3 %
Date: 2022-11-19 15:00:39 Functions: 14 14 100.0 %

          Line data    Source code
       1             : // Copyright (C) 2009 The Android Open Source Project
       2             : //
       3             : // Licensed under the Apache License, Version 2.0 (the "License");
       4             : // you may not use this file except in compliance with the License.
       5             : // You may obtain a copy of the License at
       6             : //
       7             : // http://www.apache.org/licenses/LICENSE-2.0
       8             : //
       9             : // Unless required by applicable law or agreed to in writing, software
      10             : // distributed under the License is distributed on an "AS IS" BASIS,
      11             : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      12             : // See the License for the specific language governing permissions and
      13             : // limitations under the License.
      14             : 
      15             : package com.google.gerrit.index.query;
      16             : 
      17             : import static com.google.common.base.Preconditions.checkState;
      18             : import static com.google.common.collect.ImmutableList.toImmutableList;
      19             : 
      20             : import com.google.common.collect.ImmutableList;
      21             : import java.util.ArrayList;
      22             : import java.util.Arrays;
      23             : import java.util.Collection;
      24             : import java.util.Collections;
      25             : import java.util.Comparator;
      26             : import java.util.List;
      27             : 
      28             : /** Requires all predicates to be true. */
      29             : public class AndPredicate<T> extends Predicate<T>
      30             :     implements Matchable<T>, Comparator<Predicate<T>> {
      31             :   private final List<Predicate<T>> children;
      32             :   private final int cost;
      33             : 
      34             :   @SafeVarargs
      35             :   protected AndPredicate(Predicate<T>... that) {
      36         111 :     this(Arrays.asList(that));
      37         111 :   }
      38             : 
      39         121 :   protected AndPredicate(Collection<? extends Predicate<T>> that) {
      40         121 :     List<Predicate<T>> t = new ArrayList<>(that.size());
      41         121 :     int c = 0;
      42         121 :     for (Predicate<T> p : sort(that)) {
      43         121 :       if (getClass() == p.getClass()) {
      44          16 :         for (Predicate<T> gp : p.getChildren()) {
      45          16 :           t.add(gp);
      46          16 :           c += gp.estimateCost();
      47          16 :         }
      48             :       } else {
      49         121 :         t.add(p);
      50         121 :         c += p.estimateCost();
      51             :       }
      52         121 :     }
      53         121 :     children = t;
      54         121 :     cost = c;
      55         121 :   }
      56             : 
      57             :   @Override
      58             :   public final List<Predicate<T>> getChildren() {
      59         121 :     return Collections.unmodifiableList(children);
      60             :   }
      61             : 
      62             :   @Override
      63             :   public final int getChildCount() {
      64         114 :     return children.size();
      65             :   }
      66             : 
      67             :   @Override
      68             :   public final Predicate<T> getChild(int i) {
      69         114 :     return children.get(i);
      70             :   }
      71             : 
      72             :   @Override
      73             :   public Predicate<T> copy(Collection<? extends Predicate<T>> children) {
      74           6 :     return new AndPredicate<>(children);
      75             :   }
      76             : 
      77             :   @Override
      78             :   public boolean isMatchable() {
      79         109 :     for (Predicate<T> c : children) {
      80         109 :       if (!c.isMatchable()) {
      81          16 :         return false;
      82             :       }
      83         103 :     }
      84         103 :     return true;
      85             :   }
      86             : 
      87             :   @Override
      88             :   public boolean match(T object) {
      89         103 :     for (Predicate<T> c : children) {
      90         103 :       checkState(
      91         103 :           c.isMatchable(),
      92             :           "match invoked, but child predicate %s doesn't implement %s",
      93             :           c,
      94         103 :           Matchable.class.getName());
      95         103 :       if (!c.asMatchable().match(object)) {
      96          95 :         return false;
      97             :       }
      98         102 :     }
      99          93 :     return true;
     100             :   }
     101             : 
     102             :   @Override
     103             :   public int getCost() {
     104          14 :     return cost;
     105             :   }
     106             : 
     107             :   @Override
     108             :   public int hashCode() {
     109           1 :     return getChild(0).hashCode() * 31 + getChild(1).hashCode();
     110             :   }
     111             : 
     112             :   // Suppress the EqualsGetClass warning as this is legacy code.
     113             :   @SuppressWarnings("EqualsGetClass")
     114             :   @Override
     115             :   public boolean equals(Object other) {
     116           7 :     if (other == null) {
     117           0 :       return false;
     118             :     }
     119           7 :     return getClass() == other.getClass()
     120           7 :         && getChildren().equals(((Predicate<?>) other).getChildren());
     121             :   }
     122             : 
     123             :   private ImmutableList<Predicate<T>> sort(Collection<? extends Predicate<T>> that) {
     124         121 :     return that.stream().sorted(this).collect(toImmutableList());
     125             :   }
     126             : 
     127             :   @Override
     128             :   public int compare(Predicate<T> a, Predicate<T> b) {
     129         111 :     int ai = a instanceof DataSource ? 0 : 1;
     130         111 :     int bi = b instanceof DataSource ? 0 : 1;
     131         111 :     int cmp = ai - bi;
     132             : 
     133         111 :     if (cmp == 0) {
     134         111 :       cmp = a.estimateCost() - b.estimateCost();
     135             :     }
     136             : 
     137         111 :     if (cmp == 0 && a instanceof DataSource && b instanceof DataSource) {
     138           1 :       DataSource<?> as = (DataSource<?>) a;
     139           1 :       DataSource<?> bs = (DataSource<?>) b;
     140           1 :       cmp = as.getCardinality() - bs.getCardinality();
     141             :     }
     142         111 :     return cmp;
     143             :   }
     144             : 
     145             :   @Override
     146             :   public String toString() {
     147          19 :     final StringBuilder r = new StringBuilder();
     148          19 :     r.append("(");
     149          19 :     for (int i = 0; i < getChildCount(); i++) {
     150          19 :       if (i != 0) {
     151          15 :         r.append(" ");
     152             :       }
     153          19 :       r.append(getChild(i));
     154             :     }
     155          19 :     r.append(")");
     156          19 :     return r.toString();
     157             :   }
     158             : }

Generated by: LCOV version 1.16+git.20220603.dfeb750