/**
* File: $HeadURL: https://hdt-java.googlecode.com/svn/trunk/hdt-java/src/org/rdfhdt/hdt/triples/impl/BitmapTriplesIteratorZFOQ.java $
* Revision: $Rev: 191 $
* Last modified: $Date: 2013-03-03 11:41:43 +0000 (dom, 03 mar 2013) $
* Last modified by: $Author: mario.arias $
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* Contacting the authors:
* Mario Arias: mario.arias@deri.org
* Javier D. Fernandez: jfergar@infor.uva.es
* Miguel A. Martinez-Prieto: migumar2@infor.uva.es
* Alejandro Andres: fuzzy.alej@gmail.com
*/
package org.rdfhdt.hdt.triples.impl;
import org.rdfhdt.hdt.compact.bitmap.AdjacencyList;
import org.rdfhdt.hdt.enums.ResultEstimationType;
import org.rdfhdt.hdt.enums.TripleComponentOrder;
import org.rdfhdt.hdt.triples.IteratorTripleID;
import org.rdfhdt.hdt.triples.TripleID;
/**
* @author mario.arias
*
*/
public class BitmapTriplesIteratorZFOQ implements IteratorTripleID {
BitmapTriples triples;
TripleID pattern, returnTriple;
AdjacencyList adjY, adjIndex;
long posIndex, minIndex, maxIndex;
int x, y, z;
int patY, patZ;
public BitmapTriplesIteratorZFOQ(BitmapTriples triples, TripleID pattern) {
this.triples = triples;
this.pattern = new TripleID(pattern);
this.returnTriple = new TripleID();
TripleOrderConvert.swapComponentOrder(this.pattern, TripleComponentOrder.SPO, triples.order);
patZ = this.pattern.getObject();
if(patZ==0 && (patY!=0 || this.pattern.getSubject()!=0)) {
throw new IllegalArgumentException("This structure is not meant to process this pattern");
}
patY = this.pattern.getPredicate();
adjY = triples.adjY;
adjIndex = triples.adjIndex;
calculateRange();
goToStart();
}
private long getY(long index) {
return adjY.get(adjIndex.get(index));
}
private void calculateRange() {
if(patZ==0) {
minIndex = 0;
maxIndex = adjIndex.getNumberOfElements();
return;
}
minIndex = adjIndex.find(patZ-1);
maxIndex = adjIndex.last(patZ-1);
if(patY!=0) {
while (minIndex <= maxIndex) {
long mid = (minIndex + maxIndex) / 2;
long predicate=getY(mid);
if (patY > predicate) {
minIndex = mid + 1;
} else if (patY < predicate) {
maxIndex = mid - 1;
} else {
// Binary Search to find left boundary
long left=minIndex;
long right=mid;
long pos=0;
while(left<=right) {
pos = (left+right)/2;
predicate = getY(pos);
if(predicate!=patY) {
left = pos+1;
} else {
right = pos-1;
}
}
minIndex = predicate==patY ? pos : pos+1;
// Binary Search to find right boundary
left = mid;
right= maxIndex;
while(left<=right) {
pos = (left+right)/2;
predicate = getY(pos);
if(predicate!=patY) {
right = pos-1;
} else {
left = pos+1;
}
}
maxIndex = predicate==patY ? pos : pos-1;
break;
}
}
}
}
private void updateOutput() {
returnTriple.setAll(x, y, z);
TripleOrderConvert.swapComponentOrder(returnTriple, triples.order, TripleComponentOrder.SPO);
}
/* (non-Javadoc)
* @see hdt.iterator.IteratorTripleID#hasNext()
*/
@Override
public boolean hasNext() {
return posIndex<=maxIndex;
}
/* (non-Javadoc)
* @see hdt.iterator.IteratorTripleID#next()
*/
@Override
public TripleID next() {
long posY = adjIndex.get(posIndex);
z = patZ!=0 ? patZ : (int)adjIndex.findListIndex(posIndex)+1;
y = patY!=0 ? patY : (int) adjY.get(posY);
x = (int) adjY.findListIndex(posY)+1;
posIndex++;
updateOutput();
return returnTriple;
}
/* (non-Javadoc)
* @see hdt.iterator.IteratorTripleID#hasPrevious()
*/
@Override
public boolean hasPrevious() {
return posIndex>minIndex;
}
/* (non-Javadoc)
* @see hdt.iterator.IteratorTripleID#previous()
*/
@Override
public TripleID previous() {
posIndex--;
long posY = adjIndex.get(posIndex);
z = patZ!=0 ? patZ : (int)adjIndex.findListIndex(posIndex)+1;
y = patY!=0 ? patY : (int) adjY.get(posY);
x = (int) adjY.findListIndex(posY)+1;
updateOutput();
return returnTriple;
}
/* (non-Javadoc)
* @see hdt.iterator.IteratorTripleID#goToStart()
*/
@Override
public void goToStart() {
posIndex = minIndex;
}
/* (non-Javadoc)
* @see hdt.iterator.IteratorTripleID#estimatedNumResults()
*/
@Override
public long estimatedNumResults() {
return maxIndex-minIndex+1;
}
/* (non-Javadoc)
* @see hdt.iterator.IteratorTripleID#numResultEstimation()
*/
@Override
public ResultEstimationType numResultEstimation() {
return ResultEstimationType.EXACT;
}
/* (non-Javadoc)
* @see hdt.iterator.IteratorTripleID#canGoTo()
*/
@Override
public boolean canGoTo() {
return true;
}
/* (non-Javadoc)
* @see hdt.iterator.IteratorTripleID#goTo(int)
*/
@Override
public void goTo(long pos) {
if(pos>maxIndex-minIndex || pos<0) {
throw new IndexOutOfBoundsException();
}
posIndex = minIndex+pos;
}
/* (non-Javadoc)
* @see hdt.iterator.IteratorTripleID#getOrder()
*/
@Override
public TripleComponentOrder getOrder() {
return triples.order;
}
/* (non-Javadoc)
* @see java.util.Iterator#remove()
*/
@Override
public void remove() {
throw new UnsupportedOperationException();
}
}