com.bigdata.htree.BucketPageTupleIterator Maven / Gradle / Ivy
package com.bigdata.htree;
import java.util.Iterator;
import java.util.NoSuchElementException;
import com.bigdata.btree.ITuple;
import com.bigdata.btree.ITupleIterator;
import com.bigdata.btree.raba.IRaba;
/**
* Visits the non-empty tuples in each {@link BucketPage} visited by the
* source iterator.
*
* TODO This might be reworked as an expander and an iterator visiting the
* tuples on a single bucket page. That could provide more reuse. See
* {@link BucketPage#tuples()}
*/
class BucketPageTupleIterator implements
ITupleIterator {
private final Iterator src;
private BucketPage currentBucketPage = null;
private int nextNonEmptySlot = 0;
private final Tuple tuple;
BucketPageTupleIterator(final AbstractHTree htree, final int flags,
final Iterator src) {
if (htree == null)
throw new IllegalArgumentException();
if(src == null)
throw new IllegalArgumentException();
this.tuple = new Tuple(htree,flags);
this.src = src;
}
/**
* Scan to the next non-empty slot in the current {@link BucketPage}.
*
* @return true
iff there is a non-empty slot on the
* current {@link BucketPage}.
*/
private boolean findNextSlot() {
if (currentBucketPage == null)
throw new IllegalStateException();
final IRaba keys = currentBucketPage.getKeys();
final int size = keys.size();
for (; nextNonEmptySlot < size; nextNonEmptySlot++) {
if (keys.isNull(nextNonEmptySlot))
continue;
return true;
}
// The current page is exhausted. We need to fetch another page.
currentBucketPage = null;
return false;
}
public boolean hasNext() {
if(currentBucketPage != null) {
return true;
}
// Scan for the next bucket page having a visitable tuple.
while(src.hasNext()) {
currentBucketPage = src.next();
nextNonEmptySlot = 0;
if (findNextSlot())
return true;
}
return false;
}
public ITuple next() {
if (!hasNext())
throw new NoSuchElementException();
// Copy the data for the current tuple into the Tuple buffer.
tuple.copy(nextNonEmptySlot, currentBucketPage);
/*
* Advance to the next slot on the current page. if there is non,
* then the current page reference will be cleared and we will need
* to fetch a new page in hasNext() on the next invocation.
*/
nextNonEmptySlot++; // skip past the current tuple.
findNextSlot(); // find the next non-null slot (next tuple).
// Return the Tuple buffer.
return tuple;
}
public void remove() {
throw new UnsupportedOperationException();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy