Line data Source code
1 : // Copyright (C) 2016 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.checkArgument; 18 : 19 : import com.google.common.collect.ImmutableList; 20 : import com.google.gerrit.index.IndexConfig; 21 : import java.util.Collection; 22 : import java.util.List; 23 : 24 : public class AndSource<T> extends AndPredicate<T> implements DataSource<T> { 25 : protected final DataSource<T> source; 26 : 27 : private final IsVisibleToPredicate<T> isVisibleToPredicate; 28 : private final int start; 29 : private final int cardinality; 30 : private final IndexConfig indexConfig; 31 : 32 : public AndSource(Collection<? extends Predicate<T>> that, IndexConfig indexConfig) { 33 11 : this(that, null, 0, indexConfig); 34 11 : } 35 : 36 : public AndSource( 37 : Predicate<T> that, IsVisibleToPredicate<T> isVisibleToPredicate, IndexConfig indexConfig) { 38 0 : this(that, isVisibleToPredicate, 0, indexConfig); 39 0 : } 40 : 41 : public AndSource( 42 : Predicate<T> that, 43 : IsVisibleToPredicate<T> isVisibleToPredicate, 44 : int start, 45 : IndexConfig indexConfig) { 46 117 : this(ImmutableList.of(that), isVisibleToPredicate, start, indexConfig); 47 117 : } 48 : 49 : public AndSource( 50 : Collection<? extends Predicate<T>> that, 51 : IsVisibleToPredicate<T> isVisibleToPredicate, 52 : int start, 53 : IndexConfig indexConfig) { 54 118 : super(that); 55 118 : checkArgument(start >= 0, "negative start: %s", start); 56 118 : this.isVisibleToPredicate = isVisibleToPredicate; 57 118 : this.start = start; 58 118 : this.indexConfig = indexConfig; 59 : 60 118 : int c = Integer.MAX_VALUE; 61 118 : Predicate<T> selectedSource = null; 62 118 : int minCardinality = Integer.MAX_VALUE; 63 118 : for (Predicate<T> p : getChildren()) { 64 118 : if (p instanceof DataSource) { 65 118 : DataSource<?> source = (DataSource<?>) p; 66 118 : int cardinality = source.getCardinality(); 67 118 : c = Math.min(c, source.getCardinality()); 68 : 69 118 : if (selectedSource == null 70 : || cardinality < minCardinality 71 : || (cardinality == minCardinality 72 1 : && p.estimateCost() < selectedSource.estimateCost())) { 73 118 : selectedSource = p; 74 118 : minCardinality = cardinality; 75 : } 76 : } 77 118 : } 78 118 : if (selectedSource == null) { 79 1 : throw new IllegalArgumentException("No DataSource Found"); 80 : } 81 118 : this.source = toPaginatingSource(selectedSource); 82 118 : this.cardinality = c; 83 118 : } 84 : 85 : @Override 86 : public ResultSet<T> read() { 87 118 : return source.read(); 88 : } 89 : 90 : @Override 91 : public ResultSet<FieldBundle> readRaw() { 92 0 : return source.readRaw(); 93 : } 94 : 95 : @Override 96 : public boolean isMatchable() { 97 89 : return isVisibleToPredicate != null || super.isMatchable(); 98 : } 99 : 100 : @Override 101 : public boolean match(T object) { 102 90 : if (isVisibleToPredicate != null && !isVisibleToPredicate.match(object)) { 103 18 : return false; 104 : } 105 : 106 90 : if (super.isMatchable() && !super.match(object)) { 107 9 : return false; 108 : } 109 : 110 89 : return true; 111 : } 112 : 113 : protected List<T> transformBuffer(List<T> buffer) { 114 0 : return buffer; 115 : } 116 : 117 : @Override 118 : public int getCardinality() { 119 0 : return cardinality; 120 : } 121 : 122 : @SuppressWarnings("unchecked") 123 : private PaginatingSource<T> toPaginatingSource(Predicate<T> pred) { 124 118 : return new PaginatingSource<>((DataSource<T>) pred, start, indexConfig) { 125 : @Override 126 : protected boolean match(T object) { 127 89 : return AndSource.this.match(object); 128 : } 129 : 130 : @Override 131 : protected boolean isMatchable() { 132 89 : return AndSource.this.isMatchable(); 133 : } 134 : }; 135 : } 136 : }