/**
 * JDBM LICENSE v1.00
 *
 * Redistribution and use of this software and associated documentation
 * ("Software"), with or without modification, are permitted provided
 * that the following conditions are met:
 *
 * 1. Redistributions of source code must retain copyright
 *    statements and notices.  Redistributions must also contain a
 *    copy of this document.
 *
 * 2. Redistributions in binary form must reproduce the
 *    above copyright notice, this list of conditions and the
 *    following disclaimer in the documentation and/or other
 *    materials provided with the distribution.
 *
 * 3. The name "JDBM" must not be used to endorse or promote
 *    products derived from this Software without prior written
 *    permission of Cees de Groot.  For written permission,
 *    please contact cg@cdegroot.com.
 *
 * 4. Products derived from this Software may not be called "JDBM"
 *    nor may "JDBM" appear in their names without prior written
 *    permission of Cees de Groot.
 *
 * 5. Due credit should be given to the JDBM Project
 *    (http://jdbm.sourceforge.net/).
 *
 * THIS SOFTWARE IS PROVIDED BY THE JDBM PROJECT AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
 * CEES DE GROOT OR ANY CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Copyright 2001 (C) Alex Boisvert. All Rights Reserved.
 * Contributions are Copyright (C) 2001 by their associated contributors.
 *
 */

package jdbm.btree;


import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.Serializable;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Comparator;
import java.util.concurrent.atomic.AtomicInteger;

import jdbm.RecordManager;
import jdbm.ActionRecordManager;
import jdbm.helper.Serializer;
import jdbm.helper.Tuple;
import jdbm.helper.TupleBrowser;
import jdbm.helper.WrappedRuntimeException;
import jdbm.helper.ActionContext;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import org.apache.directory.server.i18n.I18n;


/**
 * B+Tree persistent indexing data structure.  B+Trees are optimized for
 * block-based, random I/O storage because they store multiple keys on
 * one tree node (called <code>BPage</code>).  In addition, the leaf nodes
 * directly contain (inline) the values associated with the keys, allowing a
 * single (or sequential) disk read of all the values on the page.
 * <p>
 * B+Trees are n-airy, yeilding log(N) search cost.  They are self-balancing,
 * preventing search performance degradation when the size of the tree grows.
 * <p>
 * Keys and associated values must be <code>Serializable</code> objects. The
 * user is responsible to supply a serializable <code>Comparator</code> object
 * to be used for the ordering of entries, which are also called <code>Tuple</code>.
 * The B+Tree allows traversing the keys in forward and reverse order using a
 * <p>
 * This implementation does not directly support duplicate keys, but it is
 * possible to handle duplicates by inlining or referencing an object collection
 * as a value.
 * <p>
 * There is no limit on key size or value size, but it is recommended to keep
 * both as small as possible to reduce disk I/O.   This is especially true for
 * the key size, which impacts all non-leaf <code>BPage</code> objects.
 *
 * @author <a href="mailto:boisvert@intalio.com">Alex Boisvert</a>
 */
public class BTree<K, V> implements Externalizable
{
    private static final boolean DEBUG = false;

    /** Version id for serialization. */
    final static long serialVersionUID = 1L;

    /** Default page size (number of entries per node) */
    public static final int DEFAULT_SIZE = 16;

    /** Page manager used to persist changes in BPages */
    protected transient RecordManager recordManager;

    /** This BTree's record ID in the PageManager. */
    private transient long recordId;

    /** Comparator used to index entries. */
    Comparator<K> comparator;

    /** Serializer used to serialize index keys (optional) */
    protected Serializer keySerializer;

    /** Serializer used to serialize index values (optional) */
    protected Serializer valueSerializer;

    /**
     * Height of the B+Tree.  This is the number of BPages you have to traverse
     * to get to a leaf BPage, starting from the root.
     */
    int bTreeHeight;

    /** Record id of the root BPage */
    private transient long rootId;

    /** Number of entries in each BPage. */
    protected int pageSize;

    /** Total number of entries in the BTree */
    protected AtomicInteger nbEntries;

    /** Serializer used for BPages of this tree */
    private transient BPage<K, V> bpageSerializer;
    
    /** TRUE if underlying record manager is snapshot capable */
    private transient boolean isActionCapable;
    
    
    /** Big lock snychronizing all actions */
    private transient Lock bigLock = new ReentrantLock(); 
    
    /** Meta root used to access versions of Btree root */
    private transient MetaRoot metaRoot = new MetaRoot();

    /**
     * No-argument constructor used by serialization.
     */
    public BTree()
    {
        // empty
    }


    /**
     * Create a new persistent BTree, with 16 entries per node.
     *
     * @param recman Record manager used for persistence.
     * @param comparator Comparator used to order index entries
     */
    public BTree( RecordManager recman, Comparator<K> comparator ) throws IOException
    {
        createInstance( recman, comparator, null, null, DEFAULT_SIZE );
    }


    /**
     * Create a new persistent BTree, with 16 entries per node.
     *
     * @param recman Record manager used for persistence.
     * @param keySerializer Serializer used to serialize index keys (optional)
     * @param valueSerializer Serializer used to serialize index values (optional)
     * @param comparator Comparator used to order index entries
     */
    public BTree( RecordManager recman, Comparator<K> comparator, Serializer keySerializer,
        Serializer valueSerializer ) throws IOException
    {
        createInstance( recman, comparator, keySerializer, valueSerializer, DEFAULT_SIZE );
    }


    /**
     * Create a new persistent BTree with the given number of entries per node.
     *
     * @param recman Record manager used for persistence.
     * @param comparator Comparator used to order index entries
     * @param keySerializer Serializer used to serialize index keys (optional)
     * @param valueSerializer Serializer used to serialize index values (optional)
     * @param pageSize Number of entries per page (must be even).
     */
    public BTree( RecordManager recman, Comparator<K> comparator, Serializer keySerializer,
        Serializer valueSerializer, int pageSize ) throws IOException
    {
        createInstance( recman, comparator, keySerializer, valueSerializer, pageSize );
    }
    
    
    /**
     * The real BTree constructor.
     */
    private void createInstance(RecordManager recordManager, Comparator<K> comparator, Serializer keySerializer,
        Serializer valueSerializer, int pageSize) throws IOException
    {
        if ( recordManager == null )
        {
            throw new IllegalArgumentException( I18n.err( I18n.ERR_517 ) );
        }

        if ( comparator == null )
        {
            throw new IllegalArgumentException( I18n.err( I18n.ERR_518 ) );
        }

        if ( !( comparator instanceof Serializable ) )
        {
            throw new IllegalArgumentException( I18n.err( I18n.ERR_519 ) );
        }

        // make sure there's an even number of entries per BPage
        if ( ( pageSize & 1 ) != 0 )
        {
            throw new IllegalArgumentException( I18n.err( I18n.ERR_522 ) );
        }

        this.recordManager = recordManager;
        this.comparator = comparator;
        this.keySerializer = keySerializer;
        this.valueSerializer = valueSerializer;
        this.pageSize = pageSize;
        this.bpageSerializer = new BPage<K, V>();
        this.bpageSerializer.btree = this;
        this.nbEntries = new AtomicInteger( 0 );
        
        this.isActionCapable = recordManager instanceof ActionRecordManager; 

        boolean abortedAction = false;
        ActionContext context = this.beginAction( false, "createInstance" );
        try
        {
            this.recordId = recordManager.insert( this );
            updateMetaRoot( this.rootId, this.bTreeHeight );
        }
        catch ( IOException e )
        {
            abortedAction = true;
            this.abortAction( context );
            throw e;
        }
        finally
        {
            if ( !abortedAction )
                this.endAction( context );
        }
    }
    
    
    public void setPageSize( int pageSize )
    {
        if ( ( pageSize & 0x0001 ) != 0 )
        {
            this.pageSize = DEFAULT_SIZE;
        }
        else
        {
            this.pageSize = pageSize;
        }
    }


    /**
     * Load a persistent BTree.
     *
     * @param recman RecordManager used to store the persistent btree
     * @param recid Record id of the BTree
     */
    public BTree<K, V> load( RecordManager recman, long recid ) throws IOException
    {
        BTree<K, V> btree = null;
        boolean abortedAction = false;
        ActionContext context = this.beginAction( false, "load" );
        try
        {
            btree = (BTree<K, V>) recman.fetch( recid );
            btree.recordId = recid;
            btree.recordManager = recman;
            btree.bpageSerializer = new BPage<K, V>();
            btree.bpageSerializer.btree = btree;
            btree.updateMetaRoot( btree.rootId, btree.bTreeHeight );

        }
        catch ( IOException e )
        {
            abortedAction = true;
            this.abortAction( context );
            throw e;
        }
        finally
        {
            if ( !abortedAction )
                this.endAction( context );
        }
        
               
        return btree;
    }


    /**
     * Insert an entry in the BTree.
     * <p>
     * The BTree cannot store duplicate entries.  An existing entry can be
     * replaced using the <code>replace</code> flag.   If an entry with the
     * same key already exists in the BTree, its value is returned.
     *
     * @param key Insert key
     * @param value Insert value
     * @param replace Set to true to replace an existing key-value pair.
     * @return Existing value, if any.
     */
    public Object insert( K key, V value, boolean replace ) throws IOException
    {
        if ( key == null )
        {
            throw new IllegalArgumentException( I18n.err( I18n.ERR_523 ) );
        }
        
        if ( value == null )
        {
            throw new IllegalArgumentException( I18n.err( I18n.ERR_524 ) );
        }

        
        boolean abortedAction = false;
        ActionContext context  = this.beginAction( false, "insert" );
        

        if ( !isActionCapable )
            bigLock.lock();
        
        try
        {
            BPage<K, V> rootPage = getRoot();
    
            if ( rootPage == null )
            {
                // BTree is currently empty, create a new root BPage
                if ( DEBUG )
                {
                    System.out.println( "BTree.insert() new root BPage" );
                }
                
                rootPage = new BPage<K, V>( this, key, value );
                rootId = rootPage.getRecordId();
                bTreeHeight = 1;
                nbEntries.set( 1 );
                recordManager.update( recordId, this );
                updateMetaRoot( this.rootId, this.bTreeHeight );
                return null;
            }
            else
            {
                BPage.InsertResult<K, V> insert = rootPage.insert( bTreeHeight, key, value, replace );
                if ( insert.pageNewCopy != null )
                    rootPage = insert.pageNewCopy;
                
                boolean dirty = false;
                
                if ( insert.overflow != null )
                {
                    // current root page overflowed, we replace with a new root page
                    if ( DEBUG )
                    {
                        System.out.println( "BTree.insert() replace root BPage due to overflow" );
                    }
                    
                    rootPage = new BPage<K, V>( this, rootPage, insert.overflow );
                    rootId = rootPage.getRecordId();
                    bTreeHeight += 1;
                    dirty = true;
                    updateMetaRoot( this.rootId, this.bTreeHeight );
                }
                
                if ( insert.existing == null )
                {
                    nbEntries.getAndIncrement();
                    dirty = true;
                }
                
                if ( dirty )
                {
                    recordManager.update( recordId, this );
                }
                
                // insert might have returned an existing value
                return insert.existing;
            }
        }
        catch ( IOException e )
        {
            abortedAction = true;
            this.abortAction( context );
            throw e;
        }
        finally
        {
            if ( !abortedAction )
                this.endAction( context );
            
            if ( !isActionCapable )
                bigLock.unlock();
        }
        
    }
        


    /**
     * Remove an entry with the given key from the BTree.
     *
     * @param key Removal key
     * @return Value associated with the key, or null if no entry with given
     *         key existed in the BTree.
     */
    public V remove( K key ) throws IOException
    {
        if ( key == null )
        {
            throw new IllegalArgumentException( I18n.err( I18n.ERR_523 ) );
        }
       
        
        boolean abortedAction = false;
        ActionContext context = this.beginAction( false, "remove" );

        if ( !isActionCapable )
            bigLock.lock();
        
        try
        {

            BPage<K, V> rootPage = getRoot();
            
            if ( rootPage == null )
            {
                return null;
            }
            
            boolean dirty = false;
            BPage.RemoveResult<K, V> remove = rootPage.remove( bTreeHeight, key );
            if ( remove.pageNewCopy != null )
                rootPage = remove.pageNewCopy;
            
            if ( remove.underflow && rootPage.isEmpty() )
            {
                bTreeHeight -= 1;
                dirty = true;
    
                recordManager.delete( rootId );
                
                if ( bTreeHeight == 0 )
                {
                    rootId = 0;
                }
                else
                {
                    rootId = rootPage.childBPage( pageSize - 1 ).getRecordId();
                }
                updateMetaRoot( this.rootId, this.bTreeHeight );
            }
            
            if ( remove.value != null )
            {
                nbEntries.getAndDecrement();
                dirty = true;
            }
            
            if ( dirty )
            {
                recordManager.update( recordId, this );
            }
            
            return remove.value;
        }
        catch ( IOException e )
        {
            abortedAction = true;
            this.abortAction( context );
            throw e;
        }
        finally
        {
            if ( !abortedAction )
                this.endAction( context );
            
            if ( !isActionCapable )
                bigLock.unlock();
        }
        
    }


    /**
     * Find the value associated with the given key.
     *
     * @param key Lookup key.
     * @return Value associated with the key, or null if not found.
     */
    public V find( K key ) throws IOException
    {
        TupleBrowser<K, V> browser = null;
        Tuple<K, V> tuple = null;
        
        if ( key == null )
        {
            throw new IllegalArgumentException( I18n.err( I18n.ERR_523 ) );
        }
        
        if ( !isActionCapable )
            bigLock.lock();
        
        try
        {      
            tuple = new Tuple<K, V>( null, null );
     
            browser = browse( key );
   
            if ( browser.getNext( tuple ) )
            {
                // find returns the matching key or the next ordered key, so we must
                // check if we have an exact match
                if ( comparator.compare( key, tuple.getKey() ) != 0 )
                {
                    return null;
                }
                else
                {
                   return this.copyValue( tuple.getValue() );
                }
            }
            else
            {
                return null;
            }
        }
        finally
        {
            if ( browser != null )
                browser.close();  

            if ( !isActionCapable )
                bigLock.unlock();
        }
        
    }


    /**
     * Find the value associated with the given key, or the entry immediately
     * following this key in the ordered BTree.
     *
     * @param key Lookup key.
     * @return Value associated with the key, or a greater entry, or null if no
     *         greater entry was found.
     */
    public Tuple<K, V> findGreaterOrEqual( K key ) throws IOException
    {
        Tuple<K, V> tuple;
        TupleBrowser<K, V> browser = null;

        if ( key == null )
        {
            // there can't be a key greater than or equal to "null"
            // because null is considered an infinite key.
            return null;
        }

        if ( !isActionCapable )
            bigLock.lock();
        
        tuple = new Tuple<K, V>( null, null );
        try
        {
            browser = browse( key );
            
            if ( browser.getNext( tuple ) )
            {
                tuple.setValue( this.copyValue( tuple.getValue() ) );
                return tuple;
            }
            else
            {
                return null;
            }
        }
        finally
        {
            if ( browser != null )
                browser.close(); 
            
            if ( !isActionCapable )
                bigLock.unlock();

        }
    }


    /**
     * Get a browser initially positioned at the beginning of the BTree.
     * <p><b>
     * WARNING: If you make structural modifications to the BTree during
     * browsing, you will get inconsistent browing results.
     * </b>
     *
     * @return Browser positionned at the beginning of the BTree.
     */
    public TupleBrowser<K, V> browse() throws IOException
    {
        TupleBrowser<K, V> browser = null;
        ActionContext context = this.beginAction( true, "browse" ); 
        try
        {
            MetaRoot meta = this.getMetaRoot();
            BPage<K, V> rootPage = this.getRoot( meta );
            
            if ( rootPage == null )
            {
                this.endAction( context );
                return new EmptyBrowser(){};
            }
            browser = rootPage.findFirst( context );         
        }
        catch( IOException e )
        {
            this.abortAction( context );
            throw e;
        }
        
        this.unsetAsCurrentAction( context );
        return browser;
    }


    /**
     * Get a browser initially positioned just before the given key.
     * <p><b>
     * WARNING: If you make structural modifications to the BTree during
     * browsing, you will get inconsistent browsing results.
     * </b>
     *
     * @param key Key used to position the browser.  If null, the browser
     *            will be positioned after the last entry of the BTree.
     *            (Null is considered to be an "infinite" key)
     * @return Browser positioned just before the given key.
     */
    public TupleBrowser<K, V> browse( K key ) throws IOException
    {
        TupleBrowser<K, V> browser = null;
        ActionContext context = this.beginAction( true, "browse key" );  
        try
        {
            MetaRoot meta = this.getMetaRoot();
            BPage<K, V> rootPage = this.getRoot( meta );
            
            if ( rootPage == null )
            {
                this.endAction( context );
                return new EmptyBrowser(){};
            }
          
            browser  = rootPage.find( meta.treeHeight, key, context );
        }
        catch( IOException e )
        {
            this.abortAction( context );
            throw e;
        }
        
        this.unsetAsCurrentAction( context );
        return browser;
    }
    


    /**
     * Return the number of entries (size) of the BTree.
     */
    public int size()
    {
        return nbEntries.get();
    }


    /**
     * Return the persistent record identifier of the BTree.
     */
    public long getRecordId()
    {
        return recordId;
    }


    /**
     * Return the root BPage<Object, Object>, or null if it doesn't exist.
     */
    BPage<K, V> getRoot( ) throws IOException
    {        
        assert( this.rootId == metaRoot.rootID) : "Stale root id " + this.rootId + " "+ metaRoot.rootID;
        
        if ( this.rootId == 0 )
        {
            return null;
        }
        
        BPage<K, V> root = ( BPage<K, V> ) recordManager.fetch( this.rootId, bpageSerializer );
        root.setRecordId( this.rootId );
        root.btree = this;
        
        return root;
    }
    
    BPage<K, V> getRoot( MetaRoot meta ) throws IOException
    {        
        if ( meta.rootID == 0 )
        {
            return null;
        }
        
        BPage<K, V> root = ( BPage<K, V> ) recordManager.fetch( meta.rootID, bpageSerializer );
        root.setRecordId( meta.rootID );
        root.btree = this;
        
        return root;
    }
    
    /**
     * 
     * Returns the meta root that can be used to fetch the root page
     *
     * @return meta root
     * @throws IOException
     */
    MetaRoot getMetaRoot() throws IOException
    {
        if ( isActionCapable )
            return ( MetaRoot )recordManager.fetch( -this.recordId );
        else
            return metaRoot;
    }
    
    
    
    


    /**
     * Implement Externalizable interface.
     */
    public void readExternal( ObjectInput in ) throws IOException, ClassNotFoundException
    {
        comparator = ( Comparator<K> ) in.readObject();
        keySerializer = ( Serializer ) in.readObject();
        valueSerializer = ( Serializer ) in.readObject();
        bTreeHeight = in.readInt();
        rootId = in.readLong();
        pageSize = in.readInt();
        nbEntries = new AtomicInteger( in.readInt() );
    }


    /**
     * Implement Externalizable interface.
     */
    public void writeExternal( ObjectOutput out ) throws IOException
    {
        out.writeObject( comparator );
        out.writeObject( keySerializer );
        out.writeObject( valueSerializer );
        out.writeInt( bTreeHeight );
        out.writeLong( rootId );
        out.writeInt( pageSize );
        out.writeInt( nbEntries.get() );
    }


    public void setValueSerializer( Serializer valueSerializer )
    {
        this.valueSerializer = valueSerializer;
    }

    
    /** PRIVATE INNER CLASS
     *  Browser returning no element.
     */
    class EmptyBrowser extends TupleBrowser<K, V>
    {
        public boolean getNext( Tuple<K, V> tuple )
        {
            return false;
        }

        public boolean getPrevious( Tuple<K, V> tuple )
        {
            return false;
        }
    }


    /**
     * @return the comparator
     */
    public Comparator<K> getComparator()
    {
        return comparator;
    }
    
    
    
    void setAsCurrentAction( ActionContext context )
    {
        if ( context != null )
        {
            assert( isActionCapable == true );
            ( ( ActionRecordManager )recordManager ).setCurrentActionContext( context );
        }
    }

