com.google.gerrit.index.query.AndSource Maven / Gradle / Ivy
// Copyright (C) 2016 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.index.query;
import static com.google.common.base.Preconditions.checkArgument;
import com.google.common.collect.ImmutableList;
import com.google.gerrit.index.IndexConfig;
import java.util.Collection;
import java.util.List;
public class AndSource extends AndPredicate implements DataSource {
protected final DataSource source;
private final IsVisibleToPredicate isVisibleToPredicate;
private final int start;
private final int cardinality;
private final IndexConfig indexConfig;
public AndSource(Collection extends Predicate> that, IndexConfig indexConfig) {
this(that, null, 0, indexConfig);
}
public AndSource(
Predicate that, IsVisibleToPredicate isVisibleToPredicate, IndexConfig indexConfig) {
this(that, isVisibleToPredicate, 0, indexConfig);
}
public AndSource(
Predicate that,
IsVisibleToPredicate isVisibleToPredicate,
int start,
IndexConfig indexConfig) {
this(ImmutableList.of(that), isVisibleToPredicate, start, indexConfig);
}
public AndSource(
Collection extends Predicate> that,
IsVisibleToPredicate isVisibleToPredicate,
int start,
IndexConfig indexConfig) {
super(that);
checkArgument(start >= 0, "negative start: %s", start);
this.isVisibleToPredicate = isVisibleToPredicate;
this.start = start;
this.indexConfig = indexConfig;
int c = Integer.MAX_VALUE;
Predicate selectedSource = null;
int minCardinality = Integer.MAX_VALUE;
for (Predicate p : getChildren()) {
if (p instanceof DataSource) {
DataSource source = (DataSource) p;
int cardinality = source.getCardinality();
c = Math.min(c, source.getCardinality());
if (selectedSource == null
|| cardinality < minCardinality
|| (cardinality == minCardinality
&& p.estimateCost() < selectedSource.estimateCost())) {
selectedSource = p;
minCardinality = cardinality;
}
}
}
if (selectedSource == null) {
throw new IllegalArgumentException("No DataSource Found");
}
this.source = toPaginatingSource(selectedSource);
this.cardinality = c;
}
@Override
public ResultSet read() {
return source.read();
}
@Override
public ResultSet readRaw() {
return source.readRaw();
}
@Override
public boolean isMatchable() {
return isVisibleToPredicate != null || super.isMatchable();
}
@Override
public boolean match(T object) {
if (isVisibleToPredicate != null && !isVisibleToPredicate.match(object)) {
return false;
}
if (super.isMatchable() && !super.match(object)) {
return false;
}
return true;
}
protected List transformBuffer(List buffer) {
return buffer;
}
@Override
public int getCardinality() {
return cardinality;
}
@SuppressWarnings("unchecked")
private PaginatingSource toPaginatingSource(Predicate pred) {
return new PaginatingSource((DataSource) pred, start, indexConfig) {
@Override
protected boolean match(T object) {
return AndSource.this.match(object);
}
@Override
protected boolean isMatchable() {
return AndSource.this.isMatchable();
}
};
}
}