From: <tho...@us...> - 2011-01-05 13:51:33
|
Revision: 4054 http://bigdata.svn.sourceforge.net/bigdata/?rev=4054&view=rev Author: thompsonbry Date: 2011-01-05 13:51:25 +0000 (Wed, 05 Jan 2011) Log Message: ----------- Reduced several array capacity constants of 10000 or more to 100 in order to reduce the heap churn during query. Modified Paths: -------------- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/BufferAnnotations.java branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/IPredicate.java branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/btree/AbstractChunkedTupleIterator.java branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/btree/UnisolatedReadWriteIndex.java branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/relation/accesspath/BlockingBuffer.java branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/striterator/IChunkedIterator.java branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/inf/BackchainOwlSameAsIterator.java branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/inf/BackchainOwlSameAsPropertiesPIterator.java branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/inf/BackchainOwlSameAsPropertiesPOIterator.java branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/inf/BackchainOwlSameAsPropertiesSPIterator.java branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/inf/BackchainOwlSameAsPropertiesSPOIterator.java branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/inf/BackchainTypeResourceIterator.java Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/BufferAnnotations.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/BufferAnnotations.java 2011-01-05 13:49:15 UTC (rev 4053) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/BufferAnnotations.java 2011-01-05 13:51:25 UTC (rev 4054) @@ -51,8 +51,10 @@ /** * Default for {@link #CHUNK_OF_CHUNKS_CAPACITY} + * + * @todo Try smaller capacities in benchmarks */ - int DEFAULT_CHUNK_OF_CHUNKS_CAPACITY = 5;//trunk=1000 + int DEFAULT_CHUNK_OF_CHUNKS_CAPACITY = 5;//5;//trunk=1000 /** * Sets the capacity of the {@link IBuffer}[]s used to accumulate a chunk of Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/IPredicate.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/IPredicate.java 2011-01-05 13:49:15 UTC (rev 4053) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/bop/IPredicate.java 2011-01-05 13:51:25 UTC (rev 4054) @@ -42,6 +42,7 @@ import com.bigdata.btree.filter.Advancer; import com.bigdata.btree.filter.TupleFilter; import com.bigdata.mdi.PartitionLocator; +import com.bigdata.rawstore.Bytes; import com.bigdata.relation.IRelation; import com.bigdata.relation.accesspath.AccessPath; import com.bigdata.relation.accesspath.ElementFilter; @@ -258,7 +259,7 @@ * @todo Experiment with this. It should probably be something close to * the branching factor, e.g., 100. */ - int DEFAULT_FULLY_BUFFERED_READ_THRESHOLD = 100;//trunk=20*Bytes.kilobyte32 + int DEFAULT_FULLY_BUFFERED_READ_THRESHOLD = 100;//trunk=20*Bytes.kilobyte32; /** * Specify the {@link IRangeQuery} flags for the {@link IAccessPath} ( Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/btree/AbstractChunkedTupleIterator.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/btree/AbstractChunkedTupleIterator.java 2011-01-05 13:49:15 UTC (rev 4053) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/btree/AbstractChunkedTupleIterator.java 2011-01-05 13:51:25 UTC (rev 4054) @@ -248,7 +248,7 @@ */ protected int getDefaultCapacity() { - return 100000; + return 100;//1000;//100000; } Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/btree/UnisolatedReadWriteIndex.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/btree/UnisolatedReadWriteIndex.java 2011-01-05 13:49:15 UTC (rev 4053) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/btree/UnisolatedReadWriteIndex.java 2011-01-05 13:51:25 UTC (rev 4054) @@ -284,7 +284,7 @@ * main purpose of the capacity is to reduce the contention for the * {@link ReadWriteLock}. */ - final static protected int DEFAULT_CAPACITY = 10000; + final static protected int DEFAULT_CAPACITY = 100;//10000; /** * Creates a view of an unisolated index that will enforce the concurrency Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/relation/accesspath/BlockingBuffer.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/relation/accesspath/BlockingBuffer.java 2011-01-05 13:49:15 UTC (rev 4053) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/relation/accesspath/BlockingBuffer.java 2011-01-05 13:51:25 UTC (rev 4054) @@ -166,12 +166,12 @@ * The default capacity for the internal {@link Queue} on which elements (or * chunks of elements) are buffered. */ - public static transient final int DEFAULT_PRODUCER_QUEUE_CAPACITY = 5000; + public static transient final int DEFAULT_PRODUCER_QUEUE_CAPACITY = 100;//5000; /** * The default minimum chunk size for the chunk combiner. */ - public static transient final int DEFAULT_MINIMUM_CHUNK_SIZE = 10000; + public static transient final int DEFAULT_MINIMUM_CHUNK_SIZE = 100;//10000; /** * The default timeout in milliseconds during which chunks of elements may Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/striterator/IChunkedIterator.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/striterator/IChunkedIterator.java 2011-01-05 13:49:15 UTC (rev 4053) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/striterator/IChunkedIterator.java 2011-01-05 13:51:25 UTC (rev 4054) @@ -61,7 +61,7 @@ * * FIXME This is way too large. */ - int DEFAULT_CHUNK_SIZE = 10000; + int DEFAULT_CHUNK_SIZE = 100;//00; /** * The next element available from the iterator. Modified: branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/inf/BackchainOwlSameAsIterator.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/inf/BackchainOwlSameAsIterator.java 2011-01-05 13:49:15 UTC (rev 4053) +++ branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/inf/BackchainOwlSameAsIterator.java 2011-01-05 13:51:25 UTC (rev 4054) @@ -27,6 +27,8 @@ protected IV sameAs; + final int chunkSize = 100;//10000; + protected IChunkedOrderedIterator<ISPO> src; public BackchainOwlSameAsIterator(IChunkedOrderedIterator<ISPO> src, Modified: branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/inf/BackchainOwlSameAsPropertiesPIterator.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/inf/BackchainOwlSameAsPropertiesPIterator.java 2011-01-05 13:49:15 UTC (rev 4053) +++ branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/inf/BackchainOwlSameAsPropertiesPIterator.java 2011-01-05 13:51:25 UTC (rev 4054) @@ -148,7 +148,7 @@ // use a buffer so that we can do a more efficient batch contains // to filter out existing statements - int chunkSize = 10000; +// int chunkSize = 10000; SPO[] spos = new SPO[chunkSize]; int numSPOs = 0; // create a new link between {s,? sameAs s} X {o,? sameAs o} tuples @@ -199,7 +199,6 @@ } public ISPO[] nextChunk() { - final int chunkSize = 10000; ISPO[] s = new ISPO[chunkSize]; int n = 0; while (hasNext() && n < chunkSize) { Modified: branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/inf/BackchainOwlSameAsPropertiesPOIterator.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/inf/BackchainOwlSameAsPropertiesPOIterator.java 2011-01-05 13:49:15 UTC (rev 4053) +++ branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/inf/BackchainOwlSameAsPropertiesPOIterator.java 2011-01-05 13:51:25 UTC (rev 4054) @@ -100,7 +100,7 @@ // which might be present in the source iterator already // use a buffer so that we can do a more efficient batch contains // to filter out existing statements - int chunkSize = 10000; +// int chunkSize = 10000; SPO[] spos = new SPO[chunkSize]; int numSPOs = 0; // get all of o's sames @@ -112,7 +112,7 @@ db.getAccessPath(null, p, same).iterator(); while (reversePropsIt.hasNext()) { final ISPO reverseProp = reversePropsIt.next(); - // do not add ( s sameAs s ) inferences + // do not add ( s sameAs s ) inferences if (IVUtility.equals(reverseProp.p(), sameAs) && IVUtility.equals(reverseProp.s(), o)) { continue; @@ -229,7 +229,7 @@ // ignore sameAs properties // use a buffer so that we can do a more efficient batch contains // to filter out existing statements - int chunkSize = 10000; +// int chunkSize = 10000; final ISPO[] spos = new ISPO[chunkSize]; int numSPOs = 0; // get all of s's sames @@ -273,7 +273,6 @@ } public ISPO[] nextChunk() { - final int chunkSize = 10000; ISPO[] s = new ISPO[chunkSize]; int n = 0; while (hasNext() && n < chunkSize) { Modified: branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/inf/BackchainOwlSameAsPropertiesSPIterator.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/inf/BackchainOwlSameAsPropertiesSPIterator.java 2011-01-05 13:49:15 UTC (rev 4053) +++ branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/inf/BackchainOwlSameAsPropertiesSPIterator.java 2011-01-05 13:51:25 UTC (rev 4054) @@ -107,7 +107,7 @@ // which might be present in the source iterator already // use a buffer so that we can do a more efficient batch contains // to filter out existing statements - int chunkSize = 10000; +// int chunkSize = 10000; SPO[] spos = new SPO[chunkSize]; int numSPOs = 0; // get all of s's sames @@ -238,7 +238,7 @@ // ignore sameAs properties // use a buffer so that we can do a more efficient batch contains // to filter out existing statements - int chunkSize = 10000; +// int chunkSize = 10000; ISPO[] spos = new ISPO[chunkSize]; int numSPOs = 0; // get all of o's sames @@ -282,7 +282,7 @@ } public ISPO[] nextChunk() { - final int chunkSize = 10000; +// final int chunkSize = 10000; ISPO[] s = new ISPO[chunkSize]; int n = 0; while (hasNext() && n < chunkSize) { Modified: branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/inf/BackchainOwlSameAsPropertiesSPOIterator.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/inf/BackchainOwlSameAsPropertiesSPOIterator.java 2011-01-05 13:49:15 UTC (rev 4053) +++ branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/inf/BackchainOwlSameAsPropertiesSPOIterator.java 2011-01-05 13:51:25 UTC (rev 4054) @@ -108,7 +108,7 @@ // all of which might be present in the source iterator already // use a buffer so that we can do a more efficient batch contains // to filter out existing statements - int chunkSize = 10000; +// int chunkSize = 10000; SPO[] spos = new SPO[chunkSize]; int numSPOs = 0; // collect up the links between {s,? sameAs s} X {o,? sameAs o} @@ -196,7 +196,7 @@ } public ISPO[] nextChunk() { - final int chunkSize = 10000; +// final int chunkSize = 10000; ISPO[] s = new ISPO[chunkSize]; int n = 0; while (hasNext() && n < chunkSize) { Modified: branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/inf/BackchainTypeResourceIterator.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/inf/BackchainTypeResourceIterator.java 2011-01-05 13:49:15 UTC (rev 4053) +++ branches/QUADS_QUERY_BRANCH/bigdata-rdf/src/java/com/bigdata/rdf/inf/BackchainTypeResourceIterator.java 2011-01-05 13:51:25 UTC (rev 4054) @@ -20,7 +20,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ + */ /* * Created on Oct 30, 2007 */ @@ -69,973 +69,984 @@ * * @see InferenceEngine * @see InferenceEngine.Options - * + * * @author <a href="mailto:tho...@us...">Bryan Thompson</a> - * @version $Id$ - */ -public class BackchainTypeResourceIterator implements IChunkedOrderedIterator<ISPO> { + * @version $Id: BackchainTypeResourceIterator.java 3687 2010-09-29 22:50:32Z + * mrpersonick $ + */ +public class BackchainTypeResourceIterator implements + IChunkedOrderedIterator<ISPO> { - protected static final Logger log = Logger.getLogger(BackchainTypeResourceIterator.class); - - private final IChunkedOrderedIterator<ISPO> _src; - private final Iterator<ISPO> src; -// private final long s; -// private final AbstractTripleStore db; - private final IV rdfType, rdfsResource; - private final IKeyOrder<ISPO> keyOrder; + protected static final Logger log = Logger + .getLogger(BackchainTypeResourceIterator.class); - /** - * The subject(s) whose (s rdf:type rdfs:Resource) entailments will be - * visited. - */ - private PushbackIterator<IV> resourceIds; - - /** - * An iterator reading on the {@link SPOKeyOrder#POS} index. The predicate - * is bound to <code>rdf:type</code> and the object is bound to - * <code>rdfs:Resource</code>. If the subject was given to the ctor, then - * it will also be bound. The iterator visits the term identifier for the - * <em>subject</em> position. - */ - private PushbackIterator<IV> posItr; - - private boolean sourceExhausted = false; - - private boolean open = true; + private final IChunkedOrderedIterator<ISPO> _src; + private final Iterator<ISPO> src; + // private final long s; + // private final AbstractTripleStore db; + private final IV rdfType, rdfsResource; + private final IKeyOrder<ISPO> keyOrder; - /** - * This is set each time by {@link #nextChunk()} and inspected by - * {@link #nextChunk(IKeyOrder)} in order to decide whether the chunk needs - * to be sorted. - */ - private IKeyOrder<ISPO> chunkKeyOrder = null; + private final int chunkSize = 100;//10000; - /** - * The last {@link ISPO} visited by {@link #next()}. - */ - private ISPO current = null; + /** + * The subject(s) whose (s rdf:type rdfs:Resource) entailments will be + * visited. + */ + private PushbackIterator<IV> resourceIds; - /** - * Returns a suitably configured {@link BackchainTypeResourceIterator} -or- - * <i>src</i> iff the <i>accessPath</i> does not require the - * materialization of <code>(x rdf:type rdfs:Resource)</code> entailments. - * - * @param _src - * The source iterator. {@link #nextChunk()} will sort statements - * into the {@link IKeyOrder} reported by this iterator (as long - * as the {@link IKeyOrder} is non-<code>null</code>). - * @param accessPath - * The {@link IAccessPath} from which the <i>src</i> iterator - * was derived. Note that <i>src</i> is NOT necessarily - * equivalent to {@link IAccessPath#iterator()} since it MAY have - * been layered already to backchain other entailments, e.g., - * <code>owl:sameAs</code>. - * @param db - * The database from which we will read the distinct subject - * identifiers from its {@link SPORelation}. This parameter is - * used iff this is an all unbound triple pattern. - * @param rdfType - * The term identifier that corresponds to rdf:Type for the - * database. - * @param rdfsResource - * The term identifier that corresponds to rdf:Resource for the - * database. - * - * @return The backchain iterator -or- the <i>src</i> iterator iff the - * <i>accessPath</i> does not require the materialization of - * <code>(x rdf:type rdfs:Resource)</code> entailments. - */ - @SuppressWarnings("unchecked") - static public IChunkedOrderedIterator<ISPO> newInstance( - final IChunkedOrderedIterator<ISPO> _src, - final IAccessPath<ISPO> accessPath, final AbstractTripleStore db, - final IV rdfType, final IV rdfsResource) { - - if (accessPath == null) - throw new IllegalArgumentException(); - -// final SPO spo = new SPO(accessPath.getPredicate()); - final IPredicate<ISPO> pred = accessPath.getPredicate(); - final IV s = getTerm(pred, 0); - final IV p = getTerm(pred, 1); - final IV o = getTerm(pred, 2); + /** + * An iterator reading on the {@link SPOKeyOrder#POS} index. The predicate + * is bound to <code>rdf:type</code> and the object is bound to + * <code>rdfs:Resource</code>. If the subject was given to the ctor, then it + * will also be bound. The iterator visits the term identifier for the + * <em>subject</em> position. + */ + private PushbackIterator<IV> posItr; - if (((o == null || o.equals(rdfsResource)) && - (p == null || p.equals(rdfType))) == false) { - - /* - * Backchain will not generate any statements. - */ + private boolean sourceExhausted = false; - return _src; - - } - - if (_src == null) - throw new IllegalArgumentException(); - - if (db == null) - throw new IllegalArgumentException(); - - /* - * The subject(s) whose (s rdf:type rdfs:Resource) entailments will be - * visited. - */ - final PushbackIterator<IV> resourceIds; - - /* - * An iterator reading on the {@link SPOKeyOrder#POS} index. The - * predicate is bound to <code>rdf:type</code> and the object is bound - * to <code>rdfs:Resource</code>. If the subject was given to the - * ctor, then it will also be bound. The iterator visits the term - * identifier for the <em>subject</em> position. - */ - final PushbackIterator<IV> posItr; + private boolean open = true; - if (s == null) { + /** + * This is set each time by {@link #nextChunk()} and inspected by + * {@link #nextChunk(IKeyOrder)} in order to decide whether the chunk needs + * to be sorted. + */ + private IKeyOrder<ISPO> chunkKeyOrder = null; - /* - * Backchain will generate one statement for each distinct subject - * or object in the store. - * - * @todo This is Ok as long as you are forward chaining all of the - * rules that put a predicate or an object into the subject position - * since it will then have all resources. If you backward chain some - * of those rules, e.g., rdf1, then you MUST change this to read on - * the ids index and skip anything that is marked as a literal using - * the low bit of the term identifier but you will overgenerate for - * resources that are no longer in use by the KB (you could filter - * for that). - */ + /** + * The last {@link ISPO} visited by {@link #next()}. + */ + private ISPO current = null; -// resourceIds = db.getSPORelation().distinctTermScan(SPOKeyOrder.SPO); - - resourceIds = new PushbackIterator<IV>(new MergedOrderedIterator(// - db.getSPORelation().distinctTermScan(SPOKeyOrder.SPO), // - db.getSPORelation().distinctTermScan(SPOKeyOrder.OSP, - new ITermIVFilter() { - private static final long serialVersionUID = 1L; - public boolean isValid(IV iv) { - // filter out literals from the OSP scan. - return !iv.isLiteral(); - } - }))); + /** + * Returns a suitably configured {@link BackchainTypeResourceIterator} -or- + * <i>src</i> iff the <i>accessPath</i> does not require the materialization + * of <code>(x rdf:type rdfs:Resource)</code> entailments. + * + * @param _src + * The source iterator. {@link #nextChunk()} will sort statements + * into the {@link IKeyOrder} reported by this iterator (as long + * as the {@link IKeyOrder} is non-<code>null</code>). + * @param accessPath + * The {@link IAccessPath} from which the <i>src</i> iterator was + * derived. Note that <i>src</i> is NOT necessarily equivalent to + * {@link IAccessPath#iterator()} since it MAY have been layered + * already to backchain other entailments, e.g., + * <code>owl:sameAs</code>. + * @param db + * The database from which we will read the distinct subject + * identifiers from its {@link SPORelation}. This parameter is + * used iff this is an all unbound triple pattern. + * @param rdfType + * The term identifier that corresponds to rdf:Type for the + * database. + * @param rdfsResource + * The term identifier that corresponds to rdf:Resource for the + * database. + * + * @return The backchain iterator -or- the <i>src</i> iterator iff the + * <i>accessPath</i> does not require the materialization of + * <code>(x rdf:type rdfs:Resource)</code> entailments. + */ + @SuppressWarnings("unchecked") + static public IChunkedOrderedIterator<ISPO> newInstance( + final IChunkedOrderedIterator<ISPO> _src, + final IAccessPath<ISPO> accessPath, final AbstractTripleStore db, + final IV rdfType, final IV rdfsResource) { - /* - * Reading (? rdf:Type rdfs:Resource) using the POS index. - */ + if (accessPath == null) + throw new IllegalArgumentException(); - posItr = new PushbackIterator<IV>(new Striterator(db.getAccessPath( - null, rdfType, rdfsResource, - ExplicitSPOFilter.INSTANCE).iterator()) - .addFilter(new Resolver() { - private static final long serialVersionUID = 1L; - @Override - protected Object resolve(Object obj) { - return ((SPO) obj).s; - } - })); + // final SPO spo = new SPO(accessPath.getPredicate()); + final IPredicate<ISPO> pred = accessPath.getPredicate(); + final IV s = getTerm(pred, 0); + final IV p = getTerm(pred, 1); + final IV o = getTerm(pred, 2); - } else { + if (((o == null || o.equals(rdfsResource)) && (p == null || p + .equals(rdfType))) == false) { - /* - * Backchain will generate exactly one statement: (s rdf:type - * rdfs:Resource). - */ -/* - resourceIds = new PushbackIterator<Long>( - new ClosableSingleItemIterator<Long>(spo.s)); -*/ - /* - * Reading a single point (s type resource), so this will actually - * use the SPO index. - */ -/* - posItr = new PushbackIterator<Long>(new Striterator(db - .getAccessPath(spo.s, rdfType, rdfsResource, - ExplicitSPOFilter.INSTANCE).iterator()) - .addFilter(new Resolver() { - private static final long serialVersionUID = 1L; - @Override - protected Object resolve(Object obj) { - return Long.valueOf(((SPO) obj).s); - } - })); -*/ - return new BackchainSTypeResourceIterator - ( _src, accessPath, db, rdfType, rdfsResource - ); + /* + * Backchain will not generate any statements. + */ - } - - /* - * filters out (x rdf:Type rdfs:Resource) in case it is explicit in the - * db so that we do not generate duplicates for explicit type resource - * statement. - */ - final Iterator<ISPO> src = new Striterator(_src).addFilter(new Filter(){ + return _src; - private static final long serialVersionUID = 1L; + } - public boolean isValid(Object arg0) { + if (_src == null) + throw new IllegalArgumentException(); - final SPO o = (SPO) arg0; + if (db == null) + throw new IllegalArgumentException(); - if (o.p.equals(rdfType) && o.o.equals(rdfsResource)) { - - return false; - - } - - return true; - - }}); - - return new BackchainTypeResourceIterator(_src, src, resourceIds, - posItr, rdfType, rdfsResource); - - } - - private static IV getTerm(final IPredicate<ISPO> pred, final int pos) { - - final IVariableOrConstant<IV> term = pred.get(pos); - - return term == null || term.isVar() ? null : term.get(); - - } - - /** - * Create an iterator that will visit all statements in the source iterator - * and also backchain any entailments of the form (x rdf:type rdfs:Resource) - * which are valid for the given triple pattern. - * - * @param src - * The source iterator. {@link #nextChunk()} will sort statements - * into the {@link IKeyOrder} reported by this iterator (as long - * as the {@link IKeyOrder} is non-<code>null</code>). - * @param db - * The database from which we will read the distinct subject - * identifiers (iff this is an all unbound triple pattern). - * @param rdfType - * The term identifier that corresponds to rdf:Type for the - * database. - * @param rdfsResource - * The term identifier that corresponds to rdf:Resource for the - * database. - * - * @see #newInstance(IChunkedOrderedIterator, IAccessPath, - * AbstractTripleStore, long, long) - */ - @SuppressWarnings({ "unchecked", "serial" }) - private BackchainTypeResourceIterator(IChunkedOrderedIterator<ISPO> _src,// - Iterator<ISPO> src,// - PushbackIterator<IV> resourceIds,// - PushbackIterator<IV> posItr,// - final IV rdfType,// - final IV rdfsResource// - ) { - - // the raw source - we pass close() through to this. - this._src = _src; - - this.keyOrder = _src.getKeyOrder(); // MAY be null. - - // the source with (x type resource) filtered out. - this.src = src; - - // - this.resourceIds = resourceIds; - - this.posItr = posItr; - - this.rdfType = rdfType; - - this.rdfsResource = rdfsResource; - - } + /* + * The subject(s) whose (s rdf:type rdfs:Resource) entailments will be + * visited. + */ + final PushbackIterator<IV> resourceIds; - public IKeyOrder<ISPO> getKeyOrder() { + /* + * An iterator reading on the {@link SPOKeyOrder#POS} index. The + * predicate is bound to <code>rdf:type</code> and the object is bound + * to <code>rdfs:Resource</code>. If the subject was given to the ctor, + * then it will also be bound. The iterator visits the term identifier + * for the <em>subject</em> position. + */ + final PushbackIterator<IV> posItr; - return keyOrder; - - } + if (s == null) { - public void close() { + /* + * Backchain will generate one statement for each distinct subject + * or object in the store. + * + * @todo This is Ok as long as you are forward chaining all of the + * rules that put a predicate or an object into the subject position + * since it will then have all resources. If you backward chain some + * of those rules, e.g., rdf1, then you MUST change this to read on + * the ids index and skip anything that is marked as a literal using + * the low bit of the term identifier but you will overgenerate for + * resources that are no longer in use by the KB (you could filter + * for that). + */ - if(!open) return; - - // release any resources here. - - open = false; + // resourceIds = + // db.getSPORelation().distinctTermScan(SPOKeyOrder.SPO); - _src.close(); + resourceIds = new PushbackIterator<IV>(new MergedOrderedIterator(// + db.getSPORelation().distinctTermScan(SPOKeyOrder.SPO), // + db.getSPORelation().distinctTermScan(SPOKeyOrder.OSP, + new ITermIVFilter() { + private static final long serialVersionUID = 1L; - resourceIds.close(); - - resourceIds = null; - - if (posItr != null) { + public boolean isValid(IV iv) { + // filter out literals from the OSP scan. + return !iv.isLiteral(); + } + }))); - posItr.close(); - - } - - } + /* + * Reading (? rdf:Type rdfs:Resource) using the POS index. + */ - public boolean hasNext() { - - if (!open) { + posItr = new PushbackIterator<IV>(new Striterator(db.getAccessPath( + null, rdfType, rdfsResource, ExplicitSPOFilter.INSTANCE) + .iterator()).addFilter(new Resolver() { + private static final long serialVersionUID = 1L; - // the iterator has been closed. - - return false; - - } + @Override + protected Object resolve(Object obj) { + return ((SPO) obj).s; + } + })); - if (!sourceExhausted) { + } else { - if (src.hasNext()) { + /* + * Backchain will generate exactly one statement: (s rdf:type + * rdfs:Resource). + */ + /* + * resourceIds = new PushbackIterator<Long>( new + * ClosableSingleItemIterator<Long>(spo.s)); + */ + /* + * Reading a single point (s type resource), so this will actually + * use the SPO index. + */ + /* + * posItr = new PushbackIterator<Long>(new Striterator(db + * .getAccessPath(spo.s, rdfType, rdfsResource, + * ExplicitSPOFilter.INSTANCE).iterator()) .addFilter(new Resolver() + * { private static final long serialVersionUID = 1L; + * + * @Override protected Object resolve(Object obj) { return + * Long.valueOf(((SPO) obj).s); } })); + */ + return new BackchainSTypeResourceIterator(_src, accessPath, db, + rdfType, rdfsResource); - // still consuming the source iterator. + } - return true; + /* + * filters out (x rdf:Type rdfs:Resource) in case it is explicit in the + * db so that we do not generate duplicates for explicit type resource + * statement. + */ + final Iterator<ISPO> src = new Striterator(_src) + .addFilter(new Filter() { - } + private static final long serialVersionUID = 1L; - // the source iterator is now exhausted. + public boolean isValid(Object arg0) { - sourceExhausted = true; + final SPO o = (SPO) arg0; - _src.close(); + if (o.p.equals(rdfType) && o.o.equals(rdfsResource)) { - } + return false; - if (resourceIds.hasNext()) { + } - // still consuming the subjects iterator. - - return true; - - } - - // the subjects iterator is also exhausted so we are done. - - return false; - - } + return true; - /** - * Visits all {@link SPO}s visited by the source iterator and then begins - * to backchain ( x rdf:type: rdfs:Resource ) statements. - * <p> - * The "backchain" scans two iterators: an {@link IChunkedOrderedIterator} - * on <code>( ? rdf:type - * rdfs:Resource )</code> that reads on the database - * (this tells us whether we have an explicit - * <code>(x rdf:type rdfs:Resource)</code> in the database for a given - * subject) and iterator that reads on the term identifiers for the distinct - * resources in the database (this bounds the #of backchained statements - * that we will emit). - * <p> - * For each value visited by the {@link #resourceIds} iterator we examine - * the statement iterator. If the next value that would be visited by the - * statement iterator is an explicit statement for the current subject, then - * we emit the explicit statement. Otherwise we emit an inferred statement. - */ - public ISPO next() { + } + }); - if (!hasNext()) { + return new BackchainTypeResourceIterator(_src, src, resourceIds, + posItr, rdfType, rdfsResource); - throw new NoSuchElementException(); - - } + } - if (src.hasNext()) { + private static IV getTerm(final IPredicate<ISPO> pred, final int pos) { - return current = src.next(); - - } else if(resourceIds.hasNext()) { + final IVariableOrConstant<IV> term = pred.get(pos); - /* - * Examine resourceIds and posItr. - */ - - // resourceIds is the source for _inferences_ - final IV s1 = resourceIds.next(); - - if(posItr.hasNext()) { - - // posItr is the source for _explicit_ statements. - final IV s2 = posItr.next(); - - final int cmp = s1.compareTo(s2); - - if (cmp < 0) { + return term == null || term.isVar() ? null : term.get(); - /* - * Consuming from [resourceIds] (the term identifier ordered - * LT the next term identifier from [posItr]). - * - * There is NOT an explicit statement from [posItr], so emit - * as an inference and pushback on [posItr]. - */ - - current = new SPO(s1, rdfType, rdfsResource, - StatementEnum.Inferred); + } - posItr.pushback(); - - } else { - - /* - * Consuming from [posItr]. - * - * There is an explicit statement for the current term - * identifer from [resourceIds]. - */ - - if (cmp != 0) { - - /* - * Since [resourceIds] and [posItr] are NOT visiting the - * same term identifier, we pushback on [resourceIds]. - * - * Note: When they DO visit the same term identifier - * then we only emit the explicit statement and we - * consume (rather than pushback) from [resourceIds]. - */ - - resourceIds.pushback(); - - } - - current = new SPO(s2, rdfType, rdfsResource, - StatementEnum.Explicit); + /** + * Create an iterator that will visit all statements in the source iterator + * and also backchain any entailments of the form (x rdf:type rdfs:Resource) + * which are valid for the given triple pattern. + * + * @param src + * The source iterator. {@link #nextChunk()} will sort statements + * into the {@link IKeyOrder} reported by this iterator (as long + * as the {@link IKeyOrder} is non-<code>null</code>). + * @param db + * The database from which we will read the distinct subject + * identifiers (iff this is an all unbound triple pattern). + * @param rdfType + * The term identifier that corresponds to rdf:Type for the + * database. + * @param rdfsResource + * The term identifier that corresponds to rdf:Resource for the + * database. + * + * @see #newInstance(IChunkedOrderedIterator, IAccessPath, + * AbstractTripleStore, long, long) + */ + @SuppressWarnings( { "unchecked", "serial" }) + private BackchainTypeResourceIterator(IChunkedOrderedIterator<ISPO> _src,// + Iterator<ISPO> src,// + PushbackIterator<IV> resourceIds,// + PushbackIterator<IV> posItr,// + final IV rdfType,// + final IV rdfsResource// + ) { - } - - } else { - - /* - * [posItr] is exhausted so just emit inferences based on - * [resourceIds]. - */ - - current = new SPO(s1, rdfType, rdfsResource, - StatementEnum.Inferred); - - } + // the raw source - we pass close() through to this. + this._src = _src; - return current; + this.keyOrder = _src.getKeyOrder(); // MAY be null. - } else { - - /* - * Finish off the [posItr]. Anything from this source is an explicit (? - * type resource) statement. - */ - - assert posItr.hasNext(); - - return new SPO(posItr.next(), rdfType, rdfsResource, - StatementEnum.Explicit); - - } - - } + // the source with (x type resource) filtered out. + this.src = src; - /** - * Note: This method preserves the {@link IKeyOrder} of the source iterator - * iff it is reported by {@link #getKeyOrder()}. Otherwise chunks read from - * the source iterator will be in whatever order that iterator is using - * while chunks containing backchained entailments will be in - * {@link SPOKeyOrder#POS} order. - * <p> - * Note: In order to ensure that a consistent ordering is always used within - * a chunk the backchained entailments will always begin on a chunk - * boundary. - */ - public ISPO[] nextChunk() { + // + this.resourceIds = resourceIds; - final int chunkSize = 10000; - - if (!hasNext()) - throw new NoSuchElementException(); - - if(!sourceExhausted) { - - /* - * Return a chunk from the source iterator. - * - * Note: The chunk will be in the order used by the source iterator. - * If the source iterator does not report that order then - * [chunkKeyOrder] will be null. - */ - - chunkKeyOrder = keyOrder; + this.posItr = posItr; - ISPO[] s = new ISPO[chunkSize]; + this.rdfType = rdfType; - int n = 0; - - while(src.hasNext() && n < chunkSize ) { - - s[n++] = src.next(); - - } - - ISPO[] stmts = new ISPO[n]; - - // copy so that stmts[] is dense. - System.arraycopy(s, 0, stmts, 0, n); - - return stmts; - - } + this.rdfsResource = rdfsResource; - /* - * Create a "chunk" of entailments. - * - * Note: This chunk will be in natural POS order since that is the index - * that we scan to decide whether or not there was an explicit ( x - * rdf:type rdfs:Resource ) while we consume the [subjects] in termId - * order. - */ - - IV[] s = new IV[chunkSize]; - - int n = 0; - - while(resourceIds.hasNext() && n < chunkSize ) { - - s[n++] = resourceIds.next(); - - } - - SPO[] stmts = new SPO[n]; - - for(int i=0; i<n; i++) { - - stmts[i] = new SPO(s[i], rdfType, rdfsResource, - StatementEnum.Inferred); - - } - - if (keyOrder != null && keyOrder != SPOKeyOrder.POS) { + } - /* - * Sort into the same order as the source iterator. - * - * Note: We have to sort explicitly since we are scanning the POS - * index - */ + public IKeyOrder<ISPO> getKeyOrder() { - Arrays.sort(stmts, 0, stmts.length, keyOrder.getComparator()); + return keyOrder; - } + } - /* - * The chunk will be in POS order since that is how we are scanning the - * indices. - */ - - chunkKeyOrder = SPOKeyOrder.POS; - - return stmts; - - } + public void close() { - public ISPO[] nextChunk(IKeyOrder<ISPO> keyOrder) { - - if (keyOrder == null) - throw new IllegalArgumentException(); + if (!open) + return; - final ISPO[] stmts = nextChunk(); - - if (chunkKeyOrder != keyOrder) { + // release any resources here. - // sort into the required order. + open = false; - Arrays.sort(stmts, 0, stmts.length, keyOrder.getComparator()); + _src.close(); - } + resourceIds.close(); - return stmts; - - } + resourceIds = null; - /** - * Note: You can not "remove" the backchained entailments. If the last - * statement visited by {@link #next()} is "explicit" then the request is - * delegated to the source iterator. - */ - public void remove() { + if (posItr != null) { - if (!open) - throw new IllegalStateException(); - - if (current == null) - throw new IllegalStateException(); - - if(current.isExplicit()) { - - /* - * Delegate the request to the source iterator. - */ - - src.remove(); - - } - - current = null; - - } - - /** - * Reads on two iterators visiting elements in some natural order and visits - * their order preserving merge (no duplicates). - * - * @author <a href="mailto:tho...@us...">Bryan Thompson</a> - * @version $Id$ - * @param <T> - */ - private static class MergedOrderedIterator<T extends Comparable<T>> - implements IChunkedIterator<T> { - - private final IChunkedIterator<T> src1; - private final IChunkedIterator<T> src2; - - public MergedOrderedIterator(IChunkedIterator<T> src1, - IChunkedIterator<T> src2) { + posItr.close(); - this.src1 = src1; - - this.src2 = src2; - - } - - public void close() { - - src1.close(); - - src2.close(); - - } + } - /** - * Note: Not implemented since not used above and this class is private. - */ - public T[] nextChunk() { - throw new UnsupportedOperationException(); - } + } - public boolean hasNext() { + public boolean hasNext() { - return tmp1 != null || tmp2 != null || src1.hasNext() - || src2.hasNext(); - - } - - private T tmp1; - private T tmp2; - - public T next() { + if (!open) { - if(!hasNext()) throw new NoSuchElementException(); - - if (tmp1 == null && src1.hasNext()) { + // the iterator has been closed. - tmp1 = src1.next(); + return false; - } - - if (tmp2 == null && src2.hasNext()) { + } - tmp2 = src2.next(); + if (!sourceExhausted) { - } - - if (tmp1 == null) { + if (src.hasNext()) { - // src1 is exhausted so deliver from src2. - final T tmp = tmp2; + // still consuming the source iterator. - tmp2 = null; + return true; - return tmp; + } - } - - if (tmp2 == null) { + // the source iterator is now exhausted. - // src2 is exhausted so deliver from src1. - final T tmp = tmp1; + sourceExhausted = true; - tmp1 = null; + _src.close(); - return tmp; + } - } + if (resourceIds.hasNext()) { - final int cmp = tmp1.compareTo(tmp2); + // still consuming the subjects iterator. - if (cmp == 0) { + return true; - final T tmp = tmp1; + } - tmp1 = tmp2 = null; + // the subjects iterator is also exhausted so we are done. - return tmp; + return false; - } else if (cmp < 0) { + } - final T tmp = tmp1; + /** + * Visits all {@link SPO}s visited by the source iterator and then begins to + * backchain ( x rdf:type: rdfs:Resource ) statements. + * <p> + * The "backchain" scans two iterators: an {@link IChunkedOrderedIterator} + * on <code>( ? rdf:type + * rdfs:Resource )</code> that reads on the database (this tells us whether + * we have an explicit <code>(x rdf:type rdfs:Resource)</code> in the + * database for a given subject) and iterator that reads on the term + * identifiers for the distinct resources in the database (this bounds the + * #of backchained statements that we will emit). + * <p> + * For each value visited by the {@link #resourceIds} iterator we examine + * the statement iterator. If the next value that would be visited by the + * statement iterator is an explicit statement for the current subject, then + * we emit the explicit statement. Otherwise we emit an inferred statement. + */ + public ISPO next() { - tmp1 = null; + if (!hasNext()) { - return tmp; + throw new NoSuchElementException(); - } else { + } - final T tmp = tmp2; + if (src.hasNext()) { - tmp2 = null; + return current = src.next(); - return tmp; + } else if (resourceIds.hasNext()) { - } - - } + /* + * Examine resourceIds and posItr. + */ - public void remove() { + // resourceIds is the source for _inferences_ + final IV s1 = resourceIds.next(); - throw new UnsupportedOperationException(); - - } + if (posItr.hasNext()) { - } + // posItr is the source for _explicit_ statements. + final IV s2 = posItr.next(); - /** - * Filterator style construct that allows push back of a single visited - * element. - * - * @author <a href="mailto:tho...@us...">Bryan Thompson</a> - * @version $Id$ - * @param <E> - */ - public static class PushbackFilter<E> extends FilterBase { + final int cmp = s1.compareTo(s2); - /** - * - */ - private static final long serialVersionUID = -8010263934867149205L; + if (cmp < 0) { - @SuppressWarnings("unchecked") - public PushbackIterator<E> filterOnce(Iterator src, Object context) { + /* + * Consuming from [resourceIds] (the term identifier ordered + * LT the next term identifier from [posItr]). + * + * There is NOT an explicit statement from [posItr], so emit + * as an inference and pushback on [posItr]. + */ - return new PushbackIterator<E>((Iterator<E>) src); + current = new SPO(s1, rdfType, rdfsResource, + StatementEnum.Inferred); - } + posItr.pushback(); - } + } else { - /** - * Implementation class for {@link PushbackFilter}. - * - * @author <a href="mailto:tho...@us...">Bryan Thompson</a> - * @version $Id$ - * @param <E> - */ - public static class PushbackIterator<E> implements Iterator<E>, - ICloseableIterator<E> { + /* + * Consuming from [posItr]. + * + * There is an explicit statement for the current term + * identifer from [resourceIds]. + */ - private final Iterator<E> src; + if (cmp != 0) { - /** - * The most recent element visited by the iterator. - */ - private E current; - - /** - * When non-<code>null</code>, this element was pushed back and - * is the next element to be visited. - */ - private E buffer; + /* + * Since [resourceIds] and [posItr] are NOT visiting the + * same term identifier, we pushback on [resourceIds]. + * + * Note: When they DO visit the same term identifier + * then we only emit the explicit statement and we + * consume (rather than pushback) from [resourceIds]. + */ - public PushbackIterator(final Iterator<E> src) { + resourceIds.pushback(); - if (src == null) - throw new IllegalArgumentException(); + } - this.src = src; + current = new SPO(s2, rdfType, rdfsResource, + StatementEnum.Explicit); - } + } - public boolean hasNext() { + } else { - return buffer != null || src.hasNext(); + /* + * [posItr] is exhausted so just emit inferences based on + * [resourceIds]. + */ - } + current = new SPO(s1, rdfType, rdfsResource, + StatementEnum.Inferred); - public E next() { + } - if (!hasNext()) - throw new NoSuchElementException(); + return current; - final E tmp; + } else { - if (buffer != null) { + /* + * Finish off the [posItr]. Anything from this source is an explicit + * (? type resource) statement. + */ - tmp = buffer; + assert posItr.hasNext(); - buffer = null; + return new SPO(posItr.next(), rdfType, rdfsResource, + StatementEnum.Explicit); - } else { + } - tmp = src.next(); + } - } + /** + * Note: This method preserves the {@link IKeyOrder} of the source iterator + * iff it is reported by {@link #getKeyOrder()}. Otherwise chunks read from + * the source iterator will be in whatever order that iterator is using + * while chunks containing backchained entailments will be in + * {@link SPOKeyOrder#POS} order. + * <p> + * Note: In order to ensure that a consistent ordering is always used within + * a chunk the backchained entailments will always begin on a chunk + * boundary. + */ + public ISPO[] nextChunk() { - current = tmp; - - return tmp; + if (!hasNext()) + throw new NoSuchElementException(); - } + if (!sourceExhausted) { - /** - * Push the value onto the internal buffer. It will be returned by the - * next call to {@link #next()}. + /* + * Return a chunk from the source iterator. + * + * Note: The chunk will be in the order used by the source iterator. + * If the source iterator does not report that order then + * [chunkKeyOrder] will be null. + */ + + chunkKeyOrder = keyOrder; + + ISPO[] s = new ISPO[chunkSize]; + + int n = 0; + + while (src.hasNext() && n < chunkSize) { + + s[n++] = src.next(); + + } + + ISPO[] stmts = new ISPO[n]; + + // copy so that stmts[] is dense. + System.arraycopy(s, 0, stmts, 0, n); + + return stmts; + + } + + /* + * Create a "chunk" of entailments. + * + * Note: This chunk will be in natural POS order since that is the index + * that we scan to decide whether or not there was an explicit ( x + * rdf:type rdfs:Resource ) while we consume the [subjects] in termId + * order. + */ + + IV[] s = new IV[chunkSize]; + + int n = 0; + + while (resourceIds.hasNext() && n < chunkSize) { + + s[n++] = resourceIds.next(); + + } + + SPO[] stmts = new SPO[n]; + + for (int i = 0; i < n; i++) { + + stmts[i] = new SPO(s[i], rdfType, rdfsResource, + StatementEnum.Inferred); + + } + + if (keyOrder != null && keyOrder != SPOKeyOrder.POS) { + + /* + * Sort into the same order as the source iterator. + * + * Note: We have to sort explicitly since we are scanning the POS + * index + */ + + Arrays.sort(stmts, 0, stmts.length, keyOrder.getComparator()); + + } + + /* + * The chunk will be in POS order since that is how we are scanning the + * indices. + */ + + chunkKeyOrder = SPOKeyOrder.POS; + + return stmts; + + } + + public ISPO[] nextChunk(IKeyOrder<ISPO> keyOrder) { + + if (keyOrder == null) + throw new IllegalArgumentException(); + + final ISPO[] stmts = nextChunk(); + + if (chunkKeyOrder != keyOrder) { + + // sort into the required order. + + Arrays.sort(stmts, 0, stmts.length, keyOrder.getComparator()); + + } + + return stmts; + + } + + /** + * Note: You can not "remove" the backchained entailments. If the last + * statement visited by {@link #next()} is "explicit" then the request is + * delegated to the source iterator. + */ + public void remove() { + + if (!open) + throw new IllegalStateException(); + + if (current == null) + throw new IllegalStateException(); + + if (current.isExplicit()) { + + /* + * Delegate the request to the source iterator. + */ + + src.remove(); + + } + + current = null; + + } + + /** + * Reads on two iterators visiting elements in some natural order and visits + * their order preserving merge (no duplicates). + * + * @author <a href="mailto:tho...@us...">Bryan + * Thompson</a> + * @version $Id: BackchainTypeResourceIterator.java 3687 2010-09-29 + * 22:50:32Z mrpersonick $ + * @param <T> + */ + private static class MergedOrderedIterator<T extends Comparable<T>> + implements IChunkedIterator<T> { + + private final IChunkedIterator<T> src1; + private final IChunkedIterator<T> src2; + + public MergedOrderedIterator(IChunkedIterator<T> src1, + IChunkedIterator<T> src2) { + + this.src1 = src1; + + this.src2 = src2; + + } + + public void close() { + + src1.close(); + + src2.close(); + + } + + /** + * Note: Not implemented since not used above and this class is private. + */ + public T[] nextChunk() { + throw new UnsupportedOperationException(); + } + + public boolean hasNext() { + + return tmp1 != null || tmp2 != null || src1.hasNext() + || src2.hasNext(); + + } + + private T tmp1; + private T tmp2; + + public T next() { + + if (!hasNext()) + throw new NoSuchElementException(); + + if (tmp1 == null && src1.hasNext()) { + + tmp1 = src1.next(); + + } + + if (tmp2 == null && src2.hasNext()) { + + tmp2 = src2.next(); + + } + + if (tmp1 == null) { + + // src1 is exhausted so deliver from src2. + final T tmp = tmp2; + + tmp2 = null; + + return tmp; + + } + + if (tmp2 == null) { + + // src2 is exhausted so deliver from src1. + final T tmp = tmp1; + + tmp1 = null; + + return tmp; + + } + + final int cmp = tmp1.compareTo(tmp2); + + if (cmp == 0) { + + final T tmp = tmp1; + + tmp1 = tmp2 = null; + + return tmp; + + } else if (cmp < 0) { + + final T tmp = tmp1; + + tmp1 = null; + + return tmp; + + } else { + + final T tmp = tmp2; + + tmp2 = null; + + return tmp; + + } + + } + + public void remove() { + + throw new UnsupportedOperationException(); + + } + + } + + /** + * Filterator style construct that allows push back of a single visited + * element. + * + * @author <a href="mailto:tho...@us...">Bryan + * Thompson</a> + * @version $Id: BackchainTypeResourceIterator.java 3687 2010-09-29 + * 22:50:32Z mrpersonick $ + * @param <E> + */ + public static class PushbackFilter<E> extends FilterBase { + + /** * - * @param value - * The value. - * - * @throws IllegalStateException - * if there is already a value pushed back. */ - public void pushback() { + private static final long serialVersionUID = -8010263934867149205L; - if (buffer != null) - throw new IllegalStateException(); - - // pushback the last visited element. - buffer = current; - - } - - public void remove() { + @SuppressWarnings("unchecked") + public PushbackIterator<E> filterOnce(Iterator src, Object context) { - throw new UnsupportedOperationException(); + return new PushbackIterator<E>((Iterator<E>) src); - } + } - public void close() { + } - if(src instanceof ICloseableIterator) { + /** + * Implementation class for {@link PushbackFilter}. + * + * @author <a href="mailto:tho...@us...">Bryan + * Thompson</a> + * @version $Id: BackchainTypeResourceIterator.java 3687 2010-09-29 + * 22:50:32Z mrpersonick $ + * @param <E> + */ + public static class PushbackIterator<E> implements Iterator<E>, + ICloseableIterator<E> { - ((ICloseableIterator<E>)src).close(); - - } - - } + private final Iterator<E> src; - } - - private static class BackchainSTypeResourceIterator - implements IChunkedOrderedIterator<ISPO> { + /** + * The most recent element visited by the iterator. + */ + private E current; - private final IChunkedOrderedIterator<ISPO> _src; - private final IAccessPath<ISPO> accessPath; - private final AbstractTripleStore db; - private final IV rdfType; - private final IV rdfsResource; - private final IV s; - private IChunkedOrderedIterator<ISPO> appender; - private boolean canRemove; - - public BackchainSTypeResourceIterator( - final IChunkedOrderedIterator<ISPO> _src, - final IAccessPath<ISPO> accessPath, final AbstractTripleStore db, - final IV rdfType, final IV rdfsResource) { - this._src = _src; - this.accessPath = accessPath; - this.db = db; - this.rdfType = rdfType; - this.rdfsResource = rdfsResource; - this.s = (IV) accessPath... [truncated message content] |