blob: 2820b8449a79ab870176f7a548e58cd4e4b6d92e [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.ignite.cache.query;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import javax.cache.Cache;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.internal.A;
import org.apache.ignite.lang.IgniteBiPredicate;
import org.apache.ignite.lang.IgniteExperimental;
import org.jetbrains.annotations.Nullable;
/**
* Index queries work over distributed indexes and retrieve cache entries that match the specified criteria.
* {@code QueryCursor} delivers sorted cache entries by the order defined for queried index.
*
* {@code IndexQuery} has to be initialized with cache value class or type. The algorithm of discovering index is as follows:
* 1. If {@link #idxName} is set, then use it.
* 2. If {@link #idxName} is not set, then find an index that matches criteria fields.
* 3. If neither {@link #idxName}, nor {@link #setCriteria(List)} is used, then perform index scan over PK index for specified Value type.
*
* Conjuction of items in {@link #criteria} has to represent a valid range to traverse the index tree.
*/
@IgniteExperimental
public final class IndexQuery<K, V> extends Query<Cache.Entry<K, V>> {
/** */
private static final long serialVersionUID = 0L;
/** Cache Value type. Describes a table within a cache that runs a query. */
private final String valType;
/** Index name. */
private final @Nullable String idxName;
/** Index query criteria. */
private @Nullable List<IndexQueryCriterion> criteria;
/** Partition to run IndexQuery over. */
private @Nullable Integer part;
/**
* Specify index with cache value class.
*
* @param valCls Cache value class.
*/
public IndexQuery(Class<?> valCls) {
this(valCls, null);
}
/**
* Specify index with cache value type.
*
* @param valType Cache value type.
*/
public IndexQuery(String valType) {
this(valType, null);
}
/** Cache entries filter. Applies remotely to a query result cursor. */
private IgniteBiPredicate<K, V> filter;
/**
* Specify index with cache value class and index name.
*
* @param valCls Cache value class.
* @param idxName Index name.
*/
public IndexQuery(Class<?> valCls, @Nullable String idxName) {
this(valCls.getName(), idxName);
}
/**
* Specify index with cache value type and index name.
*
* @param valType Cache value type.
* @param idxName Index name.
*/
public IndexQuery(String valType, @Nullable String idxName) {
A.notEmpty(valType, "valType");
A.nullableNotEmpty(idxName, "idxName");
this.valType = valType;
this.idxName = idxName;
}
/**
* Sets conjunction (AND) criteria for index query.
*
* @param criteria Criteria to set.
* @return {@code this} for chaining.
*/
public IndexQuery<K, V> setCriteria(IndexQueryCriterion... criteria) {
validateAndSetCriteria(Arrays.asList(criteria));
return this;
}
/**
* Sets conjunction (AND) criteria for index query.
*
* @param criteria Criteria to set.
* @return {@code this} for chaining.
*/
public IndexQuery<K, V> setCriteria(List<IndexQueryCriterion> criteria) {
validateAndSetCriteria(new ArrayList<>(criteria));
return this;
}
/**
* Index query criteria.
*
* @return List of criteria for this index query.
*/
public List<IndexQueryCriterion> getCriteria() {
return criteria;
}
/**
* Cache Value type.
*
* @return Cache Value type.
*/
public String getValueType() {
return valType;
}
/**
* Index name.
*
* @return Index name.
*/
public String getIndexName() {
return idxName;
}
/**
* Sets remote cache entries filter.
*
* @param filter Predicate for remote filtering of query result cursor.
* @return {@code this} for chaining.
*/
public IndexQuery<K, V> setFilter(IgniteBiPredicate<K, V> filter) {
A.notNull(filter, "filter");
this.filter = filter;
return this;
}
/**
* Gets remote cache entries filter.
*
* @return Filter.
*/
public IgniteBiPredicate<K, V> getFilter() {
return filter;
}
/**
* Sets partition number over which this query should iterate. If {@code null}, query will iterate over
* all partitions in the cache. Must be in the range [0, N) where N is partition number in the cache.
*
* @param part Partition number over which this query should iterate.
* @return {@code this} for chaining.
*/
public IndexQuery<K, V> setPartition(@Nullable Integer part) {
A.ensure(part == null || part >= 0,
"Specified partition must be in the range [0, N) where N is partition number in the cache.");
this.part = part;
return this;
}
/**
* Gets partition number over which this query should iterate. Will return {@code null} if partition was not
* set. In this case query will iterate over all partitions in the cache.
*
* @return Partition number or {@code null}.
*/
@Nullable public Integer getPartition() {
return part;
}
/** */
private void validateAndSetCriteria(List<IndexQueryCriterion> criteria) {
if (F.isEmpty(criteria))
return;
Class<?> critCls = criteria.get(0).getClass();
for (IndexQueryCriterion c: criteria) {
A.notNull(c, "criteria");
A.ensure(c.getClass() == critCls,
"Expect a the same criteria class for merging criteria. Exp=" + critCls + ", act=" + c.getClass());
}
this.criteria = Collections.unmodifiableList(criteria);
}
}