/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at * trunk/opends/resource/legal-notices/OpenDS.LICENSE * or https://OpenDS.dev.java.net/OpenDS.LICENSE. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, * add the following below this CDDL HEADER, with the fields enclosed * by brackets "[]" replaced with your own identifying information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * * Copyright 2009-2010 Sun Microsystems, Inc. */ package org.opends.server.backends.jeb; import org.opends.messages.Message; import java.util.Collection; import java.util.List; import static org.opends.server.backends.jeb.IndexFilter.*; /** * This class represents a JE Backend Query. */ @org.opends.server.types.PublicAPI( stability = org.opends.server.types.StabilityLevel.VOLATILE, mayInstantiate = false, mayExtend = true, mayInvoke = false) public abstract class IndexQuery { /** * Evaluates the index query and returns the EntryIDSet. * * @param debugMessages If not null, diagnostic messages will be written * which will help to determine why the returned * EntryIDSet is not defined. * @return The EntryIDSet as a result of evaulation of this query. */ public abstract EntryIDSet evaluate(List<Message> debugMessages); /** * Creates an IntersectionIndexQuery object from a collection of * IndexQuery objects. * * @param subIndexQueries * A collection of IndexQuery objects. * @return An IntersectionIndexQuery object. */ public static IndexQuery createIntersectionIndexQuery( Collection<IndexQuery> subIndexQueries) { return new IntersectionIndexQuery(subIndexQueries); } /** * Creates a union IndexQuery object from a collection of IndexQuery * objects. * * @param subIndexQueries * Collection of IndexQuery objects. * @return A UnionIndexQuery object. */ public static IndexQuery createUnionIndexQuery( Collection<IndexQuery> subIndexQueries) { return new UnionIndexQuery(subIndexQueries); } /** * Creates an empty IndexQuery object. * * @return A NullIndexQuery object. */ public static IndexQuery createNullIndexQuery() { return new NullIndexQuery(); } /** * This class creates a Null IndexQuery. It is used when there is no * record in the index. It may also be used when the index contains * all the records but an empty EntryIDSet should be returned as part * of the optimization. */ private static final class NullIndexQuery extends IndexQuery { /** * {@inheritDoc} * @param debugMessages */ @Override public EntryIDSet evaluate(List<Message> debugMessages) { return new EntryIDSet(); } } /** * This class creates an intersection IndexQuery from a collection of * IndexQuery objects. */ private static final class IntersectionIndexQuery extends IndexQuery { /** * Collection of IndexQuery objects. */ private final Collection<IndexQuery> subIndexQueries; /** * Creates an instance of IntersectionIndexQuery. * * @param subIndexQueries * Collection of IndexQuery objects. */ private IntersectionIndexQuery(Collection<IndexQuery> subIndexQueries) { this.subIndexQueries = subIndexQueries; } /** * {@inheritDoc} * @param debugMessages */ @Override public EntryIDSet evaluate(List<Message> debugMessages) { EntryIDSet entryIDs = null; for (IndexQuery query : subIndexQueries) { if (entryIDs == null) { entryIDs = query.evaluate(debugMessages); } else { entryIDs.retainAll(query.evaluate(debugMessages)); } if (entryIDs.isDefined() && entryIDs.size() <= FILTER_CANDIDATE_THRESHOLD) { break; } } return entryIDs; } } /** * This class creates a union of IndexQuery objects. */ private static final class UnionIndexQuery extends IndexQuery { /** * Collection containing IndexQuery objects. */ private final Collection<IndexQuery> subIndexQueries; /** * Creates an instance of UnionIndexQuery. * * @param subIndexQueries * The Collection of IndexQuery objects. */ private UnionIndexQuery(Collection<IndexQuery> subIndexQueries) { this.subIndexQueries = subIndexQueries; } /** * {@inheritDoc} * @param debugMessages */ @Override public EntryIDSet evaluate(List<Message> debugMessages) { EntryIDSet entryIDs = null; for (IndexQuery query : subIndexQueries) { if (entryIDs == null) { entryIDs = query.evaluate(debugMessages); } else { entryIDs.addAll(query.evaluate(debugMessages)); } if (entryIDs.isDefined() && entryIDs.size() <= FILTER_CANDIDATE_THRESHOLD) { break; } } return entryIDs; } } }