All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.bigdata.htree.BuddyBucketTupleIterator Maven / Gradle / Ivy

package com.bigdata.htree;

import java.util.NoSuchElementException;

import com.bigdata.btree.AbstractTuple;
import com.bigdata.btree.IRangeQuery;
import com.bigdata.btree.ITuple;
import com.bigdata.btree.ITupleIterator;
import com.bigdata.btree.LeafTupleIterator;
import com.bigdata.btree.raba.IRaba;
import com.bigdata.util.BytesUtil;

/**
 * Iterator visits all tuples in a buddy bucket having the desired key. 
 * 

* Note: This implementation is NOT thread-safe. */ class BuddyBucketTupleIterator implements ITupleIterator { /** The key. */ private final byte[] key; /** The bucket. */ private final BucketPage bucket; // /** The index of the first slot in the buddy bucket. */ // private final int buddyOffset; /** The index of the last slot in the buddy bucket. */ private final int lastSlot; /** The index of the next slot to be visited. This is set by the * constructor to the first slot and the tuple at that slot is pre-fetched. */ private int index; private int lastVisited = -1; private final AbstractTuple tuple; public BuddyBucketTupleIterator(final byte[] key, final BucketPage bucket) {//, final int buddyOffset) { if (key == null) throw new IllegalArgumentException(); if (bucket == null) throw new IllegalArgumentException(); this.key = key; this.bucket = bucket; // // #of slots on the page. // final int slotsOnPage = bucket.slotsOnPage(); /* * The index of the last slot in the buddy bucket. * * Note: The bucket page is not divided into buddy buckets, so we want * to start at the first slot (index zero) and scan until the last slot * (slotsOnPage-1). * * Note: Optimized (assumes tuples in the bucket page are known to be * dense (no gaps), in which case we do not have to scan more than * bucket.data.getKeyCount() slots). */ lastSlot = bucket.getKeys().size();//slotsOnPage; // Lookup first slot to test. index = bucket.lookupIndex(key); tuple = new Tuple(bucket.htree, IRangeQuery.DEFAULT); } /** * Examines the entry at {@link #index}. If it passes the criteria for an * entry to visit then return true. Otherwise increment the {@link #index} * until either all entries in this leaf have been exhausted -or- the an * entry is identified that passes the various criteria. */ public boolean hasNext() { if (index == -1) { return false; } final IRaba keys = bucket.getKeys(); assert keys.size() == lastSlot; assert keys.size() <= keys.capacity(); for( ; index < lastSlot; index++) { // /* // * TODO Skip deleted entries unless specifically requested. // */ // if (hasDeleteMarkers && !visitDeleted // && leaf.getDeleteMarker(index)) { // // // skipping a deleted version. // continue; // // } if (!keys.isNull(index)) { if (BytesUtil.bytesEqual(key, keys.get(index))) { // entry @ index is next to visit. return true; } } // if key doesn't match terminate early since the keys are sorted index = lastSlot; } // next index. // nothing left to visit in this buddy bucket. return false; } public ITuple next() { if (!hasNext()) { throw new NoSuchElementException(); } lastVisited = index++; tuple.copy(lastVisited, bucket); return tuple; } /** * Operation is not supported. * * TODO ITupleCursor and delete-behind are two ways to achieve this. See * {@link LeafTupleIterator#remove()}. I also did a listener based * iterator for GOM which supports concurrent mutation (as long as you * obey the thread safety for the API). */ public void remove() { throw new UnsupportedOperationException(); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy