From: <tho...@us...> - 2010-08-21 01:16:21
|
Revision: 3456 http://bigdata.svn.sourceforge.net/bigdata/?rev=3456&view=rev Author: thompsonbry Date: 2010-08-21 01:16:12 +0000 (Sat, 21 Aug 2010) Log Message: ----------- Further cleanup of the IJoinNexus and IRelation implementations. Modified Paths: -------------- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/relation/AbstractRelation.java branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/relation/IRelation.java branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/relation/RelationFusedView.java branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/relation/rule/eval/AbstractJoinNexus.java branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/search/FullTextIndex.java branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/ap/MockJoinNexus.java branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/ap/R.java branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/ap/TestPredicateAccessPath.java branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/relation/locator/TestDefaultResourceLocator.java branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/lexicon/LexiconRelation.java branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/rules/RDFJoinNexus.java branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/spo/SPORelation.java Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/relation/AbstractRelation.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/relation/AbstractRelation.java 2010-08-20 20:43:44 UTC (rev 3455) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/relation/AbstractRelation.java 2010-08-21 01:16:12 UTC (rev 3456) @@ -31,7 +31,10 @@ import java.util.Properties; import java.util.UUID; +import com.bigdata.bop.IPredicate; import com.bigdata.btree.IIndex; +import com.bigdata.btree.ILocalBTreeView; +import com.bigdata.btree.IRangeQuery; import com.bigdata.btree.IndexMetadata; import com.bigdata.btree.UnisolatedReadWriteIndex; import com.bigdata.journal.ConcurrencyManager; @@ -40,6 +43,9 @@ import com.bigdata.journal.Journal; import com.bigdata.journal.TemporaryRawStore; import com.bigdata.journal.TemporaryStore; +import com.bigdata.relation.accesspath.AccessPath; +import com.bigdata.relation.accesspath.IAccessPath; +import com.bigdata.service.DataService; import com.bigdata.service.IBigdataFederation; import com.bigdata.striterator.IKeyOrder; @@ -184,4 +190,166 @@ } + public IAccessPath<E> getAccessPath(final IPredicate<E> predicate) { + + // find the best key order. + final IKeyOrder<E> keyOrder = getKeyOrder(predicate); + + // get the corresponding index. + final IIndex ndx = getIndex(keyOrder); + + // default flags. + final int flags = IRangeQuery.DEFAULT; + + return new AccessPath<E>(this/* relation */, getIndexManager(), + getTimestamp(), predicate, keyOrder, ndx, flags, + getChunkOfChunksCapacity(), getChunkCapacity(), + getFullyBufferedReadThreshold()).init(); + + } + + /** + * This handles a request for an access path that is restricted to a + * specific index partition. + * <p> + * Note: This path is used with the scale-out JOIN strategy, which + * distributes join tasks onto each index partition from which it needs to + * read. Those tasks constrain the predicate to only read from the index + * partition which is being serviced by that join task. + * <p> + * Note: Since the relation may materialize the index views for its various + * access paths, and since we are restricted to a single index partition and + * (presumably) an index manager that only sees the index partitions local + * to a specific data service, we create an access path view for an index + * partition without forcing the relation to be materialized. + * <p> + * Note: Expanders ARE NOT applied in this code path. Expanders require a + * total view of the relation, which is not available during scale-out + * pipeline joins. + * + * @param indexManager + * This MUST be the data service local index manager so that the + * returned access path will read against the local shard. + * @param predicate + * The predicate. {@link IPredicate#getPartitionId()} MUST return + * a valid index partition identifier. + * + * @throws IllegalArgumentException + * if either argument is <code>null</code>. + * @throws IllegalArgumentException + * unless the {@link IIndexManager} is a <em>local</em> index + * manager providing direct access to the specified shard. + * @throws IllegalArgumentException + * unless the predicate identifies a specific shard using + * {@link IPredicate#getPartitionId()}. + * + * @todo Raise this method into the {@link IRelation} interface. + */ + public IAccessPath<E> getAccessPathForIndexPartition( + final IIndexManager indexManager, // + final IPredicate<E> predicate// + ) { + + /* + * Note: getIndexManager() _always_ returns the federation's index + * manager because that is how we materialize an ILocatableResource when + * we locate it. However, the federation's index manager can not be used + * here because it addresses the scale-out indices. Instead, the caller + * must pass in the IIndexManager which has access to the local index + * objects so we can directly read on the shard. + */ +// final IIndexManager indexManager = getIndexManager(); + + if (indexManager == null) + throw new IllegalArgumentException(); + + if (indexManager instanceof IBigdataFederation<?>) { + + /* + * This will happen if you fail to re-create the JoinNexus within + * the target execution environment. + * + * This is disallowed because the predicate specifies an index + * partition and expects to have access to the local index objects + * for that index partition. However, the index partition is only + * available when running inside of the ConcurrencyManager and when + * using the IndexManager exposed by the ConcurrencyManager to its + * tasks. + */ + + throw new IllegalArgumentException( + "Expecting a local index manager, not: " + + indexManager.getClass().toString()); + + } + + if (predicate == null) + throw new IllegalArgumentException(); + + final int partitionId = predicate.getPartitionId(); + + if (partitionId == -1) // must be a valid partition identifier. + throw new IllegalArgumentException(); + + /* + * @todo This condition should probably be an error since the expander + * will be ignored. + */ +// if (predicate.getSolutionExpander() != null) +// throw new IllegalArgumentException(); + + if (predicate.getRelationCount() != 1) { + + /* + * This is disallowed. The predicate must be reading on a single + * local index partition, not a view comprised of more than one + * index partition. + * + * @todo In fact, we could allow a view here as long as all parts of + * the view are local. That could be relevant when the other view + * component was a shard of a focusStore for parallel decomposition + * of RDFS closure, etc. The best way to handle such views when the + * components are not local is to use a UNION of the JOIN. When both + * parts are local we can do better using a UNION of the + * IAccessPath. + */ + + throw new IllegalStateException(); + + } + + final String namespace = getNamespace();//predicate.getOnlyRelationName(); + + /* + * Find the best access path for that predicate. + */ + final IKeyOrder<E> keyOrder = getKeyOrder(predicate); + + // The name of the desired index partition. + final String name = DataService.getIndexPartitionName(namespace + "." + + keyOrder.getIndexName(), predicate.getPartitionId()); + + /* + * Note: whether or not we need both keys and values depends on the + * specific index/predicate. + * + * Note: If the timestamp is a historical read, then the iterator will + * be read only regardless of whether we specify that flag here or not. + */ +// * Note: We can specify READ_ONLY here since the tail predicates are not +// * mutable for rule execution. + final int flags = IRangeQuery.KEYS | IRangeQuery.VALS;// | IRangeQuery.READONLY; + + final long timestamp = getTimestamp();//getReadTimestamp(); + + // MUST be a local index view. + final ILocalBTreeView ndx = (ILocalBTreeView) indexManager + .getIndex(name, timestamp); + + return new AccessPath<E>(this/* relation */, indexManager, timestamp, + predicate, keyOrder, ndx, flags, getChunkOfChunksCapacity(), + getChunkCapacity(), getFullyBufferedReadThreshold()).init(); + + } + } Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/relation/IRelation.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/relation/IRelation.java 2010-08-20 20:43:44 UTC (rev 3455) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/relation/IRelation.java 2010-08-21 01:16:12 UTC (rev 3456) @@ -61,15 +61,86 @@ /** * The {@link IIndexManager} for the {@link IRelation}. */ - public IIndexManager getIndexManager(); + IIndexManager getIndexManager(); /** * The service used to run asynchronous or parallel tasks for the * {@link IRelation}. */ - public ExecutorService getExecutorService(); + ExecutorService getExecutorService(); /** + * Return the class for the generic type of this relation. This information + * is used to dynamically create arrays of that generic type. + */ + Class<E> getElementClass(); + + /** + * Create and return a new element. The element is constructed from the + * predicate given the bindings. Typically, this is used when generating an + * {@link ISolution} for an {@link IRule} during either a query or mutation + * operations. The element is NOT inserted into the relation. + * + * @param predicate + * The predicate that is the head of some {@link IRule}. + * @param bindingSet + * A set of bindings for that {@link IRule}. + * + * @return The new element. + * + * @throws IllegalArgumentException + * if any parameter is <code>null</code>. + * @throws IllegalStateException + * if the predicate is not fully bound given those bindings. + */ + E newElement(IPredicate<E> predicate, IBindingSet bindingSet); + + /** + * Return the {@link IKeyOrder} for the primary index for the relation. + */ + IKeyOrder<E> getPrimaryKeyOrder(); + + /** + * Return the fully qualified name of each index maintained by this + * relation. + * + * @return An immutable set of the index names for the relation. + * + * @deprecated Replace with getKeyOrders() (see below). + */ + Set<String> getIndexNames(); + +// /** +// * Return the {@link IKeyOrder}s corresponding to the registered indices for +// * this relation. [rather than getIndexNames?] +// */ +// Iterator<IKeyOrder<E>> getKeyOrders(); + + /** + * Return the {@link IKeyOrder} for the predicate corresponding to the + * perfect access path. A perfect access path is one where the bound values + * in the predicate form a prefix in the key space of the corresponding + * index. + * + * @param p + * The predicate. + * + * @return The {@link IKeyOrder} for the perfect access path -or- + * <code>null</code> if there is no index which provides a perfect + * access path for that predicate. + * + * @todo What about "best" versus "perfect"? Perfect is more a concept from + * RDF with covering indices. For other schemas we will often just + * have "best". If you only have one index then it is always "best". + * <p> + * Note that one of the main uses for this is query optimization. + * However, runtime query optimization can just work through the + * possible indices and join orders and get to a "best" query plan + * given the actual indices and foreign keys. + */ + IKeyOrder<E> getKeyOrder(IPredicate<E> p); + + /** * Return the best {@link IAccessPath} for a relation given a predicate with * zero or more unbound variables. * <p> @@ -104,7 +175,11 @@ */ IAccessPath<E> getAccessPath(IPredicate<E> predicate); - // @todo raise this method into this interface. + /* + * @todo raise this method into this interface. it is currently implemented + * by AbstractRelation and overridden by SPORelation to handle the different + * index families for triples versus quads. + */ // IAccessPath<E> getAccessPathForIndexPartition(IIndexManager indexManager, IPredicate<E> predicate); /** @@ -131,73 +206,4 @@ */ IIndex getIndex(IKeyOrder<? extends E> keyOrder); - /** - * Return the fully qualified name of each index maintained by this - * relation. - * - * @return An immutable set of the index names for the relation. - * - * @todo replace with getKeyOrders()? - */ - Set<String> getIndexNames(); - - /* - * New methods. - */ - - /** - * Return the {@link IKeyOrder} for the primary index for the relation. - */ - IKeyOrder<E> getPrimaryKeyOrder(); - -// /** -// * Return the {@link IKeyOrder}s corresponding to the registered indices for -// * this relation. [rather than getIndexNames?] -// */ -// Iterator<IKeyOrder<E>> getKeyOrders(); -// -// /** -// * Return the {@link IKeyOrder} for the predicate corresponding to the -// * perfect (best?) access path. A perfect access path is one where the bound values -// * in the predicate form a prefix in the key space of the corresponding -// * index. -// * -// * @param p -// * The predicate. -// * @return The {@link IKeyOrder} for the perfect access path -or- -// * <code>null</code> if there is no index which provides a perfect -// * access path for that predicate. -// */ -// IKeyOrder<E> getKeyOrder(IPredicate<E> p); - - /* - * End new methods. - */ - - /** - * Create and return a new element. The element is constructed from the - * predicate given the bindings. Typically, this is used when generating an - * {@link ISolution} for an {@link IRule} during either a query or mutation - * operations. The element is NOT inserted into the relation. - * - * @param predicate - * The predicate that is the head of some {@link IRule}. - * @param bindingSet - * A set of bindings for that {@link IRule}. - * - * @return The new element. - * - * @throws IllegalArgumentException - * if any parameter is <code>null</code>. - * @throws IllegalStateException - * if the predicate is not fully bound given those bindings. - */ - E newElement(IPredicate<E> predicate, IBindingSet bindingSet); - - /** - * Return the class for the generic type of this relation. This information - * is used to dynamically create arrays of that generic type. - */ - Class<E> getElementClass(); - } Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/relation/RelationFusedView.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/relation/RelationFusedView.java 2010-08-20 20:43:44 UTC (rev 3455) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/relation/RelationFusedView.java 2010-08-21 01:16:12 UTC (rev 3456) @@ -204,4 +204,8 @@ throw new UnsupportedOperationException(); } + public IKeyOrder<E> getKeyOrder(IPredicate<E> p) { + throw new UnsupportedOperationException(); + } + } Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/relation/rule/eval/AbstractJoinNexus.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/relation/rule/eval/AbstractJoinNexus.java 2010-08-20 20:43:44 UTC (rev 3455) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/relation/rule/eval/AbstractJoinNexus.java 2010-08-21 01:16:12 UTC (rev 3456) @@ -42,6 +42,8 @@ import com.bigdata.bop.IPredicate; import com.bigdata.bop.IVariable; import com.bigdata.bop.IVariableOrConstant; +import com.bigdata.btree.keys.DelegateSortKeyBuilder; +import com.bigdata.btree.keys.ISortKeyBuilder; import com.bigdata.config.Configuration; import com.bigdata.config.IValidator; import com.bigdata.config.IntegerValidator; @@ -52,9 +54,11 @@ import com.bigdata.journal.Journal; import com.bigdata.journal.TemporaryStore; import com.bigdata.mdi.PartitionLocator; +import com.bigdata.relation.AbstractRelation; import com.bigdata.relation.AbstractResource; import com.bigdata.relation.IMutableRelation; import com.bigdata.relation.IRelation; +import com.bigdata.relation.RelationFusedView; import com.bigdata.relation.accesspath.AccessPath; import com.bigdata.relation.accesspath.BlockingBuffer; import com.bigdata.relation.accesspath.IAccessPath; @@ -70,6 +74,8 @@ import com.bigdata.service.DataService; import com.bigdata.service.IBigdataFederation; import com.bigdata.service.ndx.IClientIndex; +import com.bigdata.striterator.ChunkedConvertingIterator; +import com.bigdata.striterator.DistinctFilter; import com.bigdata.striterator.IChunkedOrderedIterator; /** @@ -305,9 +311,6 @@ */ public IRelation getHeadRelationView(final IPredicate pred) { -// if (pred == null) -// throw new IllegalArgumentException(); - if (pred.getRelationCount() != 1) throw new IllegalArgumentException(); @@ -316,78 +319,38 @@ final long timestamp = (getAction().isMutation() ? getWriteTimestamp() : getReadTimestamp(/*relationName*/)); - final IRelation relation = (IRelation) resourceLocator.locate( - relationName, timestamp); - - if(log.isDebugEnabled()) { - - log.debug("predicate: "+pred+", head relation: "+relation); - - } - - return relation; - + return (IRelation<?>) resourceLocator.locate(relationName, timestamp); + } -// /** -// * The tail relations are the views from which we read. This method depends -// * solely on the name(s) of the relation(s) and the timestamp of interest -// * for the view. -// * -// * @todo we can probably get rid of the cache used by this method now that -// * calling this method has been factored out of the join loops. -// */ -// @SuppressWarnings("unchecked") -// public IRelation getTailRelationView(final IPredicate pred) { -// -//// if (pred == null) -//// throw new IllegalArgumentException(); -// -// final int nsources = pred.getRelationCount(); -// -// final IRelation relation; -// -// if (nsources == 1) { -// -// final String relationName = pred.getOnlyRelationName(); -// -// relation = (IRelation) resourceLocator.locate(relationName, -// readTimestamp); -// -// } else if (nsources == 2) { -// -// final String relationName0 = pred.getRelationName(0); -// -// final String relationName1 = pred.getRelationName(1); -// -//// final long timestamp0 = getReadTimestamp(/*relationName0*/); -//// -//// final long timestamp1 = getReadTimestamp(/*relationName1*/); -// -// final IRelation relation0 = (IRelation) resourceLocator.locate( -// relationName0, readTimestamp);//timestamp0); -// -// final IRelation relation1 = (IRelation) resourceLocator.locate( -// relationName1, readTimestamp);//timestamp1); -// -// relation = new RelationFusedView(relation0, relation1).init(); -// -// } else { -// -// throw new UnsupportedOperationException(); -// -// } -// -// if(log.isDebugEnabled()) { -// -// log.debug("predicate: "+pred+", tail relation: "+relation); -// -// } -// -// return relation; -// -// } + @SuppressWarnings("unchecked") + public IRelation getTailRelationView(final IPredicate pred) { + final int nsources = pred.getRelationCount(); + + if (nsources == 1) { + + return (IRelation) resourceLocator.locate(pred + .getOnlyRelationName(), getReadTimestamp()); + + } else if (nsources == 2) { + + final IRelation<?> relation0 = (IRelation) resourceLocator.locate( + pred.getRelationName(0), readTimestamp); + + final IRelation<?> relation1 = (IRelation) resourceLocator.locate( + pred.getRelationName(1), readTimestamp); + + return new RelationFusedView(relation0, relation1).init(); + + } else { + + throw new UnsupportedOperationException(); + + } + + } + /** * @deprecated by {@link #getTailAccessPath(IRelation, IPredicate)} * @@ -402,94 +365,43 @@ } -// /** -// * When {@link #backchain} is <code>true</code> and the tail predicate is -// * reading on the {@link SPORelation}, then the {@link IAccessPath} is -// * wrapped so that the iterator will visit the backchained inferences as -// * well. On the other hand, if {@link IPredicate#getPartitionId()} is -// * defined (not <code>-1</code>) then the returned access path will be for -// * the specified shard using the data service local index manager ( -// * {@link #indexManager} MUST be the data service local index manager for -// * this case) and expanders WILL NOT be applied (they require a view of the -// * total relation, not just a shard). -// * -// * @see InferenceEngine -// * @see BackchainAccessPath -// * -// * @todo consider encapsulating the {@link IRangeCountFactory} in the -// * returned access path for non-exact range count requests. this will -// * make it slightly harder to write the unit tests for the -// * {@link IEvaluationPlanFactory} -// */ -// public IAccessPath getTailAccessPath(final IRelation relation, -// final IPredicate predicate) { -// -// if (predicate.getPartitionId() != -1) { -// -// /* -// * Note: This handles a read against a local index partition. For -// * scale-out, the [indexManager] will be the data service's local -// * index manager. -// * -// * Note: Expanders ARE NOT applied in this code path. Expanders -// * require a total view of the relation, which is not available -// * during scale-out pipeline joins. Likewise, the [backchain] -// * property will be ignored since it is handled by an expander. -// * -// * @todo If getAccessPathForIndexPartition() is raised into the -// * IRelation interface, then we can get rid of the cast to the -// * SPORelation implementation. -// */ -// -// return ((SPORelation) relation).getAccessPathForIndexPartition( -// indexManager, predicate); -// -// } -// -//// // Find the best access path for the predicate for that relation. -// IAccessPath accessPath = relation.getAccessPath(predicate); -//// -//// if (predicate.getPartitionId() != -1) { -//// -//// /* -//// * Note: The expander can not run against a shard since it assumes -//// * access to the full key range of the index. Expanders are -//// * convenient and work well for stand alone indices, but they should -//// * be replaced by rule rewrites for scale-out. -//// */ -//// -//// return accessPath; -//// -//// } -// + public IAccessPath getTailAccessPath(final IRelation relation, + final IPredicate predicate) { + + if (predicate.getPartitionId() != -1) { + + /* + * Note: This handles a read against a local index partition. For + * scale-out, the [indexManager] will be the data service's local + * index manager. + * + * Note: Expanders ARE NOT applied in this code path. Expanders + * require a total view of the relation, which is not available + * during scale-out pipeline joins. Likewise, the [backchain] + * property will be ignored since it is handled by an expander. + */ + + return ((AbstractRelation<?>) relation) + .getAccessPathForIndexPartition(indexManager, predicate); + + } + + // Find the best access path for the predicate for that relation. + final IAccessPath<?> accessPath = relation.getAccessPath(predicate); + + // Note: No expander's for bops, at least not right now. // final ISolutionExpander expander = predicate.getSolutionExpander(); // // if (expander != null) { // -// // allow the predicate to wrap the access path : @todo caching on AP? +// // allow the predicate to wrap the access path // accessPath = expander.getAccessPath(accessPath); // // } -// -// if(backchain && relation instanceof SPORelation) { -// -// if (expander == null || expander.backchain()) { -// -// final SPORelation spoRelation = (SPORelation)relation; -// -// accessPath = new BackchainAccessPath( -// spoRelation.getContainer(), accessPath, -// joinNexusFactory.isOwlSameAsUsed ? Boolean.TRUE -// : Boolean.FALSE); -// -// } -// -// } -// -// // return that access path. -// return accessPath; -// -// } + + // return that access path. + return accessPath; + } public Iterator<PartitionLocator> locatorScan( final AbstractScaleOutFederation<?> fed, @@ -505,15 +417,8 @@ * Find the best access path for the predicate for that relation. * * Note: All we really want is the [fromKey] and [toKey] for that - * predicate and index. In general, that information is available from - * IKeyOrder#getFromKey() and IKeyOrder#getToKey(). However, we also - * need to know whether quads or triples are being used for RDF and that - * information is carried by the AbstractTripleStore container or the - * SPORelation. - * - * Note: This MUST NOT layer on expander or backchain access path - * overlays. Those add overhead during construction and the layering - * also hides the [fromKey] and [toKey]. + * predicate and index. This MUST NOT layer on expanders since the + * layering also hides the [fromKey] and [toKey]. */ @SuppressWarnings("unchecked") final AccessPath<?> accessPath = (AccessPath<?>) relation @@ -614,54 +519,6 @@ } -// /** -// * FIXME unit tests for DISTINCT with a head and ELEMENT, with bindings and -// * a head, with bindings but no head, and with a head but no bindings -// * (error). See {@link #runQuery(IStep)} -// * -// * FIXME unit tests for SORT with and without DISTINCT and with the various -// * combinations used in the unit tests for DISTINCT. Note that SORT, unlike -// * DISTINCT, requires that all solutions are materialized before any -// * solutions can be returned to the caller. A lot of optimization can be -// * done for SORT implementations, including merge sort of large blocks (ala -// * map/reduce), using compressed sort keys or word sort keys with 2nd stage -// * disambiguation, etc. -// * -// * FIXME Add property for sort {ascending,descending,none} to {@link IRule}. -// * The sort order can also be specified in terms of a sequence of variables. -// * The choice of the variable order should be applied here. -// * -// * FIXME The properties that govern the Unicode collator for the generated -// * sort keys should be configured by the {@link RDFJoinNexusFactory}. In -// * particular, Unicode should be handled however it is handled for the -// * {@link LexiconRelation}. -// */ -// public ISortKeyBuilder<IBindingSet> newBindingSetSortKeyBuilder(final IRule rule) { -// -// final IKeyBuilder keyBuilder = KeyBuilder.newUnicodeInstance(); -// -// final int nvars = rule.getVariableCount(); -// -// final IVariable[] vars = new IVariable[nvars]; -// -// { -// -// final Iterator<IVariable> itr = rule.getVariables(); -// -// int i = 0; -// -// while (itr.hasNext()) { -// -// vars[i++] = itr.next(); -// -// } -// -// } -// -// return new BindingSetSortKeyBuilder(keyBuilder, vars); -// -// } - /** * FIXME Custom serialization for solution sets, especially since there * tends to be a lot of redundancy in the data arising from how bindings are @@ -807,201 +664,38 @@ } -// /** -// * Buffer writes on {@link IMutableRelation#insert(IChunkedIterator)} when it is -// * {@link #flush() flushed}. -// * -// * @author <a href="mailto:tho...@us...">Bryan Thompson</a> -// * @version $Id$ -// * @param <E> -// */ -// public static class InsertSPOAndJustificationBuffer<E> extends AbstractSolutionBuffer<E> { -// -// /** -// * @param capacity -// * @param relation -// */ -// public InsertSPOAndJustificationBuffer(final int capacity, -// final IMutableRelation<E> relation) { -// -// super(capacity, relation); -// -// } -// -// @Override -// protected long flush(final IChunkedOrderedIterator<ISolution<E>> itr) { -// -// try { -// -// /* -// * The mutation count is the #of SPOs written (there is one -// * justification written per solution generated, but the -// * mutation count does not reflect duplicate justifications - -// * only duplicate statements). -// * -// * Note: the optional filter for the ctor was already applied. -// * If an element/solution was rejected, then it is not in the -// * buffer and we will never see it during flush(). -// */ -// -// long mutationCount = 0; -// -// while (itr.hasNext()) { -// -// final ISolution<E>[] chunk = itr.nextChunk(); -// -// mutationCount += writeChunk(chunk); -// -// } -// -// return mutationCount; -// -// } finally { -// -// itr.close(); -// -// } -// -// } -// -// private long writeChunk(final ISolution<E>[] chunk) { -// -// final int n = chunk.length; -// -// if(log.isDebugEnabled()) -// log.debug("chunkSize="+n); -// -// final long begin = System.currentTimeMillis(); -// -// final SPO[] a = new SPO[ n ]; -// -// final Justification[] b = new Justification[ n ]; -// -// for(int i=0; i<chunk.length; i++) { -// -// if(log.isDebugEnabled()) { -// -// log.debug("chunk["+i+"] = "+chunk[i]); -// -// } -// -// final ISolution<SPO> solution = (ISolution<SPO>) chunk[i]; -// -// a[i] = solution.get(); -// -// b[i] = new Justification(solution); -// -// } -// -// final SPORelation r = (SPORelation) (IMutableRelation) getRelation(); -// -// /* -// * Use a thread pool to write out the statement and the -// * justifications concurrently. This drammatically reduces the -// * latency when also writing justifications. -// */ -// -// final List<Callable<Long>> tasks = new ArrayList<Callable<Long>>(2); -// -// /* -// * Note: we reject using the filter before stmts or justifications -// * make it into the buffer so we do not need to apply the filter -// * again here. -// */ -// -// tasks.add(new Callable<Long>(){ -// public Long call() { -// return r.insert(a,a.length,null/*filter*/); -// } -// }); -// -// tasks.add(new Callable<Long>(){ -// public Long call() { -// return r -// .addJustifications(new ChunkedArrayIterator<Justification>( -// b.length, b, null/* keyOrder */)); -// } -// }); -// -// final List<Future<Long>> futures; -// -// /* -// * @todo The timings for the tasks that we run here are not being -// * reported up to this point. -// */ -// final long mutationCount; -// try { -// -// futures = r.getExecutorService().invokeAll(tasks); -// -// mutationCount = futures.get(0).get(); -// -// futures.get(1).get(); -// -// } catch (InterruptedException ex) { -// -// throw new RuntimeException(ex); -// -// } catch (ExecutionException ex) { -// -// throw new RuntimeException(ex); -// -// } -// -// final long elapsed = System.currentTimeMillis() - begin; -// -// if (log.isInfoEnabled()) -// log.info("Wrote " + mutationCount -// + " statements and justifications in " -// + elapsed + "ms"); -// -// return mutationCount; -// -// } -// -// } - -// /** -// * Note: {@link #getSolutionFilter()} is applied by -// * {@link #newUnsynchronizedBuffer(IBuffer, int)} and NOT by the buffer -// * returned by this method. -// */ -// @SuppressWarnings("unchecked") -// public IBuffer<ISolution[]> newInsertBuffer(final IMutableRelation relation) { -// -// if (getAction() != ActionEnum.Insert) -// throw new IllegalStateException(); -// -// if (log.isDebugEnabled()) { -// -// log.debug("relation=" + relation); -// -// } -// -// if(justify) { -// -// /* -// * Buffer knows how to write the computed elements on the statement -// * indices and the computed binding sets on the justifications -// * indices. -// */ -// -// return new InsertSPOAndJustificationBuffer(chunkOfChunksCapacity, -// relation); -// -// } -// -// /* -// * Buffer resolves the computed elements and writes them on the -// * statement indices. -// */ -// -// return new AbstractSolutionBuffer.InsertSolutionBuffer( -// chunkOfChunksCapacity, relation); -// -// } + /** + * {@inheritDoc} + * <p> + * Note: {@link #getSolutionFilter()} is applied by + * {@link #newUnsynchronizedBuffer(IBuffer, int)} and NOT by the buffer + * returned by this method. + */ + @SuppressWarnings("unchecked") + public IBuffer<ISolution[]> newInsertBuffer(final IMutableRelation relation) { + if (getAction() != ActionEnum.Insert) + throw new IllegalStateException(); + + if (log.isDebugEnabled()) { + + log.debug("relation=" + relation); + + } + + /* + * Buffer resolves the computed elements and writes them on the + * statement indices. + */ + + return new AbstractSolutionBuffer.InsertSolutionBuffer( + chunkOfChunksCapacity, relation); + + } + /** + * {@inheritDoc} + * <p> * Note: {@link #getSolutionFilter()} is applied by * {@link #newUnsynchronizedBuffer(IBuffer, int)} and NOT by the buffer * returned by this method. @@ -1023,117 +717,125 @@ } -// @SuppressWarnings("unchecked") -// public IChunkedOrderedIterator<ISolution> runQuery(final IStep step) -// throws Exception { -// -// if (step == null) -// throw new IllegalArgumentException(); -// -// if(log.isInfoEnabled()) -// log.info("program="+step.getName()); -// -// if(isEmptyProgram(step)) { -// -// log.warn("Empty program"); -// -// return (IChunkedOrderedIterator<ISolution>) new EmptyProgramTask( -// ActionEnum.Query, step).call(); -// -// } -// -// final IChunkedOrderedIterator<ISolution> itr = (IChunkedOrderedIterator<ISolution>) runProgram( -// ActionEnum.Query, step); -// -// if (step.isRule() && ((IRule) step).getQueryOptions().isDistinct()) { -// -// /* -// * Impose a DISTINCT constraint based on the variable bindings -// * selected by the head of the rule. The DistinctFilter will be -// * backed by a TemporaryStore if more than one chunk of solutions is -// * generated. That TemporaryStore will exist on the client where -// * this method (runQuery) was executed. The TemporaryStore will be -// * finalized and deleted when it is no longer referenced. -// */ -// -// final ISortKeyBuilder<ISolution> sortKeyBuilder; -// -// if (((IRule) step).getHead() != null -// && (solutionFlags & ELEMENT) != 0) { -// -// /* -// * Head exists and elements are requested, so impose DISTINCT -// * based on the materialized elements. -// * -// * FIXME The SPOSortKeyBuilder should be obtained from the head -// * relation. Of course there is one sort key for each access -// * path, but for the purposes of DISTINCT we want the sort key -// * to correspond to the notion of a "primary key" (the -// * distinctions that matter) and it does not matter which sort -// * order but the SPO sort order probably has the least factor of -// * "surprise". -// */ -// -// final int arity = ((IRule)step).getHead().arity(); -// -// sortKeyBuilder = new DelegateSortKeyBuilder<ISolution, ISPO>( -// new SPOSortKeyBuilder(arity)) { -// -// protected ISPO resolve(ISolution solution) { -// -// return (ISPO) solution.get(); -// -// } -// -// }; -// -// } else { -// -// if ((solutionFlags & BINDINGS) != 0) { -// -// /* -// * Bindings were requested so impose DISTINCT based on those -// * bindings. -// */ -// -// sortKeyBuilder = new DelegateSortKeyBuilder<ISolution, IBindingSet>( -// newBindingSetSortKeyBuilder((IRule) step)) { -// -// protected IBindingSet resolve(ISolution solution) { -// -// return solution.getBindingSet(); -// -// } -// -// }; -// -// } else { -// -// throw new UnsupportedOperationException( -// "You must specify BINDINGS since the rule does not have a head: " -// + step); -// -// } -// -// } -// -// return new ChunkedConvertingIterator<ISolution, ISolution>(itr, -// new DistinctFilter<ISolution>(indexManager) { -// -// protected byte[] getSortKey(ISolution e) { -// -// return sortKeyBuilder.getSortKey(e); -// -// } -// -// }); -// -// } -// -// return itr; -// -// } + /** + * Return the {@link ISortKeyBuilder} used to impose DISTINCT on the + * solutions generated by a query. + * + * @param head + * The head of the rule. + * + * @return The {@link ISortKeyBuilder}. + * + * @todo This should be based on bop annotations and a hash table for + * distinct unless it is very high volume and you can wait for the + * first result, in which case a SORT should be selected. For high + * volume with low latency to the first result, use a persistent hash + * table on a temporary store. + */ + abstract protected ISortKeyBuilder<?> newSortKeyBuilder( + final IPredicate<?> head); + @SuppressWarnings("unchecked") + public IChunkedOrderedIterator<ISolution> runQuery(final IStep step) + throws Exception { + + if (step == null) + throw new IllegalArgumentException(); + + if(log.isInfoEnabled()) + log.info("program="+step.getName()); + + if(isEmptyProgram(step)) { + + log.warn("Empty program"); + + return (IChunkedOrderedIterator<ISolution>) new EmptyProgramTask( + ActionEnum.Query, step).call(); + + } + + final IChunkedOrderedIterator<ISolution> itr = (IChunkedOrderedIterator<ISolution>) runProgram( + ActionEnum.Query, step); + + if (step.isRule() && ((IRule) step).getQueryOptions().isDistinct()) { + + /* + * Impose a DISTINCT constraint based on the variable bindings + * selected by the head of the rule. The DistinctFilter will be + * backed by a TemporaryStore if more than one chunk of solutions is + * generated. That TemporaryStore will exist on the client where + * this method (runQuery) was executed. The TemporaryStore will be + * finalized and deleted when it is no longer referenced. + */ + + final ISortKeyBuilder<ISolution> sortKeyBuilder; + + if (((IRule) step).getHead() != null + && (solutionFlags & ELEMENT) != 0) { + + /* + * Head exists and elements are requested, so impose DISTINCT + * based on the materialized elements. + */ + + sortKeyBuilder = new DelegateSortKeyBuilder( + newSortKeyBuilder(((IRule) step).getHead())) { + + protected Object resolve(Object solution) { + + return ((ISolution) solution).get(); + + } + + }; + + } else { + + if ((solutionFlags & BINDINGS) != 0) { + + /* + * Bindings were requested so impose DISTINCT based on those + * bindings. + */ + + sortKeyBuilder = new DelegateSortKeyBuilder<ISolution, IBindingSet>( + newBindingSetSortKeyBuilder((IRule) step)) { + + protected IBindingSet resolve(ISolution solution) { + + return solution.getBindingSet(); + + } + + }; + + } else { + + throw new UnsupportedOperationException( + "You must specify BINDINGS since the rule does not have a head: " + + step); + + } + + } + + return new ChunkedConvertingIterator<ISolution, ISolution>(itr, + new DistinctFilter<ISolution>(indexManager) { + + protected byte[] getSortKey(ISolution e) { + + return sortKeyBuilder.getSortKey(e); + + } + + }); + + } + + return itr; + + } + final public long runMutation(final IStep step) throws Exception { if (step == null) @@ -1284,4 +986,101 @@ // // } +// /** +// * Return <code>true</code> if the <i>relationName</i> is on a +// * {@link TempTripleStore} +// * +// * @todo Rather than parsing the relation name, it would be better to have +// * the temporary store UUIDs explicitly declared. +// */ +// protected boolean isTempStore(String relationName) { +// +// /* This is a typical UUID-based temporary store relation name. +// * +// * 1 2 3 +// * 01234567890123456789012345678901234567 +// * 81ad63b9-2172-45dc-bd97-03b63dfe0ba0kb.spo +// */ +// +// if (relationName.length() > 37) { +// +// /* +// * Could be a relation on a temporary store. +// */ +// if ( relationName.charAt( 8) == '-' // +// && relationName.charAt(13) == '-' // +// && relationName.charAt(18) == '-' // +// && relationName.charAt(23) == '-' // +// && relationName.charAt(38) == '.' // +// ) { +// +// /* +// * Pretty certain to be a relation on a temporary store. +// */ +// +// return true; +// +// } +// +// } +// +// return false; +// +// } + +//// /** +//// * A per-relation reentrant read-write lock allows either concurrent readers +//// * or an writer on the unisolated view of a relation. When we use this lock +//// * we also use {@link ITx#UNISOLATED} reads and writes and +//// * {@link #makeWriteSetsVisible()} is a NOP. +//// */ +//// final private static boolean useReentrantReadWriteLockAndUnisolatedReads = true; +// +// public long getReadTimestamp(String relationName) { +// +//// if (useReentrantReadWriteLockAndUnisolatedReads) { +// +//// if (action.isMutation()) { +//// +//// assert readTimestamp == ITx.UNISOLATED : "readTimestamp="+readTimestamp; +//// +//// } +// +// return readTimestamp; +// +//// } else { +//// +//// /* +//// * When the relation is the focusStore choose {@link ITx#UNISOLATED}. +//// * Otherwise choose whatever was specified to the +//// * {@link RDFJoinNexusFactory}. This is because we avoid doing a +//// * commit on the focusStore and instead just its its UNISOLATED +//// * indices. This is more efficient since they are already buffered +//// * and since we can avoid touching disk at all for small data sets. +//// */ +//// +//// if (isTempStore(relationName)) { +//// +//// return ITx.UNISOLATED; +//// +//// } +//// +//// if (lastCommitTime != 0L && action.isMutation()) { +//// +//// /* +//// * Note: This advances the read-behind timestamp for a local +//// * Journal configuration without the ConcurrencyManager (the +//// * only scenario where we do an explicit commit). +//// */ +//// +//// return TimestampUtility.asHistoricalRead(lastCommitTime); +//// +//// } +//// +//// return readTimestamp; +//// +//// } +// +// } + } Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/search/FullTextIndex.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/search/FullTextIndex.java 2010-08-20 20:43:44 UTC (rev 3455) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/search/FullTextIndex.java 2010-08-21 01:16:12 UTC (rev 3456) @@ -253,16 +253,6 @@ final protected static transient Logger log = Logger .getLogger(FullTextIndex.class); -// /** -// * True iff the {@link #log} level is INFO or less. -// */ -// final protected static boolean INFO = log.isInfoEnabled(); -// -// /** -// * True iff the {@link #log} level is DEBUG or less. -// */ -// final protected static boolean DEBUG = log.isDebugEnabled(); - /** * The backing index. */ @@ -1376,5 +1366,9 @@ public IKeyOrder getPrimaryKeyOrder() { throw new UnsupportedOperationException(); } - + + public IKeyOrder getKeyOrder(IPredicate p) { + throw new UnsupportedOperationException(); + } + } Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/ap/MockJoinNexus.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/ap/MockJoinNexus.java 2010-08-20 20:43:44 UTC (rev 3455) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/ap/MockJoinNexus.java 2010-08-21 01:16:12 UTC (rev 3456) @@ -33,17 +33,10 @@ import com.bigdata.bop.Var; import com.bigdata.btree.keys.ISortKeyBuilder; import com.bigdata.journal.IIndexManager; -import com.bigdata.relation.IMutableRelation; -import com.bigdata.relation.IRelation; -import com.bigdata.relation.accesspath.IAccessPath; -import com.bigdata.relation.accesspath.IBuffer; import com.bigdata.relation.rule.IRule; -import com.bigdata.relation.rule.IStep; import com.bigdata.relation.rule.eval.AbstractJoinNexus; import com.bigdata.relation.rule.eval.IJoinNexus; import com.bigdata.relation.rule.eval.IJoinNexusFactory; -import com.bigdata.relation.rule.eval.ISolution; -import com.bigdata.striterator.IChunkedOrderedIterator; /** * Mock object. @@ -53,9 +46,11 @@ */ class MockJoinNexus extends AbstractJoinNexus implements IJoinNexus { - protected MockJoinNexus(IJoinNexusFactory joinNexusFactory, - IIndexManager indexManager) { + protected MockJoinNexus(final IJoinNexusFactory joinNexusFactory, + final IIndexManager indexManager) { + super(joinNexusFactory, indexManager); + } public IConstant fakeBinding(IPredicate predicate, Var var) { @@ -63,30 +58,15 @@ return null; } - public IAccessPath getTailAccessPath(IRelation relation, IPredicate pred) { - // TODO Auto-generated method stub - return null; - } - - public IRelation getTailRelationView(IPredicate pred) { - // TODO Auto-generated method stub - return null; - } - public ISortKeyBuilder<IBindingSet> newBindingSetSortKeyBuilder(IRule rule) { // TODO Auto-generated method stub return null; } - public IBuffer<ISolution[]> newInsertBuffer(IMutableRelation relation) { + @Override + protected ISortKeyBuilder<?> newSortKeyBuilder(IPredicate<?> head) { // TODO Auto-generated method stub return null; } - - public IChunkedOrderedIterator<ISolution> runQuery(IStep step) - throws Exception { - // TODO Auto-generated method stub - return null; - } - + } Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/ap/R.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/ap/R.java 2010-08-20 20:43:44 UTC (rev 3455) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/ap/R.java 2010-08-21 01:16:12 UTC (rev 3456) @@ -36,13 +36,10 @@ import com.bigdata.bop.IBindingSet; import com.bigdata.bop.IPredicate; import com.bigdata.btree.IIndex; -import com.bigdata.btree.IRangeQuery; import com.bigdata.btree.IndexMetadata; import com.bigdata.journal.IIndexManager; import com.bigdata.relation.AbstractRelation; import com.bigdata.relation.IMutableRelation; -import com.bigdata.relation.accesspath.AccessPath; -import com.bigdata.relation.accesspath.IAccessPath; import com.bigdata.relation.locator.ILocatableResource; import com.bigdata.striterator.AbstractKeyOrder; import com.bigdata.striterator.IChunkedOrderedIterator; @@ -161,6 +158,12 @@ } + public IKeyOrder<E> getKeyOrder(final IPredicate<E> p) { + + return primaryKeyOrder; + + } + /** * Simple insert procedure works fine for a local journal. */ @@ -219,27 +222,4 @@ } - public IAccessPath<E> getAccessPath(final IPredicate<E> predicate) { - - // assume the key order (there is only one) vs looking @ predicate. - final IKeyOrder<E> keyOrder = primaryKeyOrder; - - // get the corresponding index. - final IIndex ndx = getIndex(keyOrder); - - // default flags. - final int flags = IRangeQuery.DEFAULT; - - final AccessPath<E> accessPath = new AccessPath<E>( - this/* relation */, getIndexManager(), getTimestamp(), - predicate, keyOrder, ndx, flags, getChunkOfChunksCapacity(), - getChunkCapacity(), getFullyBufferedReadThreshold()) { - }; - - accessPath.init(); - - return accessPath; - - } - } Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/ap/TestPredicateAccessPath.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/ap/TestPredicateAccessPath.java 2010-08-20 20:43:44 UTC (rev 3455) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/bop/ap/TestPredicateAccessPath.java 2010-08-21 01:16:12 UTC (rev 3456) @@ -224,10 +224,6 @@ * (we can join with an incoming binding set easily enough using * only a single primary index), distincts, selecting only * certain columns, etc. - * - * @todo This is failing because the MockJoinNexus does not have - * the necessary stuff to resolve the relation. Is it time to - * clean IJoinNexus up? */ { Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/relation/locator/TestDefaultResourceLocator.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/relation/locator/TestDefaultResourceLocator.java 2010-08-20 20:43:44 UTC (rev 3455) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/relation/locator/TestDefaultResourceLocator.java 2010-08-21 01:16:12 UTC (rev 3456) @@ -339,6 +339,11 @@ // TODO Auto-generated method stub return null; } + + public IKeyOrder getKeyOrder(IPredicate p) { + // TODO Auto-generated method stub + return null; + } } Modified: branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/lexicon/LexiconRelation.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/lexicon/LexiconRelation.java 2010-08-20 20:43:44 UTC (rev 3455) +++ branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/lexicon/LexiconRelation.java 2010-08-21 01:16:12 UTC (rev 3456) @@ -2707,5 +2707,14 @@ return lexiconConfiguration; } - + + public IKeyOrder<BigdataValue> getKeyOrder(final IPredicate<BigdataValue> p) { + if (p.get(0/* term */).isConstant()) { + return LexiconKeyOrder.TERM2ID; + } else if (p.get(1/* id */).isConstant()) { + return LexiconKeyOrder.ID2TERM; + } + return null; + } + } Modified: branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/rules/RDFJoinNexus.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/rules/RDFJoinNexus.java 2010-08-20 20:43:44 UTC (rev 3455) +++ branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/rules/RDFJoinNexus.java 2010-08-21 01:16:12 UTC (rev 3456) @@ -44,7 +44,6 @@ import com.bigdata.bop.IVariable; import com.bigdata.bop.IVariableOrConstant; import com.bigdata.bop.Var; -import com.bigdata.btree.keys.DelegateSortKeyBuilder; import com.bigdata.btree.keys.IKeyBuilder; import com.bigdata.btree.keys.ISortKeyBuilder; import com.bigdata.btree.keys.KeyBuilder; @@ -56,14 +55,12 @@ import com.bigdata.rdf.lexicon.LexiconRelation; import com.bigdata.rdf.model.BigdataValue; import com.bigdata.rdf.relation.rule.BindingSetSortKeyBuilder; -import com.bigdata.rdf.spo.ISPO; import com.bigdata.rdf.spo.SPO; import com.bigdata.rdf.spo.SPORelation; import com.bigdata.rdf.spo.SPOSortKeyBuilder; import com.bigdata.rdf.store.AbstractTripleStore; import com.bigdata.relation.IMutableRelation; import com.bigdata.relation.IRelation; -import com.bigdata.relation.RelationFusedView; import com.bigdata.relation.accesspath.IAccessPath; import com.bigdata.relation.accesspath.IAsynchronousIterator; import com.bigdata.relation.accesspath.IBuffer; @@ -75,7 +72,6 @@ import com.bigdata.relation.rule.eval.AbstractJoinNexus; import com.bigdata.relation.rule.eval.AbstractSolutionBuffer; import com.bigdata.relation.rule.eval.ActionEnum; -import com.bigdata.relation.rule.eval.EmptyProgramTask; import com.bigdata.relation.rule.eval.IEvaluationPlanFactory; import com.bigdata.relation.rule.eval.IJoinNexus; import com.bigdata.relation.rule.eval.IRangeCountFactory; @@ -83,10 +79,7 @@ import com.bigdata.relation.rule.eval.IRuleStatisticsFactory; import com.bigdata.relation.rule.eval.ISolution; import com.bigdata.relation.rule.eval.RuleStats; -import com.bigdata.service.IBigdataFederation; import com.bigdata.striterator.ChunkedArrayIterator; -import com.bigdata.striterator.ChunkedConvertingIterator; -import com.bigdata.striterator.DistinctFilter; import com.bigdata.striterator.IChunkedIterator; import com.bigdata.striterator.IChunkedOrderedIterator; @@ -126,9 +119,6 @@ * thread-safe and that is designed to store a single chunk of elements, e.g., * in an array E[N]). * - * @todo add an {@link IBinding... [truncated message content] |