    void unsetAsCurrentAction( ActionContext context )
    {
        if ( context != null )
        {
            assert( isActionCapable == true );
            ( ( ActionRecordManager )recordManager ).unsetCurrentActionContext( context );
        }
    }

    
    ActionContext beginAction( boolean readOnly, String whoStarted )
    {
        ActionContext context = null;
        if ( isActionCapable )
        {
            context = ( ( ActionRecordManager )recordManager ).beginAction( readOnly, whoStarted );
        }
        return context;
    }
    
    
    void endAction( ActionContext context )
    {
        if ( context != null )
        {
            assert( isActionCapable );
            ( ( ActionRecordManager )recordManager ).endAction( context );
        }
    }
    
    void abortAction( ActionContext context )
    {
        if ( context != null )
        {
            assert( isActionCapable );
            ( ( ActionRecordManager )recordManager ).abortAction( context );
        }

    }
    
    
    BPage<K,V> copyOnWrite( BPage<K,V> page) throws IOException
    {
       return page.copyOnWrite();

    }
    
    private MetaRoot copyOnWrite( MetaRoot oldMetaRoot )
    {
        MetaRoot newMetaRoot = new MetaRoot();
        newMetaRoot.rootID = oldMetaRoot.rootID;
        newMetaRoot.treeHeight = oldMetaRoot.treeHeight;
        
        return newMetaRoot;
    }
    
    private void updateMetaRoot( long newRootId, int newTreeHeight ) throws IOException
    {
        metaRoot = this.copyOnWrite( metaRoot );
        metaRoot.rootID = newRootId;
        metaRoot.treeHeight = newTreeHeight;
        
        if ( isActionCapable )
            recordManager.update( -this.recordId, metaRoot );
    }
    
    V copyValue( V value) throws IOException 
    {

        byte[] array;
        V valueCopy = null;
        
        if ( this.valueSerializer != null )
        {
            array = this.valueSerializer.serialize( value );
            valueCopy = (V) this.valueSerializer.deserialize( array );
        }
        else
        {
            ObjectOutputStream out = null;
            ObjectInputStream in = null;
            ByteArrayOutputStream bout = null;
            ByteArrayInputStream bin = null;

            try
            {
                bout = new ByteArrayOutputStream();
                out = new ObjectOutputStream( bout );
                out.writeObject( value );
                out.flush();
                byte[]  arr = bout.toByteArray();
                bin = new ByteArrayInputStream( arr );
                in =new ObjectInputStream( bin );
                valueCopy = ( V )in.readObject();
            }
            catch ( ClassNotFoundException e )
            {
                throw new WrappedRuntimeException( e );
            }
            finally
            {
                if ( bout != null )
                    bout.close();

                if ( out != null )
                    out.close();

                if ( bin != null )
                    bin.close();

                if ( in != null )
                    in.close();
            }

           }
           return valueCopy;   
    }
    
    
    
    public String toString()
    {
        StringBuilder sb = new StringBuilder();
        
        sb.append( "BTree" );
        sb.append( "(height:" ).append(bTreeHeight );
        sb.append( ", pageSize:" ).append( pageSize );
        sb.append( ", nbEntries:" ).append( nbEntries );
        sb.append( ", rootId:" ).append( rootId );
        sb.append( ", comparator:" );
        
        if ( comparator == null )
        {
            sb.append( "null" );
        }
        else
        {
            sb.append( comparator.getClass().getSimpleName() );
        }

        sb.append( ", keySerializer:" );
        
        if ( keySerializer == null )
        {
            sb.append( "null" );
        }
        else
        {
            sb.append( keySerializer.getClass().getSimpleName() );
        }

        sb.append( ", valueSerializer:" );

        if ( valueSerializer == null )
        {
            sb.append( "null" );
        }
        else
        {
            sb.append( valueSerializer.getClass().getSimpleName() );
        }
        
        sb.append( ")\n" );

        return sb.toString();
    }
    
    /**
     * Used to poin to the root page that the reader needs based on the reader's
     * read action context. ReadWrite actions always use the latest root. 
     */
    class MetaRoot
    {
        long rootID;
        int treeHeight;
    }
}
