You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2015/02/19 10:46:27 UTC
svn commit: r1660820 - in /directory/mavibot/trunk/mavibot/src:
main/java/org/apache/directory/mavibot/btree/BulkLoader.java
main/java/org/apache/directory/mavibot/btree/LevelInfo.java
test/java/org/apache/directory/mavibot/btree/BulkLoaderTest.java
Author: elecharny
Date: Thu Feb 19 09:46:27 2015
New Revision: 1660820
URL: http://svn.apache.org/r1660820
Log:
o Made the BulkLoader a class with static methods
o Externalized the LevelInfo class
Added:
directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/LevelInfo.java
Modified:
directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/BulkLoader.java
directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/BulkLoaderTest.java
Modified: directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/BulkLoader.java
URL: http://svn.apache.org/viewvc/directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/BulkLoader.java?rev=1660820&r1=1660819&r2=1660820&view=diff
==============================================================================
--- directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/BulkLoader.java (original)
+++ directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/BulkLoader.java Thu Feb 19 09:46:27 2015
@@ -55,81 +55,16 @@ import org.apache.directory.mavibot.btre
*/
public class BulkLoader<K, V>
{
+ private BulkLoader()
+ {
+ };
+
static enum LevelEnum
{
LEAF,
NODE
}
- /**
- * A private class to store informations on a level. We have to keep :
- * <ul>
- * <li>The number of elements to store in this level</li>
- * <li>A flag that tells if it's a leaf or a node level</li>
- * <li>The number of pages necessary to store all the elements in a level</li>
- * <li>The number of elements we can store in a complete page (we may have one or two
- * incomplete pages at the end)</li>
- * <li>A flag that tells if we have some incomplete page at the end</li>
- * </ul>
- * TODO LevelInfo.
- *
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- */
- /*private*/class LevelInfo
- {
- /** The level number */
- private int levelNumber;
-
- /** Nb of elements for this level */
- /*private*/int nbElems;
-
- /** The number of pages in this level */
- /*private*/int nbPages;
-
- /** Nb of elements before we reach an incomplete page */
- /*private*/int nbElemsLimit;
-
- /** A flag that tells if the level contains nodes or leaves */
- private boolean isNode;
-
- /** The current page which contains the data until we move it to the resulting BTree */
- /*private*/Page<K, V> currentPage;
-
- /** The current position in the currentPage */
- private int currentPos;
-
- /** The number of already added elements for this level */
- private int nbAddedElems;
-
-
- /** @see Object#toString() */
- public String toString()
- {
- StringBuilder sb = new StringBuilder();
-
- if ( isNode )
- {
- sb.append( "NodeLevel[" );
- sb.append( levelNumber );
- sb.append( "] :" );
- }
- else
- {
- sb.append( "LeafLevel:" );
- }
-
- sb.append( "\n nbElems = " ).append( nbElems );
- sb.append( "\n nbPages = " ).append( nbPages );
- sb.append( "\n nbElemsLimit = " ).append( nbElemsLimit );
- sb.append( "\n nbAddedElems = " ).append( nbAddedElems );
- sb.append( "\n currentPos = " ).append( currentPos );
- sb.append( "\n currentPage" );
- sb.append( "\n nbKeys : " ).append( currentPage.getNbElems() );
-
- return sb.toString();
- }
- }
-
/**
* Process the data, and creates files to store them sorted if necessary, or store them
@@ -143,7 +78,7 @@ public class BulkLoader<K, V>
* @return
* @throws IOException
*/
- private int readElements( BTree<K, V> btree, Iterator<Tuple<K, V>> iterator, List<File> sortedFiles,
+ private static <K, V> int readElements( BTree<K, V> btree, Iterator<Tuple<K, V>> iterator, List<File> sortedFiles,
List<Tuple<K, V>> tuples, int chunkSize ) throws IOException
{
int nbRead = 0;
@@ -228,7 +163,7 @@ public class BulkLoader<K, V>
* sorted and merged elements.
* @throws IOException
*/
- private Tuple<Iterator<Tuple<K, Set<V>>>, Integer> processFiles( BTree<K, V> btree,
+ private static <K, V> Tuple<Iterator<Tuple<K, Set<V>>>, Integer> processFiles( BTree<K, V> btree,
Iterator<Tuple<K, Set<V>>> dataIterator ) throws IOException
{
File file = File.createTempFile( "sortedUnique", "data" );
@@ -287,7 +222,7 @@ public class BulkLoader<K, V>
* @param chunkSize The number of elements we may store in memory at each iteration
* @throws IOException If there is a problem while processing the data
*/
- public BTree<K, V> load( PersistedBTree<K, V> btree, Iterator<Tuple<K, V>> iterator, int chunkSize )
+ public static <K, V> BTree<K, V> load( PersistedBTree<K, V> btree, Iterator<Tuple<K, V>> iterator, int chunkSize )
throws IOException
{
if ( btree == null )
@@ -372,7 +307,7 @@ public class BulkLoader<K, V>
* Creates a node leaf LevelInfo based on the number of elements in the lower level. We can store
* up to PageSize + 1 references to pages in a node.
*/
- /* no qualifier*/LevelInfo computeLevel( BTree<K, V> btree, int nbElems, LevelEnum levelType )
+ /* no qualifier*/static <K, V> LevelInfo<K, V> computeLevel( BTree<K, V> btree, int nbElems, LevelEnum levelType )
{
int pageSize = btree.getPageSize();
int incrementNode = 0;
@@ -382,31 +317,31 @@ public class BulkLoader<K, V>
incrementNode = 1;
}
- LevelInfo level = new LevelInfo();
- level.isNode = ( levelType == LevelEnum.NODE );
- level.nbElems = nbElems;
- level.nbPages = nbElems / ( pageSize + incrementNode );
- level.levelNumber = 0;
- level.nbAddedElems = 0;
- level.currentPos = 0;
+ LevelInfo<K, V> level = new LevelInfo<K, V>();
+ level.setType( ( levelType == LevelEnum.NODE ) );
+ level.setNbElems( nbElems );
+ level.setNbPages( nbElems / ( pageSize + incrementNode ) );
+ level.setLevelNumber( 0 );
+ level.setNbAddedElems( 0 );
+ level.setCurrentPos( 0 );
// Create the first level page
if ( nbElems <= pageSize + incrementNode )
{
if ( nbElems % ( pageSize + incrementNode ) != 0 )
{
- level.nbPages = 1;
+ level.setNbPages( 1 );
}
- level.nbElemsLimit = nbElems;
+ level.setNbElemsLimit( nbElems );
- if ( level.isNode )
+ if ( level.isNode() )
{
- level.currentPage = BTreeFactory.createNode( btree, 0L, nbElems - 1 );
+ level.setCurrentPage( BTreeFactory.createNode( btree, 0L, nbElems - 1 ) );
}
else
{
- level.currentPage = BTreeFactory.createLeaf( btree, 0L, nbElems );
+ level.setCurrentPage( BTreeFactory.createLeaf( btree, 0L, nbElems ) );
}
}
else
@@ -415,59 +350,60 @@ public class BulkLoader<K, V>
if ( remaining == 0 )
{
- level.nbElemsLimit = nbElems;
+ level.setNbElemsLimit( nbElems );
- if ( level.isNode )
+ if ( level.isNode() )
{
- level.currentPage = BTreeFactory.createNode( btree, 0L, pageSize );
+ level.setCurrentPage( BTreeFactory.createNode( btree, 0L, pageSize ) );
}
else
{
- level.currentPage = BTreeFactory.createLeaf( btree, 0L, pageSize );
+ level.setCurrentPage( BTreeFactory.createLeaf( btree, 0L, pageSize ) );
}
}
else
{
- level.nbPages++;
+ level.incNbPages();
if ( remaining < ( pageSize / 2 ) + incrementNode )
{
- level.nbElemsLimit = nbElems - remaining - ( pageSize + incrementNode );
+ level.setNbElemsLimit( nbElems - remaining - ( pageSize + incrementNode ) );
- if ( level.nbElemsLimit > 0 )
+ if ( level.getNbElemsLimit() > 0 )
{
- if ( level.isNode )
+ if ( level.isNode() )
{
- level.currentPage = BTreeFactory.createNode( btree, 0L, pageSize );
+ level.setCurrentPage( BTreeFactory.createNode( btree, 0L, pageSize ) );
}
else
{
- level.currentPage = BTreeFactory.createLeaf( btree, 0L, pageSize );
+ level.setCurrentPage( BTreeFactory.createLeaf( btree, 0L, pageSize ) );
}
}
else
{
- if ( level.isNode )
+ if ( level.isNode() )
{
- level.currentPage = BTreeFactory.createNode( btree, 0L, ( pageSize / 2 ) + remaining - 1 );
+ level
+ .setCurrentPage( BTreeFactory.createNode( btree, 0L, ( pageSize / 2 ) + remaining - 1 ) );
}
else
{
- level.currentPage = BTreeFactory.createLeaf( btree, 0L, ( pageSize / 2 ) + remaining );
+ level.setCurrentPage( BTreeFactory.createLeaf( btree, 0L, ( pageSize / 2 ) + remaining ) );
}
}
}
else
{
- level.nbElemsLimit = nbElems - remaining;
+ level.setNbElemsLimit( nbElems - remaining );
- if ( level.isNode )
+ if ( level.isNode() )
{
- level.currentPage = BTreeFactory.createNode( btree, 0L, pageSize );
+ level.setCurrentPage( BTreeFactory.createNode( btree, 0L, pageSize ) );
}
else
{
- level.currentPage = BTreeFactory.createLeaf( btree, 0L, pageSize );
+ level.setCurrentPage( BTreeFactory.createLeaf( btree, 0L, pageSize ) );
}
}
}
@@ -481,24 +417,24 @@ public class BulkLoader<K, V>
* Compute the number of pages necessary to store all the elements per level. The resulting list is
* reversed ( ie the leaves are on the left, the root page on the right.
*/
- /* No Qualifier */List<LevelInfo> computeLevels( BTree<K, V> btree, int nbElems )
+ /* No Qualifier */static <K, V> List<LevelInfo<K, V>> computeLevels( BTree<K, V> btree, int nbElems )
{
- List<LevelInfo> levelList = new ArrayList<LevelInfo>();
+ List<LevelInfo<K, V>> levelList = new ArrayList<LevelInfo<K, V>>();
// Compute the leaves info
- LevelInfo leafLevel = computeLevel( btree, nbElems, LevelEnum.LEAF );
+ LevelInfo<K, V> leafLevel = computeLevel( btree, nbElems, LevelEnum.LEAF );
levelList.add( leafLevel );
- int nbPages = leafLevel.nbPages;
+ int nbPages = leafLevel.getNbPages();
int levelNumber = 1;
while ( nbPages > 1 )
{
// Compute the Nodes info
- LevelInfo nodeLevel = computeLevel( btree, nbPages, LevelEnum.NODE );
- nodeLevel.levelNumber = levelNumber++;
+ LevelInfo<K, V> nodeLevel = computeLevel( btree, nbPages, LevelEnum.NODE );
+ nodeLevel.setLevelNumber( levelNumber++ );
levelList.add( nodeLevel );
- nbPages = nodeLevel.nbPages;
+ nbPages = nodeLevel.getNbPages();
}
return levelList;
@@ -508,23 +444,23 @@ public class BulkLoader<K, V>
/**
* Inject a tuple into a leaf
*/
- private void injectInLeaf( BTree<K, V> btree, Tuple<K, Set<V>> tuple, LevelInfo leafLevel )
+ private static <K, V> void injectInLeaf( BTree<K, V> btree, Tuple<K, Set<V>> tuple, LevelInfo leafLevel )
{
- PersistedLeaf<K, V> leaf = ( PersistedLeaf<K, V> ) leafLevel.currentPage;
+ PersistedLeaf<K, V> leaf = ( PersistedLeaf<K, V> ) leafLevel.getCurrentPage();
KeyHolder<K> keyHolder = new PersistedKeyHolder<K>( btree.getKeySerializer(), tuple.getKey() );
ValueHolder<V> valueHolder = new PersistedValueHolder<V>( btree, ( V[] ) tuple.getValue().toArray() );
- leaf.setKey( leafLevel.currentPos, keyHolder );
- leaf.setValue( leafLevel.currentPos, valueHolder );
+ leaf.setKey( leafLevel.getCurrentPos(), keyHolder );
+ leaf.setValue( leafLevel.getCurrentPos(), valueHolder );
- leafLevel.currentPos++;
+ leafLevel.incCurrentPos();
}
- private int computeNbElemsLeaf( BTree<K, V> btree, LevelInfo levelInfo )
+ private static <K, V> int computeNbElemsLeaf( BTree<K, V> btree, LevelInfo<K, V> levelInfo )
{
int pageSize = btree.getPageSize();
- int remaining = levelInfo.nbElems - levelInfo.nbAddedElems;
+ int remaining = levelInfo.getNbElems() - levelInfo.getNbAddedElems();
if ( remaining < pageSize )
{
@@ -534,7 +470,7 @@ public class BulkLoader<K, V>
{
return pageSize;
}
- else if ( remaining > levelInfo.nbElems - levelInfo.nbElemsLimit )
+ else if ( remaining > levelInfo.getNbElems() - levelInfo.getNbElemsLimit() )
{
return pageSize;
}
@@ -548,10 +484,10 @@ public class BulkLoader<K, V>
/**
* Compute the number of nodes necessary to store all the elements.
*/
- /* No qualifier */int computeNbElemsNode( BTree<K, V> btree, LevelInfo levelInfo )
+ /* No qualifier */int computeNbElemsNode( BTree<K, V> btree, LevelInfo<K, V> levelInfo )
{
int pageSize = btree.getPageSize();
- int remaining = levelInfo.nbElems - levelInfo.nbAddedElems;
+ int remaining = levelInfo.getNbElems() - levelInfo.getNbAddedElems();
if ( remaining < pageSize + 1 )
{
@@ -561,7 +497,7 @@ public class BulkLoader<K, V>
{
return pageSize + 1;
}
- else if ( remaining > levelInfo.nbElems - levelInfo.nbElemsLimit )
+ else if ( remaining > levelInfo.getNbElems() - levelInfo.getNbElemsLimit() )
{
return pageSize + 1;
}
@@ -575,28 +511,28 @@ public class BulkLoader<K, V>
/**
* Inject a page reference into the root page.
*/
- private void injectInRoot( BTree<K, V> btree, Page<K, V> page, PageHolder<K, V> pageHolder, LevelInfo level )
- throws IOException
+ private static <K, V> void injectInRoot( BTree<K, V> btree, Page<K, V> page, PageHolder<K, V> pageHolder,
+ LevelInfo<K, V> level ) throws IOException
{
- PersistedNode<K, V> node = ( PersistedNode<K, V> ) level.currentPage;
- if ( ( level.currentPos == 0 ) && ( node.getPage( 0 ) == null ) )
+ PersistedNode<K, V> node = ( PersistedNode<K, V> ) level.getCurrentPage();
+ if ( ( level.getCurrentPos() == 0 ) && ( node.getPage( 0 ) == null ) )
{
node.setPageHolder( 0, pageHolder );
- level.nbAddedElems++;
+ level.incNbAddedElems();
}
else
{
// Inject the pageHolder and the page leftmost key
- node.setPageHolder( level.currentPos + 1, pageHolder );
+ node.setPageHolder( level.getCurrentPos() + 1, pageHolder );
KeyHolder<K> keyHolder = new PersistedKeyHolder<K>( btree.getKeySerializer(), page.getLeftMostKey() );
- node.setKey( level.currentPos, keyHolder );
- level.currentPos++;
- level.nbAddedElems++;
+ node.setKey( level.getCurrentPos(), keyHolder );
+ level.incCurrentPos();
+ level.incNbAddedElems();
// Check that we haven't added the last element. If so,
// we have to write the page on disk and update the btree
- if ( level.nbAddedElems == level.nbElems )
+ if ( level.getNbAddedElems() == level.getNbElems() )
{
PageHolder<K, V> rootHolder = ( ( PersistedBTree<K, V> ) btree ).getRecordManager().writePage(
btree, node, 0L );
@@ -611,19 +547,20 @@ public class BulkLoader<K, V>
/**
* Inject a page reference into a Node. This method will recurse if needed.
*/
- private void injectInNode( BTree<K, V> btree, Page<K, V> page, List<LevelInfo> levels, int levelIndex )
+ private static <K, V> void injectInNode( BTree<K, V> btree, Page<K, V> page, List<LevelInfo<K, V>> levels,
+ int levelIndex )
throws IOException
{
int pageSize = btree.getPageSize();
- LevelInfo level = levels.get( levelIndex );
- PersistedNode<K, V> node = ( PersistedNode<K, V> ) level.currentPage;
+ LevelInfo<K, V> level = levels.get( levelIndex );
+ PersistedNode<K, V> node = ( PersistedNode<K, V> ) level.getCurrentPage();
// We first have to write the page on disk
PageHolder<K, V> pageHolder = ( ( PersistedBTree<K, V> ) btree ).getRecordManager().writePage( btree, page, 0L );
// First deal with a node that has less than PageSize elements at this level.
// It will become the root node.
- if ( level.nbElems <= pageSize + 1 )
+ if ( level.getNbElems() <= pageSize + 1 )
{
injectInRoot( btree, page, pageHolder, level );
@@ -634,31 +571,31 @@ public class BulkLoader<K, V>
// o Full node before the limit
// o Node over the limit but with at least N/2 elements
// o Node over the limit but with elements spread into 2 nodes
- if ( level.nbAddedElems < level.nbElemsLimit )
+ if ( level.getNbAddedElems() < level.getNbElemsLimit() )
{
// Ok, we haven't yet reached the incomplete pages (if any).
// Let's add the page reference into the node
// There is one special case : when we are adding the very first page
// reference into a node. In this case, we don't store the key
- if ( ( level.currentPos == 0 ) && ( node.getKey( 0 ) == null ) )
+ if ( ( level.getCurrentPos() == 0 ) && ( node.getKey( 0 ) == null ) )
{
node.setPageHolder( 0, pageHolder );
}
else
{
// Inject the pageHolder and the page leftmost key
- node.setPageHolder( level.currentPos, pageHolder );
+ node.setPageHolder( level.getCurrentPos(), pageHolder );
KeyHolder<K> keyHolder = new PersistedKeyHolder<K>( btree.getKeySerializer(), page.getLeftMostKey() );
- node.setKey( level.currentPos - 1, keyHolder );
+ node.setKey( level.getCurrentPos() - 1, keyHolder );
}
// Now, increment this level nb of added elements
- level.currentPos++;
- level.nbAddedElems++;
+ level.incCurrentPos();
+ level.incNbAddedElems();
// Check that we haven't added the last element. If so,
// we have to write the page on disk and update the parent's node
- if ( level.nbAddedElems == level.nbElems )
+ if ( level.getNbAddedElems() == level.getNbElems() )
{
//PageHolder<K, V> rootHolder = ( ( PersistedBTree<K, V> ) btree ).getRecordManager().writePage(
// btree, node, 0L );
@@ -670,29 +607,30 @@ public class BulkLoader<K, V>
else
{
// Check that we haven't completed the current node, and that this is not the root node.
- if ( ( level.currentPos == pageSize + 1 ) && ( level.levelNumber < levels.size() - 1 ) )
+ if ( ( level.getCurrentPos() == pageSize + 1 ) && ( level.getLevelNumber() < levels.size() - 1 ) )
{
// yes. We have to write the node on disk, update its parent
// and create a new current node
injectInNode( btree, node, levels, levelIndex + 1 );
// The page is full, we have to create a new one, with a size depending on the remaining elements
- if ( level.nbAddedElems < level.nbElemsLimit )
+ if ( level.getNbAddedElems() < level.getNbElemsLimit() )
{
// We haven't reached the limit, create a new full node
- level.currentPage = BTreeFactory.createNode( btree, 0L, pageSize );
+ level.setCurrentPage( BTreeFactory.createNode( btree, 0L, pageSize ) );
}
- else if ( level.nbElems - level.nbAddedElems <= pageSize )
+ else if ( level.getNbElems() - level.getNbAddedElems() <= pageSize )
{
- level.currentPage = BTreeFactory.createNode( btree, 0L, level.nbElems - level.nbAddedElems - 1 );
+ level.setCurrentPage( BTreeFactory.createNode( btree, 0L,
+ level.getNbElems() - level.getNbAddedElems() - 1 ) );
}
else
{
- level.currentPage = BTreeFactory.createNode( btree, 0L, ( level.nbElems - 1 )
- - ( level.nbAddedElems + 1 ) - pageSize / 2 );
+ level.setCurrentPage( BTreeFactory.createNode( btree, 0L, ( level.getNbElems() - 1 )
+ - ( level.getNbAddedElems() + 1 ) - pageSize / 2 ) );
}
- level.currentPos = 0;
+ level.setCurrentPos( 0 );
}
}
@@ -704,32 +642,32 @@ public class BulkLoader<K, V>
// We can have either one single pages which can contain up to pageSize-1 elements
// or with two pages, the first one containing ( nbElems - limit ) - pageSize/2 elements
// and the second one will contain pageSize/2 elements.
- if ( level.nbElems - level.nbElemsLimit > pageSize )
+ if ( level.getNbElems() - level.getNbElemsLimit() > pageSize )
{
// As the remaining elements are above a page size, they will be spread across
// two pages. We have two cases here, depending on the page we are filling
- if ( level.nbElems - level.nbAddedElems <= pageSize / 2 + 1 )
+ if ( level.getNbElems() - level.getNbAddedElems() <= pageSize / 2 + 1 )
{
// As we have less than PageSize/2 elements to write, we are on the second page
- if ( ( level.currentPos == 0 ) && ( node.getKey( 0 ) == null ) )
+ if ( ( level.getCurrentPos() == 0 ) && ( node.getKey( 0 ) == null ) )
{
node.setPageHolder( 0, pageHolder );
}
else
{
// Inject the pageHolder and the page leftmost key
- node.setPageHolder( level.currentPos, pageHolder );
+ node.setPageHolder( level.getCurrentPos(), pageHolder );
KeyHolder<K> keyHolder = new PersistedKeyHolder<K>( btree.getKeySerializer(),
page.getLeftMostKey() );
- node.setKey( level.currentPos - 1, keyHolder );
+ node.setKey( level.getCurrentPos() - 1, keyHolder );
}
// Now, increment this level nb of added elements
- level.currentPos++;
- level.nbAddedElems++;
+ level.incCurrentPos();
+ level.incNbAddedElems();
// Check if we are done with the page
- if ( level.nbAddedElems == level.nbElems )
+ if ( level.getNbAddedElems() == level.getNbElems() )
{
// Yes, we have to update the parent
injectInNode( btree, node, levels, levelIndex + 1 );
@@ -738,7 +676,7 @@ public class BulkLoader<K, V>
else
{
// This is the first page
- if ( ( level.currentPos == 0 ) && ( node.getKey( 0 ) == null ) )
+ if ( ( level.getCurrentPos() == 0 ) && ( node.getKey( 0 ) == null ) )
{
// First element of the page
node.setPageHolder( 0, pageHolder );
@@ -747,32 +685,32 @@ public class BulkLoader<K, V>
{
// Any other following elements
// Inject the pageHolder and the page leftmost key
- node.setPageHolder( level.currentPos, pageHolder );
+ node.setPageHolder( level.getCurrentPos(), pageHolder );
KeyHolder<K> keyHolder = new PersistedKeyHolder<K>( btree.getKeySerializer(),
page.getLeftMostKey() );
- node.setKey( level.currentPos - 1, keyHolder );
+ node.setKey( level.getCurrentPos() - 1, keyHolder );
}
// Now, increment this level nb of added elements
- level.currentPos++;
- level.nbAddedElems++;
+ level.incCurrentPos();
+ level.incNbAddedElems();
// Check if we are done with the page
- if ( level.currentPos == node.getNbElems() + 1 )
+ if ( level.getCurrentPos() == node.getNbElems() + 1 )
{
// Yes, we have to update the parent
injectInNode( btree, node, levels, levelIndex + 1 );
// An create a new one
- level.currentPage = BTreeFactory.createNode( btree, 0L, pageSize / 2 );
- level.currentPos = 0;
+ level.setCurrentPage( BTreeFactory.createNode( btree, 0L, pageSize / 2 ) );
+ level.setCurrentPos( 0 );
}
}
}
else
{
// Two cases : we don't have anything else to write, or this is a single page
- if ( level.nbAddedElems == level.nbElems )
+ if ( level.getNbAddedElems() == level.getNbElems() )
{
// We are done with the page
injectInNode( btree, node, levels, levelIndex + 1 );
@@ -781,7 +719,7 @@ public class BulkLoader<K, V>
{
// We have some more elements to add in the page
// This is the first page
- if ( ( level.currentPos == 0 ) && ( node.getKey( 0 ) == null ) )
+ if ( ( level.getCurrentPos() == 0 ) && ( node.getKey( 0 ) == null ) )
{
// First element of the page
node.setPageHolder( 0, pageHolder );
@@ -790,25 +728,25 @@ public class BulkLoader<K, V>
{
// Any other following elements
// Inject the pageHolder and the page leftmost key
- node.setPageHolder( level.currentPos, pageHolder );
+ node.setPageHolder( level.getCurrentPos(), pageHolder );
KeyHolder<K> keyHolder = new PersistedKeyHolder<K>( btree.getKeySerializer(),
page.getLeftMostKey() );
- node.setKey( level.currentPos - 1, keyHolder );
+ node.setKey( level.getCurrentPos() - 1, keyHolder );
}
// Now, increment this level nb of added elements
- level.currentPos++;
- level.nbAddedElems++;
+ level.incCurrentPos();
+ level.incNbAddedElems();
// Check if we are done with the page
- if ( level.currentPos == node.getNbElems() + 1 )
+ if ( level.getCurrentPos() == node.getNbElems() + 1 )
{
// Yes, we have to update the parent
injectInNode( btree, node, levels, levelIndex + 1 );
// An create a new one
- level.currentPage = BTreeFactory.createNode( btree, 0L, pageSize / 2 );
- level.currentPos = 0;
+ level.setCurrentPage( BTreeFactory.createNode( btree, 0L, pageSize / 2 ) );
+ level.setCurrentPos( 0 );
}
}
@@ -818,8 +756,8 @@ public class BulkLoader<K, V>
}
- private BTree<K, V> bulkLoadSinglePage( BTree<K, V> btree, Iterator<Tuple<K, Set<V>>> dataIterator, int nbElems )
- throws IOException
+ private static <K, V> BTree<K, V> bulkLoadSinglePage( BTree<K, V> btree, Iterator<Tuple<K, Set<V>>> dataIterator,
+ int nbElems ) throws IOException
{
// Create a new page
PersistedLeaf<K, V> rootPage = ( PersistedLeaf<K, V> ) BTreeFactory.createLeaf( btree, 0L, nbElems );
@@ -854,7 +792,7 @@ public class BulkLoader<K, V>
* Construct the target BTree from the sorted data. We will use the nb of elements
* to determinate the structure of the BTree, as it must be balanced
*/
- private BTree<K, V> bulkLoad( BTree<K, V> btree, Iterator<Tuple<K, Set<V>>> dataIterator, int nbElems )
+ private static <K, V> BTree<K, V> bulkLoad( BTree<K, V> btree, Iterator<Tuple<K, Set<V>>> dataIterator, int nbElems )
throws IOException
{
int pageSize = btree.getPageSize();
@@ -868,49 +806,50 @@ public class BulkLoader<K, V>
// Ok, we will need more than one page to store the elements, which
// means we also will need more than one level.
// First, compute the needed number of levels.
- List<LevelInfo> levels = computeLevels( btree, nbElems );
+ List<LevelInfo<K, V>> levels = computeLevels( btree, nbElems );
// Now, let's fill the levels
- LevelInfo leafLevel = levels.get( 0 );
+ LevelInfo<K, V> leafLevel = levels.get( 0 );
while ( dataIterator.hasNext() )
{
// let's fill page up to the point all the complete pages have been filled
- if ( leafLevel.nbAddedElems < leafLevel.nbElemsLimit )
+ if ( leafLevel.getNbAddedElems() < leafLevel.getNbElemsLimit() )
{
// grab a tuple
Tuple<K, Set<V>> tuple = dataIterator.next();
injectInLeaf( btree, tuple, leafLevel );
- leafLevel.nbAddedElems++;
+ leafLevel.incNbAddedElems();
// The page is completed, update the parent's node and create a new current page
- if ( leafLevel.currentPos == pageSize )
+ if ( leafLevel.getCurrentPos() == pageSize )
{
- injectInNode( btree, leafLevel.currentPage, levels, 1 );
+ injectInNode( btree, leafLevel.getCurrentPage(), levels, 1 );
// The page is full, we have to create a new one
- leafLevel.currentPage = BTreeFactory.createLeaf( btree, 0L, computeNbElemsLeaf( btree, leafLevel ) );
- leafLevel.currentPos = 0;
+ leafLevel.setCurrentPage( BTreeFactory
+ .createLeaf( btree, 0L, computeNbElemsLeaf( btree, leafLevel ) ) );
+ leafLevel.setCurrentPos( 0 );
}
}
else
{
// We have to deal with uncompleted pages now (if we have any)
- if ( leafLevel.nbAddedElems == nbElems )
+ if ( leafLevel.getNbAddedElems() == nbElems )
{
// First use case : we have injected all the elements in the btree : get out
break;
}
- if ( nbElems - leafLevel.nbElemsLimit > pageSize )
+ if ( nbElems - leafLevel.getNbElemsLimit() > pageSize )
{
// Second use case : the number of elements after the limit does not
// fit in a page, that means we have to split it into
// two pages
// First page will contain nbElems - leafLevel.nbElemsLimit - PageSize/2 elements
- int nbToAdd = nbElems - leafLevel.nbElemsLimit - pageSize / 2;
+ int nbToAdd = nbElems - leafLevel.getNbElemsLimit() - pageSize / 2;
while ( nbToAdd > 0 )
{
@@ -918,17 +857,17 @@ public class BulkLoader<K, V>
Tuple<K, Set<V>> tuple = dataIterator.next();
injectInLeaf( btree, tuple, leafLevel );
- leafLevel.nbAddedElems++;
+ leafLevel.incNbAddedElems();
nbToAdd--;
}
// Now inject the page into the node
- injectInNode( btree, leafLevel.currentPage, levels, 1 );
+ injectInNode( btree, leafLevel.getCurrentPage(), levels, 1 );
// Create a new page for the remaining elements
nbToAdd = pageSize / 2;
- leafLevel.currentPage = BTreeFactory.createLeaf( btree, 0L, nbToAdd );
- leafLevel.currentPos = 0;
+ leafLevel.setCurrentPage( BTreeFactory.createLeaf( btree, 0L, nbToAdd ) );
+ leafLevel.setCurrentPos( 0 );
while ( nbToAdd > 0 )
{
@@ -936,12 +875,12 @@ public class BulkLoader<K, V>
Tuple<K, Set<V>> tuple = dataIterator.next();
injectInLeaf( btree, tuple, leafLevel );
- leafLevel.nbAddedElems++;
+ leafLevel.incNbAddedElems();
nbToAdd--;
}
// And update the parent node
- injectInNode( btree, leafLevel.currentPage, levels, 1 );
+ injectInNode( btree, leafLevel.getCurrentPage(), levels, 1 );
// We are done
break;
@@ -950,7 +889,7 @@ public class BulkLoader<K, V>
{
// Third use case : we can push all the elements in the last page.
// Let's do it
- int nbToAdd = nbElems - leafLevel.nbElemsLimit;
+ int nbToAdd = nbElems - leafLevel.getNbElemsLimit();
while ( nbToAdd > 0 )
{
@@ -958,12 +897,12 @@ public class BulkLoader<K, V>
Tuple<K, Set<V>> tuple = dataIterator.next();
injectInLeaf( btree, tuple, leafLevel );
- leafLevel.nbAddedElems++;
+ leafLevel.incNbAddedElems();
nbToAdd--;
}
// Now inject the page into the node
- injectInNode( btree, leafLevel.currentPage, levels, 1 );
+ injectInNode( btree, leafLevel.getCurrentPage(), levels, 1 );
// and we are done
break;
@@ -980,7 +919,8 @@ public class BulkLoader<K, V>
* for the tuples having the same keys.
* @throws IOException
*/
- private File flushToDisk( int fileNb, List<Tuple<K, V>> tuples, BTree<K, V> btree ) throws IOException
+ private static <K, V> File flushToDisk( int fileNb, List<Tuple<K, V>> tuples, BTree<K, V> btree )
+ throws IOException
{
// Sort the tuples.
Tuple<K, Set<V>>[] sortedTuples = sort( btree, tuples );
@@ -1023,7 +963,7 @@ public class BulkLoader<K, V>
* Sort a list of tuples, eliminating the duplicate keys and storing the values in a set when we
* have a duplicate key
*/
- private Tuple<K, Set<V>>[] sort( BTree<K, V> btree, List<Tuple<K, V>> tuples )
+ private static <K, V> Tuple<K, Set<V>>[] sort( BTree<K, V> btree, List<Tuple<K, V>> tuples )
{
Comparator<Tuple<K, Set<V>>> tupleComparator = new TupleComparator( btree.getKeyComparator(), btree
.getValueComparator() );
@@ -1079,7 +1019,7 @@ public class BulkLoader<K, V>
/**
* Build an iterator over an array of sorted tuples, in memory
*/
- private Iterator<Tuple<K, Set<V>>> createTupleIterator( BTree<K, V> btree, List<Tuple<K, V>> tuples )
+ private static <K, V> Iterator<Tuple<K, Set<V>>> createTupleIterator( BTree<K, V> btree, List<Tuple<K, V>> tuples )
{
final Tuple<K, Set<V>>[] sortedTuples = sort( btree, tuples );
@@ -1121,7 +1061,7 @@ public class BulkLoader<K, V>
}
- private Tuple<K, Set<V>> fetchTuple( BTree<K, V> btree, FileInputStream fis )
+ private static <K, V> Tuple<K, Set<V>> fetchTuple( BTree<K, V> btree, FileInputStream fis )
{
try
{
@@ -1176,7 +1116,8 @@ public class BulkLoader<K, V>
* Build an iterator over an array of sorted tuples, from files on the disk
* @throws FileNotFoundException
*/
- private Iterator<Tuple<K, Set<V>>> createIterator( final BTree<K, V> btree, final FileInputStream[] streams )
+ private static <K, V> Iterator<Tuple<K, Set<V>>> createIterator( final BTree<K, V> btree,
+ final FileInputStream[] streams )
throws FileNotFoundException
{
// The number of files we have to read from
@@ -1295,7 +1236,8 @@ public class BulkLoader<K, V>
* Build an iterator over an array of sorted tuples, from files on the disk
* @throws FileNotFoundException
*/
- private Iterator<Tuple<K, Set<V>>> createUniqueFileIterator( final BTree<K, V> btree, final FileInputStream stream )
+ private static <K, V> Iterator<Tuple<K, Set<V>>> createUniqueFileIterator( final BTree<K, V> btree,
+ final FileInputStream stream )
throws FileNotFoundException
{
Iterator<Tuple<K, Set<V>>> tupleIterator = new Iterator<Tuple<K, Set<V>>>()
Added: directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/LevelInfo.java
URL: http://svn.apache.org/viewvc/directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/LevelInfo.java?rev=1660820&view=auto
==============================================================================
--- directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/LevelInfo.java (added)
+++ directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/LevelInfo.java Thu Feb 19 09:46:27 2015
@@ -0,0 +1,261 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.directory.mavibot.btree;
+
+
+/**
+ * A class to store informations on a level. We have to keep :
+ * <ul>
+ * <li>The number of elements to store in this level</li>
+ * <li>A flag that tells if it's a leaf or a node level</li>
+ * <li>The number of pages necessary to store all the elements in a level</li>
+ * <li>The number of elements we can store in a complete page (we may have one or two
+ * incomplete pages at the end)</li>
+ * <li>A flag that tells if we have some incomplete page at the end</li>
+ * </ul>
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class LevelInfo<K, V>
+{
+ /** The level number */
+ private int levelNumber;
+
+ /** Nb of elements for this level */
+ private int nbElems;
+
+ /** The number of pages in this level */
+ private int nbPages;
+
+ /** Nb of elements before we reach an incomplete page */
+ private int nbElemsLimit;
+
+ /** A flag that tells if the level contains nodes or leaves */
+ private boolean isNode;
+
+ /** The current page which contains the data until we move it to the resulting BTree */
+ private Page<K, V> currentPage;
+
+ /** The current position in the currentPage */
+ private int currentPos;
+
+ /** The number of already added elements for this level */
+ private int nbAddedElems;
+
+
+ /**
+ * @return the levelNumber
+ */
+ public int getLevelNumber()
+ {
+ return levelNumber;
+ }
+
+
+ /**
+ * @param levelNumber the levelNumber to set
+ */
+ public void setLevelNumber( int levelNumber )
+ {
+ this.levelNumber = levelNumber;
+ }
+
+
+ /**
+ * @return the nbElems
+ */
+ public int getNbElems()
+ {
+ return nbElems;
+ }
+
+
+ /**
+ * @param nbElems the nbElems to set
+ */
+ public void setNbElems( int nbElems )
+ {
+ this.nbElems = nbElems;
+ }
+
+
+ /**
+ * @return the nbPages
+ */
+ public int getNbPages()
+ {
+ return nbPages;
+ }
+
+
+ /**
+ * @param nbPages the nbPages to set
+ */
+ public void setNbPages( int nbPages )
+ {
+ this.nbPages = nbPages;
+ }
+
+
+ /**
+ * Increment the number of pages
+ */
+ public void incNbPages()
+ {
+ this.nbPages++;
+ }
+
+
+ /**
+ * @return the nbElemsLimit
+ */
+ public int getNbElemsLimit()
+ {
+ return nbElemsLimit;
+ }
+
+
+ /**
+ * @param nbElemsLimit the nbElemsLimit to set
+ */
+ public void setNbElemsLimit( int nbElemsLimit )
+ {
+ this.nbElemsLimit = nbElemsLimit;
+ }
+
+
+ /**
+ * @return the isNode
+ */
+ public boolean isNode()
+ {
+ return isNode;
+ }
+
+
+ /**
+ * @param isNode the isNode to set
+ */
+ public void setType( boolean isNode )
+ {
+ this.isNode = isNode;
+ }
+
+
+ /**
+ * @return the currentPage
+ */
+ public Page<K, V> getCurrentPage()
+ {
+ return currentPage;
+ }
+
+
+ /**
+ * @param currentPage the currentPage to set
+ */
+ public void setCurrentPage( Page<K, V> currentPage )
+ {
+ this.currentPage = currentPage;
+ }
+
+
+ /**
+ * @return the currentPos
+ */
+ public int getCurrentPos()
+ {
+ return currentPos;
+ }
+
+
+ /**
+ * @param currentPos the currentPos to set
+ */
+ public void setCurrentPos( int currentPos )
+ {
+ this.currentPos = currentPos;
+ }
+
+
+ /**
+ * Increment the current position
+ */
+ public void incCurrentPos()
+ {
+ this.currentPos++;
+ }
+
+
+ /**
+ * @return the nbAddedElems
+ */
+ public int getNbAddedElems()
+ {
+ return nbAddedElems;
+ }
+
+
+ /**
+ * @param nbAddedElems the nbAddedElems to set
+ */
+ public void setNbAddedElems( int nbAddedElems )
+ {
+ this.nbAddedElems = nbAddedElems;
+ }
+
+
+ /**
+ * Increment the number of added elements
+ */
+ public void incNbAddedElems()
+ {
+ this.nbAddedElems++;
+ }
+
+
+ /** @see Object#toString() */
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ if ( isNode )
+ {
+ sb.append( "NodeLevel[" );
+ sb.append( levelNumber );
+ sb.append( "] :" );
+ }
+ else
+ {
+ sb.append( "LeafLevel:" );
+ }
+
+ sb.append( "\n nbElems = " ).append( nbElems );
+ sb.append( "\n nbPages = " ).append( nbPages );
+ sb.append( "\n nbElemsLimit = " ).append( nbElemsLimit );
+ sb.append( "\n nbAddedElems = " ).append( nbAddedElems );
+ sb.append( "\n currentPos = " ).append( currentPos );
+ sb.append( "\n currentPage" );
+ sb.append( "\n nbKeys : " ).append( currentPage.getNbElems() );
+
+ return sb.toString();
+ }
+}
Modified: directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/BulkLoaderTest.java
URL: http://svn.apache.org/viewvc/directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/BulkLoaderTest.java?rev=1660820&r1=1660819&r2=1660820&view=diff
==============================================================================
--- directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/BulkLoaderTest.java (original)
+++ directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/BulkLoaderTest.java Thu Feb 19 09:46:27 2015
@@ -162,7 +162,6 @@ public class BulkLoaderTest
PersistedBTree<Long, String> btree = ( PersistedBTree<Long, String> ) rm.addBTree( "test",
LongSerializer.INSTANCE, StringSerializer.INSTANCE, false );
- BulkLoader<Long, String> bulkLoader = new BulkLoader<Long, String>();
int nbElems = i;
int addedElems = 0;
@@ -230,7 +229,7 @@ public class BulkLoaderTest
};
long t0 = System.currentTimeMillis();
- BTree<Long, String> result = bulkLoader.load( btree, tupleIterator, 128 );
+ BTree<Long, String> result = BulkLoader.load( btree, tupleIterator, 128 );
long t1 = System.currentTimeMillis();
if ( i % 100 == 0 )
@@ -426,8 +425,6 @@ public class BulkLoaderTest
PersistedBTree<Long, String> btree = ( PersistedBTree<Long, String> ) rm.addBTree( "test",
LongSerializer.INSTANCE, StringSerializer.INSTANCE, false );
- BulkLoader<Long, String> bulkLoader = new BulkLoader<Long, String>();
-
int[] expectedNbPages = new int[]
{
0,
@@ -458,11 +455,11 @@ public class BulkLoaderTest
System.out.println( "== Iteration n#" + i );
System.out.println( "=======================================" );
- BulkLoader<Long, String>.LevelInfo leafInfo = bulkLoader.computeLevel( btree, i, LevelEnum.LEAF );
+ LevelInfo<Long, String> leafInfo = BulkLoader.computeLevel( btree, i, LevelEnum.LEAF );
- assertEquals( expectedNbPages[i], leafInfo.nbPages );
- assertEquals( expectedLimit[i], leafInfo.nbElemsLimit );
- assertEquals( expectedKeys[i], leafInfo.currentPage.getNbElems() );
+ assertEquals( expectedNbPages[i], leafInfo.getNbPages() );
+ assertEquals( expectedLimit[i], leafInfo.getNbElemsLimit() );
+ assertEquals( expectedKeys[i], leafInfo.getCurrentPage().getNbElems() );
}
}
finally
@@ -489,8 +486,6 @@ public class BulkLoaderTest
PersistedBTree<Long, String> btree = ( PersistedBTree<Long, String> ) rm.addBTree( "test",
LongSerializer.INSTANCE, StringSerializer.INSTANCE, false );
- BulkLoader<Long, String> bulkLoader = new BulkLoader<Long, String>();
-
int[] expectedNbPages = new int[]
{
-1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -519,11 +514,11 @@ public class BulkLoaderTest
System.out.println( "== Iteration n#" + i );
System.out.println( "=======================================" );
- BulkLoader<Long, String>.LevelInfo nodeInfo = bulkLoader.computeLevel( btree, i, LevelEnum.NODE );
+ LevelInfo<Long, String> nodeInfo = BulkLoader.computeLevel( btree, i, LevelEnum.NODE );
- assertEquals( expectedNbPages[i], nodeInfo.nbPages );
- assertEquals( expectedLimit[i], nodeInfo.nbElemsLimit );
- assertEquals( expectedKeys[i], nodeInfo.currentPage.getNbElems() );
+ assertEquals( expectedNbPages[i], nodeInfo.getNbPages() );
+ assertEquals( expectedLimit[i], nodeInfo.getNbElemsLimit() );
+ assertEquals( expectedKeys[i], nodeInfo.getCurrentPage().getNbElems() );
}
}
finally
@@ -550,8 +545,6 @@ public class BulkLoaderTest
PersistedBTree<Long, String> btree = ( PersistedBTree<Long, String> ) rm.addBTree( "test",
LongSerializer.INSTANCE, StringSerializer.INSTANCE, false );
- BulkLoader<Long, String> bulkLoader = new BulkLoader<Long, String>();
-
int[] expectedNbPages = new int[]
{
-1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -580,9 +573,9 @@ public class BulkLoaderTest
System.out.println( "== Iteration #" + i );
System.out.println( "=======================================" );
- List<BulkLoader<Long, String>.LevelInfo> levels = bulkLoader.computeLevels( btree, i );
+ List<LevelInfo<Long, String>> levels = BulkLoader.computeLevels( btree, i );
- for ( BulkLoader<Long, String>.LevelInfo level : levels )
+ for ( LevelInfo<Long, String> level : levels )
{
System.out.println( level );
}
@@ -616,7 +609,6 @@ public class BulkLoaderTest
PersistedBTree<Long, String> btree = ( PersistedBTree<Long, String> ) rm.addBTree( "test",
LongSerializer.INSTANCE, StringSerializer.INSTANCE, false );
- BulkLoader<Long, String> bulkLoader = new BulkLoader<Long, String>();
int nbElems = i;
int addedElems = 0;
@@ -684,7 +676,7 @@ public class BulkLoaderTest
try
{
- result = bulkLoader.load( btree, tupleIterator, 128 );
+ result = BulkLoader.load( btree, tupleIterator, 128 );
}
catch ( NullPointerException npe )
{
@@ -762,7 +754,6 @@ public class BulkLoaderTest
PersistedBTree<Long, String> btree = ( PersistedBTree<Long, String> ) rm.addBTree( "test",
LongSerializer.INSTANCE, StringSerializer.INSTANCE, false );
- BulkLoader<Long, String> bulkLoader = new BulkLoader<Long, String>();
int nbElems = 4;
int addedElems = 0;
@@ -804,7 +795,7 @@ public class BulkLoaderTest
BTree<Long, String> result = null;
try
{
- result = bulkLoader.load( btree, tupleIterator, 128 );
+ result = BulkLoader.load( btree, tupleIterator, 128 );
}
catch ( NullPointerException npe )
{
@@ -1185,8 +1176,6 @@ public class BulkLoaderTest
// btree.valueThresholdUp = 8;
- BulkLoader<Long, String> bulkLoader = new BulkLoader<Long, String>();
-
Iterator<Tuple<Long, String>> tupleIterator = new Iterator<Tuple<Long, String>>()
{
private int pos = 0;
@@ -1217,7 +1206,7 @@ public class BulkLoaderTest
long t0 = System.currentTimeMillis();
BTree<Long, String> result = null;
- result = bulkLoader.load( btree, tupleIterator, 128 );
+ result = BulkLoader.load( btree, tupleIterator, 128 );
TupleCursor<Long, String> cursor = result.browse();
int nbFetched = 0;