All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.googlecode.cqengine.index.compound.CompoundIndex Maven / Gradle / Ivy

Go to download

Collection Query Engine: NoSQL indexing and query engine for Java collections with ultra-low latency

There is a newer version: 3.6.0
Show newest version
/**
 * Copyright 2012-2015 Niall Gallagher
 *
 * 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.googlecode.cqengine.index.compound;

import com.googlecode.cqengine.attribute.Attribute;
import com.googlecode.cqengine.index.support.AbstractMapBasedAttributeIndex;
import com.googlecode.cqengine.index.support.Factory;
import com.googlecode.cqengine.index.support.KeyStatisticsAttributeIndex;
import com.googlecode.cqengine.index.compound.support.CompoundAttribute;
import com.googlecode.cqengine.index.compound.support.CompoundQuery;
import com.googlecode.cqengine.index.compound.support.CompoundValueTuple;
import com.googlecode.cqengine.index.support.CloseableIterable;
import com.googlecode.cqengine.quantizer.Quantizer;
import com.googlecode.cqengine.query.Query;
import com.googlecode.cqengine.query.option.QueryOptions;
import com.googlecode.cqengine.resultset.ResultSet;
import com.googlecode.cqengine.resultset.filter.QuantizedResultSet;
import com.googlecode.cqengine.resultset.stored.StoredResultSet;
import com.googlecode.cqengine.resultset.stored.StoredSetBasedResultSet;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * An index backed by a {@link java.util.concurrent.ConcurrentHashMap} which indexes {@link CompoundAttribute}s,
 * storing {@link CompoundValueTuple} objects as keys.
 * 

* Supports query types: *

    *
  • * {@link com.googlecode.cqengine.index.compound.support.CompoundQuery} *
  • *
* The constructor of this index accepts {@link Factory} objects, from which it will create the map and value sets it * uses internally. This allows the application to "tune" the construction parameters of these maps/sets, * by supplying custom factories. * For default settings, supply {@link DefaultIndexMapFactory} and {@link DefaultValueSetFactory}. * * @author Niall Gallagher */ public class CompoundIndex extends AbstractMapBasedAttributeIndex, O, ConcurrentMap, StoredResultSet>> implements KeyStatisticsAttributeIndex, O> { protected static final int INDEX_RETRIEVAL_COST = 20; protected final CompoundAttribute attribute; /** * Package-private constructor, used by static factory methods. Creates a new HashIndex initialized to index the * supplied attribute. * * @param indexMapFactory A factory used to create the main map-based data structure used by the index * @param valueSetFactory A factory used to create sets to store values in the index * @param attribute The attribute on which the index will be built */ protected CompoundIndex(Factory, StoredResultSet>> indexMapFactory, Factory> valueSetFactory, CompoundAttribute attribute) { // We can supply the superclass constructor with an empty set of supported queries, // because we implement/override supportsQuery() in this class instead... super(indexMapFactory, valueSetFactory, attribute, Collections.>emptySet()); this.attribute = attribute; } /** * Returns true if the given {@link Query} is based on the same list of attributes as the * {@link CompoundAttribute} on which this compound index is based. * * @param query A {@link Query} to test * @return True if the given {@link Query} is based on the same list of attributes as the * {@link CompoundAttribute} on which this compound index is based, otherwise false */ @Override public boolean supportsQuery(Query query) { if (query instanceof CompoundQuery) { CompoundQuery compoundQuery = (CompoundQuery) query; return attribute.equals(compoundQuery.getCompoundAttribute()); } return false; } @Override public CompoundAttribute getAttribute() { return attribute; } /** * {@inheritDoc} *

* This index is mutable. * * @return true */ @Override public boolean isMutable() { return true; } /** * {@inheritDoc} */ @Override public ResultSet retrieve(Query query, final QueryOptions queryOptions) { Class queryClass = query.getClass(); if (queryClass.equals(CompoundQuery.class)) { final CompoundQuery compoundQuery = (CompoundQuery) query; final CompoundValueTuple valueTuple = compoundQuery.getCompoundValueTuple(); return new ResultSet() { @Override public Iterator iterator() { ResultSet rs = indexMap.get(getQuantizedValue(valueTuple)); return rs == null ? Collections.emptySet().iterator() : filterForQuantization(rs, compoundQuery, queryOptions).iterator(); } @Override public boolean contains(O object) { ResultSet rs = indexMap.get(getQuantizedValue(valueTuple)); return rs != null && filterForQuantization(rs, compoundQuery, queryOptions).contains(object); } @Override public int size() { ResultSet rs = indexMap.get(getQuantizedValue(valueTuple)); return rs == null ? 0 : filterForQuantization(rs, compoundQuery, queryOptions).size(); } @Override public int getRetrievalCost() { return INDEX_RETRIEVAL_COST; } @Override public int getMergeCost() { // Return size of entire stored set as merge cost... ResultSet rs = indexMap.get(getQuantizedValue(valueTuple)); return rs == null ? 0 : rs.size(); } @Override public void close() { // No op. } }; } else { throw new IllegalArgumentException("Unsupported query: " + query); } } @Override public CloseableIterable> getDistinctKeys(QueryOptions queryOptions) { return super.getDistinctKeys(); } @Override public Integer getCountForKey(CompoundValueTuple key, QueryOptions queryOptions) { return super.getCountForKey(key); } // ---------- Hook methods which can be overridden by subclasses using a Quantizer ---------- /** * A no-op method which can be overridden by a subclass to return a {@link ResultSet} which filters objects from the * given {@link ResultSet}, to return only those objects matching the query, for the case that the index is using a * {@link com.googlecode.cqengine.quantizer.Quantizer}. *

* This default implementation simply returns the given {@link ResultSet} unmodified. * * @param storedResultSet A {@link com.googlecode.cqengine.resultset.ResultSet} stored against a quantized key in the index * @param query The query against which results should be matched * @param queryOptions Optional parameters for the query * @return A {@link ResultSet} which filters objects from the given {@link ResultSet}, * to return only those objects matching the query */ protected ResultSet filterForQuantization(ResultSet storedResultSet, Query query, QueryOptions queryOptions) { return storedResultSet; } /** * Creates a new {@link CompoundIndex} on the given combination of attributes. *

* @param attributes The combination of simple attributes on which index will be built * @param The type of the object containing the attributes * @return A {@link CompoundIndex} based on these attributes */ // TODO: add overloaded non-varargs versions of this method to prevent unchecked warnings pre JDK 7? public static CompoundIndex onAttributes(Attribute... attributes) { return onAttributes(new DefaultIndexMapFactory(), new DefaultValueSetFactory(), attributes); } /** * Creates a new {@link CompoundIndex} on the given combination of attributes. *

* @param indexMapFactory A factory used to create the main map-based data structure used by the index * @param valueSetFactory A factory used to create sets to store values in the index * @param attributes The combination of simple attributes on which index will be built * @param The type of the object containing the attributes * @return A {@link CompoundIndex} based on these attributes */ // TODO: add overloaded non-varargs versions of this method to prevent unchecked warnings pre JDK 7? public static CompoundIndex onAttributes(Factory, StoredResultSet>> indexMapFactory, Factory> valueSetFactory, Attribute... attributes) { List> attributeList = Arrays.asList(attributes); CompoundAttribute compoundAttribute = new CompoundAttribute(attributeList); return new CompoundIndex(indexMapFactory, valueSetFactory, compoundAttribute); } /** * Creates a new {@link CompoundIndex} using the given {@link Quantizer} on the given combination of attributes. *

* @param attributes The combination of simple attributes on which index will be built * @param quantizer A {@link Quantizer} to use in this index * @param The type of the object containing the attributes * @return A {@link CompoundIndex} based on these attributes */ public static CompoundIndex withQuantizerOnAttributes(final Quantizer> quantizer, Attribute... attributes) { return withQuantizerOnAttributes(new DefaultIndexMapFactory(), new DefaultValueSetFactory(), quantizer, attributes); } /** * Creates a new {@link CompoundIndex} using the given {@link Quantizer} on the given combination of attributes. *

* @param indexMapFactory A factory used to create the main map-based data structure used by the index * @param valueSetFactory A factory used to create sets to store values in the index * @param attributes The combination of simple attributes on which index will be built * @param quantizer A {@link Quantizer} to use in this index * @param The type of the object containing the attributes * @return A {@link CompoundIndex} based on these attributes */ public static CompoundIndex withQuantizerOnAttributes(Factory, StoredResultSet>> indexMapFactory, Factory> valueSetFactory, final Quantizer> quantizer, Attribute... attributes) { List> attributeList = Arrays.asList(attributes); CompoundAttribute compoundAttribute = new CompoundAttribute(attributeList); return new CompoundIndex(indexMapFactory, valueSetFactory, compoundAttribute) { // ---------- Override the hook methods related to Quantizer ---------- @Override protected ResultSet filterForQuantization(ResultSet resultSet, final Query query, QueryOptions queryOptions) { return new QuantizedResultSet(resultSet, query, queryOptions); } @Override protected CompoundValueTuple getQuantizedValue(CompoundValueTuple attributeValue) { return quantizer.getQuantizedValue(attributeValue); } @Override public boolean isIndexQuantized() { return true; } }; } /** * Creates an index map using default settings. */ public static class DefaultIndexMapFactory implements Factory, StoredResultSet>> { @Override public ConcurrentMap, StoredResultSet> create() { return new ConcurrentHashMap, StoredResultSet>(); } } /** * Creates a value set using default settings. */ public static class DefaultValueSetFactory implements Factory> { @Override public StoredResultSet create() { return new StoredSetBasedResultSet(Collections.newSetFromMap(new ConcurrentHashMap())); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy