directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From akaras...@apache.org
Subject svn commit: r608964 - in /directory/sandbox/akarasulu/bigbang/apacheds: btree-base/src/main/java/org/apache/directory/server/core/partition/impl/btree/ jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/
Date Fri, 04 Jan 2008 19:26:12 GMT
Author: akarasulu
Date: Fri Jan  4 11:26:10 2008
New Revision: 608964

URL: http://svn.apache.org/viewvc?rev=608964&view=rev
Log:
changes to store and btree abstraction ...
 
 o We can now afford to simplify the Table interface by removing the listTuple
   interfaces which positioned a cursor in various places with a single cursor()
   method and the cursor it self can be positioned after creation: meaning we 
   no longer need to coincide Cursor creation with Cursor positioning.
 o Removed a bunch of Enumeration implementations on JDBM btrees and cleaned up 
   the two jdbm cursors we have implemented.
 o Using generics for Tuple, Table and Cursors.


Added:
    directory/sandbox/akarasulu/bigbang/apacheds/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmDupsCursor.java
      - copied, changed from r607775, directory/sandbox/akarasulu/bigbang/apacheds/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/DupsCursor.java
    directory/sandbox/akarasulu/bigbang/apacheds/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmNoDupsCursor.java
      - copied, changed from r607775, directory/sandbox/akarasulu/bigbang/apacheds/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/TupleCursor.java
Removed:
    directory/sandbox/akarasulu/bigbang/apacheds/btree-base/src/main/java/org/apache/directory/server/core/partition/impl/btree/NoDupsCursor.java
    directory/sandbox/akarasulu/bigbang/apacheds/btree-base/src/main/java/org/apache/directory/server/core/partition/impl/btree/NoDupsEnumeration.java
    directory/sandbox/akarasulu/bigbang/apacheds/btree-base/src/main/java/org/apache/directory/server/core/partition/impl/btree/TupleBrowser.java
    directory/sandbox/akarasulu/bigbang/apacheds/btree-base/src/main/java/org/apache/directory/server/core/partition/impl/btree/TupleBrowserFactory.java
    directory/sandbox/akarasulu/bigbang/apacheds/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/BTreeCursor.java
    directory/sandbox/akarasulu/bigbang/apacheds/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/BTreeEnumeration.java
    directory/sandbox/akarasulu/bigbang/apacheds/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/BTreeIterator.java
    directory/sandbox/akarasulu/bigbang/apacheds/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/BTreeTupleCursor.java
    directory/sandbox/akarasulu/bigbang/apacheds/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/BTreeTupleEnumeration.java
    directory/sandbox/akarasulu/bigbang/apacheds/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/DupsCursor.java
    directory/sandbox/akarasulu/bigbang/apacheds/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/DupsEnumeration.java
    directory/sandbox/akarasulu/bigbang/apacheds/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmTupleBrowser.java
    directory/sandbox/akarasulu/bigbang/apacheds/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmTupleBrowserFactory.java
    directory/sandbox/akarasulu/bigbang/apacheds/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/TupleCursor.java
Modified:
    directory/sandbox/akarasulu/bigbang/apacheds/btree-base/src/main/java/org/apache/directory/server/core/partition/impl/btree/Table.java
    directory/sandbox/akarasulu/bigbang/apacheds/btree-base/src/main/java/org/apache/directory/server/core/partition/impl/btree/Tuple.java
    directory/sandbox/akarasulu/bigbang/apacheds/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmTable.java

Modified: directory/sandbox/akarasulu/bigbang/apacheds/btree-base/src/main/java/org/apache/directory/server/core/partition/impl/btree/Table.java
URL: http://svn.apache.org/viewvc/directory/sandbox/akarasulu/bigbang/apacheds/btree-base/src/main/java/org/apache/directory/server/core/partition/impl/btree/Table.java?rev=608964&r1=608963&r2=608964&view=diff
==============================================================================
--- directory/sandbox/akarasulu/bigbang/apacheds/btree-base/src/main/java/org/apache/directory/server/core/partition/impl/btree/Table.java (original)
+++ directory/sandbox/akarasulu/bigbang/apacheds/btree-base/src/main/java/org/apache/directory/server/core/partition/impl/btree/Table.java Fri Jan  4 11:26:10 2008
@@ -26,28 +26,27 @@
 
 
 /**
- * A wrapper interface around a BTree (that does not support duplicate keys) which 
- * transparently enables duplicate keys and translates underlying exceptions to
- * NamingExceptions.
+ * A wrapper interface around BTree implementations used to abstract away
+ * implementation details.
  * 
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  * @version $Rev$
  */
-public interface Table
+public interface Table<K, V>
 {
     /**
-     * Gets the comparator used by this Table: may be null if this Table was
-     * not initialized with one.
+     * Gets the comparator pair used by this Table: may be null if this Table
+     * was not initialized with one.
      *
-     * @return the final comparator instance or null if this Table was not
-     * created with one.
+     * @return the comparator pair or null if this Table was not created with
+     * one.
      */
     TupleComparator getComparator();
 
 
     /**
-     * Gets the data renderer used by this Table to display or log records keys
-     * and values.
+     * Gets an optional data renderer associated with this Table to display or
+     * log record keys and values.
      *
      * @return the renderer used
      */
@@ -72,9 +71,10 @@
 
 
     /**
-     * Checks to see if this Table has enabled the use of duplicate keys.
+     * Checks to see if this Table has allows for duplicate keys (a.k.a.
+     * multiple values for the same key).
      *
-     * @return true if duplicate keys are enabled, false otherwise.
+     * @return true if duplicate keys are enabled, false otherwise
      */
     boolean isDupsEnabled();
 
@@ -94,57 +94,57 @@
 
     
     /**
-     * Checks to see if this table has a key: same as a get call with a check to
-     * see if the returned value is null or not.
+     * Checks to see if this table has one or more tuples with a specific key:
+     * this is exactly the same as a get call with a check to see if the
+     * returned value is null or not.
      *
      * @param key the Object of the key to check for
-     * @return true if the key exists, false otherwise.
+     * @return true if the key exists, false otherwise
      * @throws IOException if there is a failure to read the underlying Db
      */
-    boolean has( Object key ) throws IOException;
+    boolean has( K key ) throws IOException;
 
 
     /**
      * Checks to see if this table has a key with a specific value.
      *
-     * @param key the key Object to check for
-     * @param value the value Object to check for
-     * @return true if a record with the key and value exists, false otherwise.
+     * @param key the key to check for
+     * @param value the value to check for
+     * @return true if a record with the key and value exists, false otherwise
      * @throws IOException if there is a failure to read the underlying Db
      */
-    boolean has( Object key, Object value ) throws IOException;
+    boolean has( K key, V value ) throws IOException;
 
 
     /**
      * Checks to see if this table has a record with a key greater/less than or
      * equal to the key argument.  The key argument need not exist for this
-     * call to return true.  The underlying database must be a BTree because
-     * this method depends on the use of sorted keys.
+     * call to return true.  The underlying database must sort keys based on a
+     * key comparator because this method depends on key ordering.
      *
-     * @param key the key Object to compare keys to
+     * @param key the key to compare keys to
      * @param isGreaterThan boolean for greater than or less then comparison
      * @return true if a record with a key greater/less than the key argument
      * exists, false otherwise
-     * @throws IOException if there is a failure to read the underlying Db,
-     * or if the underlying Db is not a Btree.
+     * @throws IOException if there is a failure to read the underlying Db
      */
-    boolean has( Object key, boolean isGreaterThan ) throws IOException;
+    boolean has( K key, boolean isGreaterThan ) throws IOException;
 
 
     /**
      * Checks to see if this table has a record with a key equal to the
      * argument key with a value greater/less than or equal to the value
      * argument provided.  The key argument <strong>MUST</strong> exist for
-     * this call to return true and the underlying Db must be a Btree that
-     * allows for sorted duplicate values.  The entire basis to this method
-     * depends on the fact that duplicate key values are sorted according to
-     * a valid value comparator function.
+     * this call to return true and the underlying Db must allows for sorted
+     * duplicate values.  The entire basis to this method depends on the fact
+     * that tuples of the same key have values sorted according to a valid
+     * value comparator.
      *
-     * If the table does not support duplicates then an 
+     * If the table does not support duplicates then an
      * UnsupportedOperationException is thrown.
      *
-     * @param key the key Object
-     * @param val the value Object to compare values to
+     * @param key the key
+     * @param val the value to compare values to
      * @param isGreaterThan boolean for greater than or less then comparison
      * @return true if a record with a key greater/less than the key argument
      * exists, false otherwise
@@ -152,7 +152,7 @@
      * or if the underlying Db is not of the Btree type that allows sorted
      * duplicate values.
      */
-    boolean has( Object key, Object val, boolean isGreaterThan ) throws IOException;
+    boolean has( K key, V val, boolean isGreaterThan ) throws IOException;
 
 
     // ------------------------------------------------------------------------
@@ -162,16 +162,16 @@
     /**
      * Gets the value of a record by key if the key exists.  If this Table
      * allows duplicate keys then the first key will be returned.  If this
-     * Table is also a Btree that first key will be the smallest key in the
-     * Table as specificed by this Table's comparator or the default berkeley
-     * bytewise lexical comparator.
+     * Table sorts keys then the key will be the smallest key in the Table as
+     * specificed by this Table's comparator or the default bytewise lexical
+     * comparator.
      *
      * @param key the key of the record
-     * @return the value of the record with key if key exists or null if
-     * no such record exists.
+     * @return the value of the record with the specified key if key exists or
+     * null if no such key exists.
      * @throws IOException if there is a failure to read the underlying Db
      */
-    Object get( Object key ) throws IOException;
+    V get( K key ) throws IOException;
 
 
     /**
@@ -179,27 +179,27 @@
      *
      * @param key the key of the record
      * @param value the value of the record.
-     * @return the last value present for key or null if this the key did not
+     * @return the last value present for the key or null if the key did not
      * exist before.
      * @throws IOException if there is a failure to read or write to
      * the underlying Db
      */
-    Object put( Object key, Object value ) throws IOException;
+    V put( K key, V value ) throws IOException;
 
 
     /**
-     * Puts a set of values into the Table.  If the Table does not support
-     * duplicate keys then only the first value found in the Cursor is added.
-     * If duplicate keys are not supported and there is more than one element
-     * in the Cursor an IllegalStateException will be raised without putting
-     * any values.
+     * Puts a set of values into the Table for a specific key.  If the Table
+     * does not support duplicate keys then only the first value found in the
+     * Cursor is added.  If duplicate keys are not supported and there is more
+     * than one element in the Cursor an IllegalStateException will be raised
+     * without putting any values into this Table.
      *
      * @param key the key to use for the values
      * @param values the values supplied as an cursor
      * @return the replaced object or null if one did not exist
      * @throws IOException if something goes wrong
      */
-    Object put( Object key, Cursor<Object> values ) throws IOException;
+    V put( K key, Cursor<V> values ) throws IOException;
 
 
     /**
@@ -210,7 +210,7 @@
      * @throws IOException if there is a failure to read or write to
      * the underlying Db
      */
-    Object remove( Object key ) throws IOException;
+    V remove( K key ) throws IOException;
 
 
     /**
@@ -223,7 +223,7 @@
      * @throws IOException if there is a failure to read or write to
      * the underlying Db
      */
-    Object remove( Object key, Object value ) throws IOException;
+    V remove( K key, V value ) throws IOException;
 
 
     /**
@@ -239,99 +239,23 @@
      * @throws IOException if there is a failure to read or write to
      * the underlying Db
      */
-    Object remove( Object key, Cursor<Object> values ) throws IOException;
-
-
-    /**
-     * Sets a Cursor to the first record in the Table with a key value of
-     * key and enables single next steps across all duplicate records with
-     * this key.  This Cursor will only iterate over duplicates of the key.
-     * Unlike listTuples(Object) which returns Tuples from the enumerations 
-     * this just returns the values of the key as an Object.
-     * 
-     * @param key the key to iterate over
-     * @return the values of the key ONLY, not the Tuples
-     * @throws IOException if the underlying btree browser could not be set
-     */
-    Cursor<Object> listValues( Object key ) throws IOException;
-
-
-    // ------------------------------------------------------------------------
-    // listTuples overloads
-    // ------------------------------------------------------------------------
-
-    
-    /**
-     * Sets a cursor to the first record in the Table and enables single
-     * next steps across all records.
-     *
-     * @return the values as key value Tuples
-     * @throws IOException if the underlying cursor could not be set.
-     */
-    Cursor<Tuple> listTuples() throws IOException;
+    V remove( K key, Cursor<V> values ) throws IOException;
 
 
     /**
-     * Sets a cursor to the first record in the Table with a key value of
-     * key and enables single next steps across all duplicate records with
-     * this key.  This cursor will only iterate over duplicates of the key.
+     * Creates a Cursor that traverses records in a Table.
      *
-     * Unlike listValues(Object) this returns Tuples from the resulting 
-     * Cursor.
-     *
-     * @param key the key to iterate over
-     * @return the values as key value Tuples
-     * @throws IOException if the underlying cursor could not be set
-     */
-    Cursor<Tuple> listTuples( Object key ) throws IOException;
-
-
-    /**
-     * Sets a cursor to the first record in the Table with a key value
-     * greater/less than or equal to key and enables single next steps across
-     * all records with key values equal to or less/greater than key.
-     *
-     * @param key the key to use to position this cursor to record with a key
-     * greater/less than or equal to it
-     * @param isGreaterThan if true the cursor iterates up over ascending keys
-     * greater than or equal to the key argument, but if false this cursor
-     * iterates down over descending keys less than or equal to key argument
-     * @return the values as key value Tuples
-     * @throws IOException if the underlying cursor could not be set
-     */
-    Cursor<Tuple> listTuples( Object key, boolean isGreaterThan ) throws IOException;
-
-
-    /**
-     * Sets a cursor to the first record in the Table with a key equal to
-     * the key argument whose value is greater/less than or equal to val and
-     * enables single next steps across all records with key equal to key.
-     * Hence this cursor will only iterate over duplicate keys where values are
-     * less than or greater than or equal to val.
-     *
-     * If the table does not support duplicates then an 
-     * UnsupportedOperationException is thrown.
-     *
-     * @param key the key to use to position this cursor to record with a key
-     * equal to it.
-     * @param val the value to use to position this cursor to record with a
-     * value greater/less than or equal to it.
-     * @param isGreaterThan if true the cursor iterates up over ascending
-     * values greater than or equal to the val argument, but if false this
-     * cursor iterates down over descending values less than or equal to val
-     * argument starting from the largest value going down
-     * @return the values as key value Tuples
-     * @throws IOException if the underlying cursor could not be set or
-     * this method is called over a cursor on a table that does not have sorted
-     * duplicates enabled.
+     * @return a Cursor over Tuples containing the key value pairs
+     * @throws IOException if there are failures accessing underlying stores
      */
-    Cursor<Tuple> listTuples( Object key, Object val, boolean isGreaterThan ) throws IOException;
+    Cursor<Tuple<K,V>> cursor() throws IOException;
 
 
     // ------------------------------------------------------------------------
     // Table Record Count Methods
     // ------------------------------------------------------------------------
 
+    
     /**
      * Gets the count of the number of records in this Table.
      *
@@ -349,7 +273,7 @@
      * @return the number of duplicate records for a key.
      * @throws IOException if there is a failure to read the underlying Db
      */
-    int count( Object key ) throws IOException;
+    int count( K key ) throws IOException;
 
 
     /**
@@ -362,7 +286,7 @@
      * @return the number of keys greater or less than key.
      * @throws IOException if there is a failure to read the underlying Db
      */
-    int count( Object key, boolean isGreaterThan ) throws IOException;
+    int count( K key, boolean isGreaterThan ) throws IOException;
 
 
     /**

Modified: directory/sandbox/akarasulu/bigbang/apacheds/btree-base/src/main/java/org/apache/directory/server/core/partition/impl/btree/Tuple.java
URL: http://svn.apache.org/viewvc/directory/sandbox/akarasulu/bigbang/apacheds/btree-base/src/main/java/org/apache/directory/server/core/partition/impl/btree/Tuple.java?rev=608964&r1=608963&r2=608964&view=diff
==============================================================================
--- directory/sandbox/akarasulu/bigbang/apacheds/btree-base/src/main/java/org/apache/directory/server/core/partition/impl/btree/Tuple.java (original)
+++ directory/sandbox/akarasulu/bigbang/apacheds/btree-base/src/main/java/org/apache/directory/server/core/partition/impl/btree/Tuple.java Fri Jan  4 11:26:10 2008
@@ -21,19 +21,17 @@
 
 
 /**
- * A key/value tuple for simple two column Tables.  Implemented to provide 
- * independence from the Jdbm Tuple class.  Key and value copying should be 
- * performed to transpose jdbm.helper.Tuple data into our generic Tuple.
+ * A key/value tuple for simple two column persistent Tables with sorted keys.
  * 
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  * @version $Rev$
  */
-public class Tuple
+public class Tuple<K, V>
 {
     /** the key for this Tuple */
-    private Object key;
+    private K key;
     /** the value for this Tuple */
-    private Object value;
+    private V value;
 
 
     /**
@@ -51,7 +49,7 @@
      * @param key the key to set
      * @param value the value to set
      */
-    public Tuple( Object key, Object value )
+    public Tuple( K key, V value )
     {
         this.key = key;
         this.value = value;
@@ -63,7 +61,7 @@
      *
      * @return the Tuple's key
      */
-    public Object getKey()
+    public K getKey()
     {
         return key;
     }
@@ -75,7 +73,7 @@
      * @param key the new key to set
      * @return this Tuple itself to set and return
      */
-    public Tuple setKey( Object key )
+    public Tuple<K,V> setKey( K key )
     {
         this.key = key;
         return this;
@@ -87,7 +85,7 @@
      *
      * @return the Tuple's value
      */
-    public Object getValue()
+    public V getValue()
     {
         return value;
     }
@@ -99,7 +97,7 @@
      * @param value the new value to set
      * @return this Tuple itself to set and return
      */
-    public Tuple setValue( Object value )
+    public Tuple<K,V> setValue( V value )
     {
         this.value = value;
         return this;
@@ -115,7 +113,7 @@
      * @param value the new value to set
      * @return this Tuple itself to set and return
      */
-    public Tuple setBoth( Object key, Object value )
+    public Tuple<K,V> setBoth( K key, V value )
     {
         this.key = key;
         this.value = value;

Copied: directory/sandbox/akarasulu/bigbang/apacheds/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmDupsCursor.java (from r607775, directory/sandbox/akarasulu/bigbang/apacheds/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/DupsCursor.java)
URL: http://svn.apache.org/viewvc/directory/sandbox/akarasulu/bigbang/apacheds/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmDupsCursor.java?p2=directory/sandbox/akarasulu/bigbang/apacheds/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmDupsCursor.java&p1=directory/sandbox/akarasulu/bigbang/apacheds/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/DupsCursor.java&r1=607775&r2=608964&rev=608964&view=diff
==============================================================================
--- directory/sandbox/akarasulu/bigbang/apacheds/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/DupsCursor.java (original)
+++ directory/sandbox/akarasulu/bigbang/apacheds/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmDupsCursor.java Fri Jan  4 11:26:10 2008
@@ -1,13 +1,12 @@
 package org.apache.directory.server.core.partition.impl.btree.jdbm;
 
 
-import jdbm.helper.Tuple;
 import jdbm.btree.BTree;
-import org.apache.directory.server.core.cursor.AbstractCursor;
 import org.apache.directory.server.core.cursor.InvalidCursorPositionException;
 import org.apache.directory.server.core.cursor.Cursor;
 import org.apache.directory.server.core.cursor.ListCursor;
-import org.apache.directory.server.core.partition.impl.btree.TupleComparator;
+import org.apache.directory.server.core.cursor.AbstractCursor;
+import org.apache.directory.server.core.partition.impl.btree.Tuple;
 import org.apache.directory.shared.ldap.NotImplementedException;
 
 import java.io.IOException;
@@ -17,35 +16,62 @@
 /**
  * A Cursor over a BTree which manages duplicate keys.
  */
-public class DupsCursor extends AbstractCursor<Tuple> 
+public class JdbmDupsCursor<K,V> extends AbstractCursor<Tuple<K,V>>
 {
-    private final JdbmTable table;
-    private final TupleComparator comparator;
-    private final TupleCursor wrapped;
-    private final Tuple tuple = new Tuple();
+    /**
+     * The JDBM backed table this Cursor traverses over.
+     */
+    private final JdbmTable<K,V> table;
+
+    /**
+     * The Tuple that is used to return values via the get() method. This
+     * same Tuple instance will be returned every time.  At different
+     * positions it may return different values for the same key if the table
+     * supports duplicate keys.
+     */
+    private final Tuple<K,V> tuple = new Tuple<K,V>();
+
+    /**
+     * The underlying Cursor which is simply returns Tuples with key value
+     * pairs in the btree of the JDBM Table.  It does not return different
+     * values for the same key: hence it is not duplicate key aware.  So for
+     * tables supporting duplicate keys, it's Tuple vlaues may contain
+     * TreeSet or BTreeRedirect objects.  These objects are processed by
+     * this outer Cursor to mimic traversal over the Table as if duplicate
+     * keys are natively allowed by JDBM.
+     *
+     * In essence the TreeSet and the BTreeRedirect are used to store multiple
+     * values for the same key.
+     */
+    private final JdbmNoDupsCursor<K,V> noDupsCursor;
+
+    /**
+     * A Cursor over a set of value objects for the current key.  A new Cursor
+     * will be created for each new key as we traverse table's that allow for
+     * duplicate keys.  The Cursor traverses over either a TreeSet object full
+     * of values in a multi-valued key or it traverses over a BTree which
+     * contains the values in it's keys.
+     */
+    private Cursor<V> dupCursor;
 
     /**
-     * A Cursor over a set of value objects for the same key.  It traverses
-     * over either a TreeSet of values in a multi valued key or it traverses
-     * over a BTree of values.
+     * The current Tuple returned from the underlying JdbmNoDupsCursor which
+     * may contain a TreeSet or BTreeRedirect for Tuple values.  A
+     * JdbmNoDupsCursor on a Table that allows duplicates returns TreeSets or
+     * BTreeRedirect objects for Tuple values.
      */
-    private Cursor<Object> dupCursor;
+    private Tuple<K,V> noDupsTuple;
 
     /**
-     * The current Tuple returned from the underlying TupleCursor which may
-     * contain a TreeSet for Tuple values.  A TupleCursor on a Table that
-     * allows duplicates essentially returns Strings for keys and TreeSets or
-     * BTreeRedirect objects for their values.
+     * Whether or not a value is available when get() is called.
      */
-    private Tuple duplicates;
     private boolean valueAvailable;
 
 
-    public DupsCursor( JdbmTable table, TupleCursor wrapped, TupleComparator comparator )
+    public JdbmDupsCursor( JdbmTable<K,V> table ) throws IOException
     {
         this.table = table;
-        this.wrapped = wrapped;
-        this.comparator = comparator;
+        this.noDupsCursor = new JdbmNoDupsCursor<K,V>( table );
     }
 
 
@@ -95,18 +121,18 @@
 
     public boolean last() throws IOException
     {
-        if ( wrapped.last() )
+        if ( noDupsCursor.last() )
         {
-            duplicates = wrapped.get();
-            Object values = duplicates.getValue();
+            noDupsTuple = noDupsCursor.get();
+            Object values = noDupsTuple.getValue();
 
             if ( values instanceof TreeSet)
             {
                 //noinspection unchecked
-                TreeSet<Object> set = ( TreeSet ) duplicates.getValue();
-                List<Object> list = new ArrayList<Object>( set.size() );
+                TreeSet<V> set = ( TreeSet ) noDupsTuple.getValue();
+                List<V> list = new ArrayList<V>( set.size() );
                 list.addAll( set );
-                dupCursor = new ListCursor<Object>( list );
+                dupCursor = new ListCursor<V>( list );
                 if ( ! dupCursor.previous() )
                 {
                     clearValue();
@@ -117,7 +143,7 @@
             {
                 BTree tree = table.getBTree( ( BTreeRedirect ) values );
                 //noinspection unchecked
-                dupCursor = new KeyCursor( tree, comparator.getKeyComparator() );
+                dupCursor = new KeyCursor( tree, table.getComparator().getKeyComparator() );
                 if ( ! dupCursor.previous() )
                 {
                     clearValue();
@@ -127,12 +153,12 @@
 
             /*
              * If we get to this point then cursor has more elements and
-             * duplicates holds the Tuple containing the key and the btree or
+             * noDupsTuple holds the Tuple containing the key and the btree or
              * TreeSet of values for that key which the Cursor traverses.  All we
              * need to do is populate our tuple object with the key and the value
              * in the cursor.
              */
-            tuple.setKey( duplicates.getKey() );
+            tuple.setKey( noDupsTuple.getKey() );
             tuple.setValue( dupCursor.get() );
             return valueAvailable = true;
         }
@@ -155,25 +181,25 @@
              * key/TreeSet Tuple to work with and get a cursor over it's
              * values.
              */
-            if ( wrapped.previous() )
+            if ( noDupsCursor.previous() )
             {
-                duplicates = wrapped.get();
-                Object values = duplicates.getValue();
+                noDupsTuple = noDupsCursor.get();
+                Object values = noDupsTuple.getValue();
 
                 if ( values instanceof TreeSet )
                 {
                     //noinspection unchecked
-                    TreeSet<Object> set = ( TreeSet ) duplicates.getValue();
-                    List<Object> list = new ArrayList<Object>( set.size() );
+                    TreeSet<V> set = ( TreeSet ) noDupsTuple.getValue();
+                    List<V> list = new ArrayList<V>( set.size() );
                     list.addAll( set );
-                    dupCursor = new ListCursor<Object>( list );
+                    dupCursor = new ListCursor<V>( list );
                     dupCursor.previous();
                 }
                 else if ( values instanceof BTreeRedirect )
                 {
                     BTree tree = table.getBTree( ( BTreeRedirect ) values );
                     //noinspection unchecked
-                    dupCursor = new KeyCursor( tree, comparator.getKeyComparator() );
+                    dupCursor = new KeyCursor( tree, table.getComparator().getKeyComparator() );
                     dupCursor.previous();
                 }
             }
@@ -185,12 +211,12 @@
 
         /*
          * If we get to this point then cursor has more elements and
-         * duplicates holds the Tuple containing the key and the btree or
+         * noDupsTuple holds the Tuple containing the key and the btree or
          * TreeSet of values for that key which the Cursor traverses.  All we
          * need to do is populate our tuple object with the key and the value
          * in the cursor.
          */
-        tuple.setKey( duplicates.getKey() );
+        tuple.setKey( noDupsTuple.getKey() );
         tuple.setValue( dupCursor.get() );
         return valueAvailable = true;
     }
@@ -208,25 +234,25 @@
              * If the underlying cursor has more elements we get the next
              * key/TreeSet Tuple to work with and get a cursor over it.
              */
-            if ( wrapped.next() )
+            if ( noDupsCursor.next() )
             {
-                duplicates = wrapped.get();
-                Object values = duplicates.getValue();
+                noDupsTuple = noDupsCursor.get();
+                Object values = noDupsTuple.getValue();
 
                 if ( values instanceof TreeSet)
                 {
                     //noinspection unchecked
-                    TreeSet<Object> set = ( TreeSet ) duplicates.getValue();
-                    List<Object> list = new ArrayList<Object>( set.size() );
+                    TreeSet<V> set = ( TreeSet ) noDupsTuple.getValue();
+                    List<V> list = new ArrayList<V>( set.size() );
                     list.addAll( set );
-                    dupCursor = new ListCursor<Object>( list );
+                    dupCursor = new ListCursor<V>( list );
                     dupCursor.next();
                 }
                 else if ( values instanceof BTreeRedirect )
                 {
                     BTree tree = table.getBTree( ( BTreeRedirect ) values );
                     //noinspection unchecked
-                    dupCursor = new KeyCursor( tree, comparator.getKeyComparator() );
+                    dupCursor = new KeyCursor( tree, table.getComparator().getKeyComparator() );
                     dupCursor.next();
                 }
             }
@@ -238,18 +264,18 @@
 
         /*
          * If we get to this point then cursor has more elements and
-         * duplicates holds the Tuple containing the key and the btree or
+         * noDupsTuple holds the Tuple containing the key and the btree or
          * TreeSet of values for that key which the Cursor traverses.  All we
          * need to do is populate our tuple object with the key and the value
          * in the cursor.
          */
-        tuple.setKey( duplicates.getKey() );
+        tuple.setKey( noDupsTuple.getKey() );
         tuple.setValue( dupCursor.get() );
         return valueAvailable = true;
     }
 
 
-    public Tuple get() throws IOException
+    public Tuple<K,V> get() throws IOException
     {
         checkClosed( "get()" );
 

Copied: directory/sandbox/akarasulu/bigbang/apacheds/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmNoDupsCursor.java (from r607775, directory/sandbox/akarasulu/bigbang/apacheds/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/TupleCursor.java)
URL: http://svn.apache.org/viewvc/directory/sandbox/akarasulu/bigbang/apacheds/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmNoDupsCursor.java?p2=directory/sandbox/akarasulu/bigbang/apacheds/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmNoDupsCursor.java&p1=directory/sandbox/akarasulu/bigbang/apacheds/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/TupleCursor.java&r1=607775&r2=608964&rev=608964&view=diff
==============================================================================
--- directory/sandbox/akarasulu/bigbang/apacheds/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/TupleCursor.java (original)
+++ directory/sandbox/akarasulu/bigbang/apacheds/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmNoDupsCursor.java Fri Jan  4 11:26:10 2008
@@ -21,13 +21,11 @@
 
 import org.apache.directory.server.core.cursor.AbstractCursor;
 import org.apache.directory.server.core.cursor.InvalidCursorPositionException;
+import org.apache.directory.server.core.partition.impl.btree.Tuple;
 
 import java.io.IOException;
-import java.util.Comparator;
 
-import jdbm.helper.Tuple;
 import jdbm.helper.TupleBrowser;
-import jdbm.btree.BTree;
 
 
 /**
@@ -39,34 +37,34 @@
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  * @version $Rev$, $Date$
  */
-public class TupleCursor extends AbstractCursor<Tuple>
+public class JdbmNoDupsCursor<K,V> extends AbstractCursor<Tuple<K,V>>
 {
-    private final Comparator comparator;
-    private final BTree btree;
+    private final JdbmTable table;
 
-    private Tuple tuple = new Tuple();
+    private jdbm.helper.Tuple jdbmTuple = new jdbm.helper.Tuple();
+    private Tuple<K,V> returnedTuple = new Tuple<K,V>();
     private TupleBrowser browser;
     private boolean valueAvailable;
 
 
     /**
-     * Creates a Cursor over the tuples of a JDBM BTree.
+     * Creates a Cursor over the tuples of a JDBM table.
      *
-     * @param btree the JDBM BTree to build a Cursor over
-     * @param comparator the Comparator used to determine <b>key</b> ordering
+     * @param table the JDBM Table to build a Cursor over
      * @throws IOException of there are problems accessing the BTree
      */
-    public TupleCursor( BTree btree, Comparator comparator ) throws IOException
+    public JdbmNoDupsCursor( JdbmTable table ) throws IOException
     {
-        this.btree = btree;
-        this.comparator = comparator;
+        this.table = table;
     }
 
 
     private void clearValue()
     {
-        tuple.setKey( null );
-        tuple.setValue( null );
+        returnedTuple.setKey( null );
+        returnedTuple.setValue( null );
+        jdbmTuple.setKey( null );
+        jdbmTuple.setValue( null );
         valueAvailable = false;
     }
 
@@ -85,14 +83,14 @@
      */
     public void before( Tuple element ) throws IOException
     {
-        browser = btree.browse( element.getKey() );
+        browser = table.getBTree().browse( element.getKey() );
         clearValue();
     }
 
 
     public void after( Tuple element ) throws IOException
     {
-        browser = btree.browse( element.getKey() );
+        browser = table.getBTree().browse( element.getKey() );
 
         /*
          * While the next value is less than or equal to the element keep
@@ -101,12 +99,12 @@
          * the element then we stop, backup, and return so subsequent calls
          * to getNext() will return a value greater than the element.
          */
-        while ( browser.getNext( tuple ) )
+        while ( browser.getNext( jdbmTuple ) )
         {
-            Object next = tuple.getKey();
+            Object next = jdbmTuple.getKey();
 
             //noinspection unchecked
-            int nextCompared = comparator.compare( next, element.getKey() );
+            int nextCompared = table.getComparator().getKeyComparator().compare( next, element.getKey() );
 
             if ( nextCompared <= 0 )
             {
@@ -120,12 +118,12 @@
                  * the call below to getPrevious() will fail.  In this special
                  * case we just reset the Cursor's browser and return.
                  */
-                if ( browser.getPrevious( tuple ) )
+                if ( browser.getPrevious( jdbmTuple ) )
                 {
                 }
                 else
                 {
-                    browser = btree.browse( element.getKey() );
+                    browser = table.getBTree().browse( element.getKey() );
                 }
 
                 clearValue();
@@ -140,14 +138,14 @@
 
     public void beforeFirst() throws IOException
     {
-        browser = btree.browse();
+        browser = table.getBTree().browse();
         clearValue();
     }
 
 
     public void afterLast() throws IOException
     {
-        browser = btree.browse( null );
+        browser = table.getBTree().browse( null );
     }
 
 
@@ -167,8 +165,12 @@
 
     public boolean previous() throws IOException
     {
-        if ( browser.getPrevious( tuple ) )
+        if ( browser.getPrevious( jdbmTuple ) )
         {
+            //noinspection unchecked
+            returnedTuple.setKey( ( K ) jdbmTuple.getKey() );
+            //noinspection unchecked
+            returnedTuple.setValue( ( V ) jdbmTuple.getValue() );
             return valueAvailable = true;
         }
         else
@@ -181,8 +183,12 @@
 
     public boolean next() throws IOException
     {
-        if ( browser.getNext( tuple ) )
+        if ( browser.getNext( jdbmTuple ) )
         {
+            //noinspection unchecked
+            returnedTuple.setKey( ( K ) jdbmTuple.getKey() );
+            //noinspection unchecked
+            returnedTuple.setValue( ( V ) jdbmTuple.getValue() );
             return valueAvailable = true;
         }
         else
@@ -193,12 +199,12 @@
     }
 
 
-    public Tuple get() throws IOException
+    public Tuple<K,V> get() throws IOException
     {
         if ( valueAvailable )
         {
             //noinspection unchecked
-            return tuple;
+            return returnedTuple;
         }
 
         throw new InvalidCursorPositionException();
@@ -208,11 +214,5 @@
     public boolean isElementReused()
     {
         return true;
-    }
-
-
-    BTree getBTree()
-    {
-        return btree;
     }
 }

Modified: directory/sandbox/akarasulu/bigbang/apacheds/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmTable.java
URL: http://svn.apache.org/viewvc/directory/sandbox/akarasulu/bigbang/apacheds/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmTable.java?rev=608964&r1=608963&r2=608964&view=diff
==============================================================================
--- directory/sandbox/akarasulu/bigbang/apacheds/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmTable.java (original)
+++ directory/sandbox/akarasulu/bigbang/apacheds/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmTable.java Fri Jan  4 11:26:10 2008
@@ -25,12 +25,7 @@
 import jdbm.helper.Serializer;
 import jdbm.helper.TupleBrowser;
 import org.apache.directory.server.core.cursor.Cursor;
-import org.apache.directory.server.core.cursor.EmptyCursor;
-import org.apache.directory.server.core.cursor.IteratorCursor;
-import org.apache.directory.server.core.cursor.SingletonCursor;
 import org.apache.directory.server.core.partition.impl.btree.*;
-import org.apache.directory.server.core.partition.impl.btree.jdbm.KeyCursor;
-import org.apache.directory.server.core.partition.impl.btree.jdbm.TupleCursor;
 import org.apache.directory.server.schema.SerializableComparator;
 
 import javax.naming.NamingException;
@@ -44,7 +39,7 @@
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  * @version $Rev$
  */
-public class JdbmTable implements Table
+public class JdbmTable<K,V> implements Table<K,V>
 {
     /**  */
     private static final String SZSUFFIX = "_btree_sz";
@@ -64,8 +59,6 @@
     private int count;
     /** */
     private BTree bt;
-    /** */
-    private TupleBrowserFactory browserFactory;
 
 
     /** */
@@ -86,11 +79,17 @@
      *
      * @param name the name of the table
      * @param allowsDuplicates whether or not duplicates are enabled 
+     * @param numDupLimit the size limit of duplicates before switching to
+     * BTrees for values instead of TreeSets
      * @param manager the record manager to be used for this table
      * @param comparator a tuple comparator
+     * @param keySerializer a serializer to use for the keys instead of using
+     * default Java serialization which could be very expensive
+     * @param valueSerializer a serializer to use for the values instead of
+     * using default Java serialization which could be very expensive
      * @throws NamingException if the table's file cannot be created
      */
-    public JdbmTable( String name, boolean allowsDuplicates, int numDupLimit, 
+    public JdbmTable( String name, boolean allowsDuplicates, int numDupLimit,
         RecordManager manager, TupleComparator comparator, Serializer keySerializer, 
         Serializer valueSerializer )
         throws NamingException
@@ -146,33 +145,6 @@
             ne.setRootCause( e );
             throw ne;
         }
-
-        
-        browserFactory = new TupleBrowserFactory()
-        {
-            public long size() throws IOException
-            {
-                return bt.size();
-            }
-
-
-            public org.apache.directory.server.core.partition.impl.btree.TupleBrowser beforeFirst() throws IOException
-            {
-                return new JdbmTupleBrowser( bt.browse() );
-            }
-
-
-            public org.apache.directory.server.core.partition.impl.btree.TupleBrowser afterLast() throws IOException
-            {
-                return new JdbmTupleBrowser( bt.browse( null ) );
-            }
-
-
-            public org.apache.directory.server.core.partition.impl.btree.TupleBrowser beforeKey( Object key ) throws IOException
-            {
-                return new JdbmTupleBrowser( bt.browse( key ) );
-            }
-        };
     }
 
 
@@ -183,12 +155,18 @@
      * @param name the name of the table
      * @param manager the record manager to be used for this table
      * @param keyComparator a tuple comparator
+     * @param keySerializer a serializer to use for the keys instead of using
+     * default Java serialization which could be very expensive
+     * @param valueSerializer a serializer to use for the values instead of
+     * using default Java serialization which could be very expensive
      * @throws NamingException if the table's file cannot be created
      */
-    public JdbmTable( String name, RecordManager manager, SerializableComparator keyComparator, Serializer keySerializer, Serializer valueSerializer ) 
+    public JdbmTable( String name, RecordManager manager, SerializableComparator keyComparator,
+                      Serializer keySerializer, Serializer valueSerializer )
         throws NamingException
     {
-        this( name, false, Integer.MAX_VALUE, manager, new KeyOnlyComparator( keyComparator ), keySerializer, valueSerializer );
+        this( name, false, Integer.MAX_VALUE, manager, new KeyOnlyComparator( keyComparator ),
+                keySerializer, valueSerializer );
     }
 
 
@@ -196,6 +174,7 @@
     // Simple Table Properties
     // ------------------------------------------------------------------------
 
+    
     /**
      * @see org.apache.directory.server.core.partition.impl.btree.Table#getComparator()
      */
@@ -260,7 +239,7 @@
     /**
      * @see Table#count(java.lang.Object, boolean)
      */
-    public int count( Object key, boolean isGreaterThan ) throws IOException
+    public int count( K key, boolean isGreaterThan ) throws IOException
     {
         // take a best guess
         return count;
@@ -270,7 +249,7 @@
     /**
      * @see Table#count(java.lang.Object)
      */
-    public int count( Object key ) throws IOException
+    public int count( K key ) throws IOException
     {
         if ( !allowsDuplicates )
         {
@@ -326,10 +305,8 @@
     // get/has/put/remove Methods and Overloads
     // ------------------------------------------------------------------------
 
-    /**
-     * @see Table#get(java.lang.Object)
-     */
-    public Object get( Object key ) throws IOException
+
+    public V get( K key ) throws IOException
     {
         if ( ! allowsDuplicates )
         {
@@ -345,7 +322,8 @@
         
         if ( values instanceof TreeSet )
         {
-            TreeSet set = ( TreeSet ) values;
+            //noinspection unchecked
+            TreeSet<V> set = ( TreeSet<V> ) values;
             
             if ( set.size() == 0 )
             {
@@ -380,7 +358,7 @@
      * java.lang.Object, boolean)
      */
     @SuppressWarnings("unchecked")
-    public boolean has( Object key, Object val, boolean isGreaterThan ) throws IOException
+    public boolean has( K key, V val, boolean isGreaterThan ) throws IOException
     {
         if ( !allowsDuplicates )
         {
@@ -452,7 +430,7 @@
     /**
      * @see Table#has(java.lang.Object, boolean)
      */
-    public boolean has( Object key, boolean isGreaterThan ) throws IOException
+    public boolean has( K key, boolean isGreaterThan ) throws IOException
     {
         // See if we can find the border between keys greater than and less
         // than in the set of keys.  This will be the spot we search from.
@@ -534,7 +512,7 @@
      * @see org.apache.directory.server.core.partition.impl.btree.Table#has(java.lang.Object,
      * java.lang.Object)
      */
-    public boolean has( Object key, Object value ) throws IOException
+    public boolean has( K key, V value ) throws IOException
     {
         if ( ! allowsDuplicates )
         {
@@ -566,7 +544,7 @@
     /**
      * @see Table#has(java.lang.Object)
      */
-    public boolean has( Object key ) throws IOException
+    public boolean has( K key ) throws IOException
     {
         return getRaw( key ) != null;
     }
@@ -577,13 +555,13 @@
      * java.lang.Object)
      */
     @SuppressWarnings("unchecked")
-    public Object put( Object key, Object value ) throws IOException
+    public V put( K key, V value ) throws IOException
     {
-        Object replaced;
+        V replaced;
 
         if ( ! allowsDuplicates )
         {
-            replaced = putRaw( key, value, true );
+            replaced = ( V ) bt.insert( key, value, true );
 
             if ( null == replaced )
             {
@@ -597,12 +575,12 @@
         
         if ( values == null )
         {
-            values = new TreeSet( comparator.getValueComparator() );
+            values = new TreeSet<V>( comparator.getValueComparator() );
         }
         
         if ( values instanceof TreeSet )
         {
-            TreeSet set = ( TreeSet ) values;
+            TreeSet<V> set = ( TreeSet ) values;
             
             if ( set.contains( value ) )
             {
@@ -615,11 +593,11 @@
             {
                 BTree tree = convertToBTree( set );
                 BTreeRedirect redirect = new BTreeRedirect( tree.getRecid() );
-                replaced = putRaw( key, redirect, true );
+                replaced = ( V ) bt.insert( key, redirect, true );
             }
             else
             {
-                replaced = putRaw( key, set, true );
+                replaced = ( V ) bt.insert( key, set, true );
             }
             
             if ( addSuccessful )
@@ -636,7 +614,6 @@
             if ( insertDupIntoBTree( tree, value ) )
             {
                 count++;
-                return values;
             }
             return null;
         }
@@ -649,7 +626,7 @@
      * @see Table#put(Object, Cursor
      */
     @SuppressWarnings("unchecked")
-    public Object put( Object key, Cursor<Object> values ) throws IOException
+    public V put( K key, Cursor<V> values ) throws IOException
     {
         /*
          * If we do not allow duplicates call the single add put using the
@@ -661,7 +638,7 @@
         {
             if ( values.next() )
             {
-                Object value = values.get();
+                V value = values.get();
 
                 if ( values.next() )
                 {
@@ -678,7 +655,7 @@
         Object storedValues = getRaw( key );
         if ( storedValues == null )
         {
-            storedValues = new TreeSet( comparator.getValueComparator() );
+            storedValues = new TreeSet<V>( comparator.getValueComparator() );
         }
         
         if ( storedValues instanceof TreeSet )
@@ -689,10 +666,10 @@
              * does not exist for key.  We check if the value is present and
              * if it is we add it and increment the table entry counter.
              */
-            TreeSet set = ( TreeSet ) storedValues;
+            TreeSet<V> set = ( TreeSet<V> ) storedValues;
             while ( values.next() )
             {
-                Object val = values.get();
+                V val = values.get();
     
                 if ( !set.contains( val ) )
                 {
@@ -708,11 +685,11 @@
             {
                 BTree tree = convertToBTree( set );
                 BTreeRedirect redirect = new BTreeRedirect( tree.getRecid() );
-                return putRaw( key, redirect, true );
+                return ( V ) bt.insert( key, redirect, true );
             }
             else
             {
-                return putRaw( key, set, true );
+                return ( V ) bt.insert( key, set, true );
             }
         }
         
@@ -721,7 +698,7 @@
             BTree tree = getBTree( ( BTreeRedirect ) storedValues );
             while ( values.next() )
             {
-                Object val = values.get();
+                V val = values.get();
                 
                 if ( insertDupIntoBTree( tree, val ) )
                 {
@@ -729,7 +706,7 @@
                 }
             }
 
-            return storedValues;
+            return null;
         }
         
         throw new IllegalStateException( "When using duplicate keys either a TreeSet or BTree is used for values." );
@@ -740,16 +717,15 @@
      * @see Table#remove(java.lang.Object,
      * java.lang.Object)
      */
-    public Object remove( Object key, Object value ) throws IOException
+    public V remove( K key, V value ) throws IOException
     {
         if ( ! allowsDuplicates )
         {
-            Object oldValue = getRaw( key );
+            V oldValue = getRaw( key );
         
             // Remove the value only if it is the same as value.
             if ( oldValue != null && oldValue.equals( value ) )
             {
-                removeRaw( key );
                 count--;
                 return oldValue;
             }
@@ -773,11 +749,10 @@
             {
                 if ( set.isEmpty() )
                 {
-                    removeRaw( key );
                 }
                 else
                 {
-                    putRaw( key, set, true );
+                    bt.insert( key, set, true );
                 }
 
                 // Decrement counter if removal occurs.
@@ -798,7 +773,6 @@
             {
                 if ( tree.size() == 0 )
                 {
-                    removeRaw( key );
                 }
                 
                 count--;
@@ -815,7 +789,7 @@
     /**
      * @see Table#remove(Object, Cursor
      */
-    public Object remove( Object key, Cursor<Object> values ) throws IOException
+    public V remove( K key, Cursor<V> values ) throws IOException
     {
         /*
          * If we do not allow dupliicates call the single remove using the
@@ -827,7 +801,7 @@
         {
             if ( values.next() )
             {
-                Object value = values.get();
+                V value = values.get();
 
                 if ( values.next() )
                 {
@@ -855,17 +829,18 @@
              * Table holding all the duplicate key values or return null if it
              * does not exist for key - nothing to do here.
              */
-            TreeSet set = ( TreeSet ) storedValues;
+            //noinspection unchecked
+            TreeSet<V> set = ( TreeSet<V> ) storedValues;
     
             /*
              * So we have a valid TreeSet with values in it.  We check if each value
              * is in the set and remove it if it is present.  We decrement the 
              * counter while doing so.
              */
-            Object firstValue = null;
+            V firstValue = null;
             while ( values.next() )
             {
-                Object val = values.get();
+                V val = values.get();
     
                 // get the first value
                 if ( firstValue == null )
@@ -881,7 +856,7 @@
             }
     
             // Return the raw TreeSet and put the changed one back.
-            putRaw( key, set, true );
+            bt.insert( key, set, true );
             return firstValue;
         }
         
@@ -890,10 +865,10 @@
         if ( storedValues instanceof BTreeRedirect )
         {
             BTree tree = getBTree( ( BTreeRedirect ) storedValues );
-            Object first = null;
+            V first = null;
             while ( values.next() )
             {
-                Object val = values.get();
+                V val = values.get();
                 
                 if ( removeDupFromBTree( tree, val ) )
                 {
@@ -916,9 +891,10 @@
     /**
      * @see Table#remove(java.lang.Object)
      */
-    public Object remove( Object key ) throws IOException
+    public V remove( K key ) throws IOException
     {
-        Object returned = removeRaw( key );
+        //noinspection unchecked
+        V returned = ( V ) bt.remove( key );
 
         if ( null == returned )
         {
@@ -933,7 +909,8 @@
 
         if ( returned instanceof TreeSet )
         {
-            TreeSet set = ( TreeSet ) returned;
+            //noinspection unchecked
+            TreeSet<V> set = ( TreeSet<V> ) returned;
             this.count -= set.size();
             return set.first();
         }
@@ -949,249 +926,17 @@
     }
 
 
-    /**
-     * @see Table#listValues(java.lang.Object)
-     */
-    public Cursor<Object> listValues( Object key ) throws IOException
-    {
-        if ( !allowsDuplicates )
-        {
-            Object value = get( key );
-
-            if ( null == value )
-            {
-                return new EmptyCursor();
-            }
-            else
-            {
-                return new SingletonCursor( value );
-            }
-        }
-
-        Object values = getRaw( key );
-        
-        if ( values == null )
-        {
-            return new EmptyCursor<Object>();
-        }
-        
-        if ( values instanceof TreeSet )
-        {
-            TreeSet set = ( TreeSet ) values;
-            return new IteratorCursor<Object>( set.iterator() );
-        }
-        
-        if ( values instanceof BTreeRedirect )
-        {
-            BTree tree = getBTree( ( BTreeRedirect ) values );
-            return new KeyCursor( tree, comparator.getKeyComparator() );
-        }
-        
-        throw new IllegalStateException( "When using duplicate keys either a TreeSet or BTree is used for values." );
-    }
-
-
-    // ------------------------------------------------------------------------
-    // listTuple Overloads 
-    // ------------------------------------------------------------------------
-
-    
-    /**
-     * @see org.apache.directory.server.core.partition.impl.btree.Table#listTuples()
-     */
-    public Cursor<Tuple> listTuples() throws IOException
+    public Cursor<Tuple<K,V>> cursor() throws IOException
     {
-        Cursor<Tuple> list = new NoDupsCursor( browserFactory );
-
         if ( allowsDuplicates )
         {
-            return new DupsEnumeration( this, ( NoDupsEnumeration ) list );
+            return new JdbmDupsCursor<K,V>( this );
         }
 
-        return list;
+        return new JdbmNoDupsCursor<K,V>( this );
     }
 
 
-    /**
-     * @see org.apache.directory.server.core.partition.impl.btree.Table#listTuples(java.lang.Object)
-     */
-    @SuppressWarnings("unchecked")
-    public Cursor<Tuple> listTuples( Object key ) throws IOException
-    {
-        // Handle single and zero value returns without duplicates enabled
-        if ( !allowsDuplicates )
-        {
-            Object val = getRaw( key );
-
-            if ( null == val )
-            {
-                return new EmptyCursor();
-            }
-            else
-            {
-                return new SingletonCursor( new Tuple( key, getRaw( key ) ) );
-            }
-        }
-
-        Object values = getRaw( key );
-
-        if ( values == null )
-        {
-            return new EmptyCursor();
-        }
-        
-        if ( values instanceof TreeSet )
-        {
-            TreeSet set = ( TreeSet ) values;
-            Object[] objs = new Object[set.size()];
-            objs = set.toArray( objs );
-            return new ValueArrayCursor( key, objs );
-        }
-        
-        if ( values instanceof BTreeRedirect )
-        {
-            return new SameKeyTupleCursor( getBTree( ( BTreeRedirect ) values ), key, comparator.getValueComparator() );
-        }
-
-        throw new IllegalStateException( "When using duplicate keys either a TreeSet or BTree is used for values." );
-    }
-
-
-    /**
-     * @see Table#listTuples(java.lang.Object,
-     * boolean)
-     */
-    public Cursor<Tuple> listTuples( Object key, boolean isGreaterThan ) throws IOException
-    {
-        Cursor<Tuple> list;
-
-        if ( isGreaterThan )
-        {
-            list = new NoDupsCursor( browserFactory, key );
-        }
-        else
-        {
-            /* According to the jdbm docs a browser is positioned right
-             * before a key greater than or equal to key.  getNext() will
-             * return the next tuple with a key greater than or equal to
-             * key.  getPrevious() used in descending scans for less than
-             * for equal to comparisions will not.  We need to advance
-             * forward once and check if the returned Tuple key equals
-             * key.  If it does then we do nothing feeding in the browser
-             * to the NoDupsCursor.  If it does not we call getPrevious and
-             * pass it into the NoDupsCursor constructor.
-             */
-            jdbm.helper.Tuple tuple = new jdbm.helper.Tuple();
-            TupleBrowser browser = bt.browse( key );
-
-            if ( browser.getNext( tuple ) )
-            {
-                Object greaterKey = tuple.getKey();
-
-                if ( 0 != comparator.compareKey( key, greaterKey ) )
-                {
-                    // Make sure we don't return greaterKey in cursor
-                    browser.getPrevious( tuple );
-                }
-            }
-
-            // If greaterKey != key above then it will not be returned.
-//            list = new NoDupsCursor( new JdbmTupleBrowser( browser ), isGreaterThan );
-            list = new NoDupsCursor( browserFactory, isGreaterThan );
-        }
-
-        if ( allowsDuplicates )
-        {
-            list = new DupsEnumeration( this, ( NoDupsEnumeration ) list );
-        }
-
-        return list;
-    }
-
-
-    /**
-     * @see org.apache.directory.server.core.partition.impl.btree.Table#listTuples(java.lang.Object,
-     * java.lang.Object, boolean)
-     */
-    @SuppressWarnings("unchecked")
-    public Cursor<Tuple> listTuples( Object key, Object val, boolean isGreaterThan ) throws IOException
-    {
-        if ( !allowsDuplicates )
-        {
-            throw new IllegalStateException( "Cannot list tuples over duplicates on table that " +
-                    "does not support duplicates." );
-        }
-
-        Object values = getRaw( key );
-        
-        if ( values == null )
-        {
-            return new EmptyCursor();
-        }
-
-        if ( values instanceof TreeSet )
-        {
-            TreeSet set = ( TreeSet ) values;
-    
-            if ( isGreaterThan )
-            {
-                Set tailSet = set.tailSet( val );
-                
-                if ( tailSet.isEmpty() )
-                {
-                    return new EmptyCursor();
-                }
-                
-                Object[] objs = new Object[tailSet.size()];
-                objs = tailSet.toArray( objs );
-                return new ValueArrayCursor( key, objs );
-            }
-            else
-            {
-                // Get all values from the smallest upto val and put them into
-                // a list.  They will be in ascending order so we need to reverse
-                // the list after adding val which is not included in headSet.
-                SortedSet headset = set.headSet( val );
-                List list = new ArrayList( headset.size() + 1 );
-                list.addAll( headset );
-    
-                // Add largest value (val) if it is in the set.  TreeSet.headSet
-                // does not get val if val is in the set.  So we add it now to
-                // the end of the list.  List is now ascending from smallest to
-                // val
-                if ( set.contains( val ) )
-                {
-                    list.add( val );
-                }
-    
-                // Reverse the list now we have descending values from val to the
-                // smallest value that key has.  Return tuple cursor over list.
-                Collections.reverse( list );
-                return new ValueArrayCursor( key, list );
-            }
-        }
-        
-        if ( values instanceof BTreeRedirect )
-        {
-//            return new BTreeTupleEnumeration( getBTree( ( BTreeRedirect ) values ),
-//                comparator.getValueComparator(), key, val, isGreaterThan );
-            JdbmTupleBrowserFactory factory = new JdbmTupleBrowserFactory( getBTree( ( BTreeRedirect ) values ) );
-            Cursor<Tuple> cursor = new TupleCursor( factory, key, comparator.getValueComparator() );
-            if ( isGreaterThan )
-            {
-                cursor.after( new Tuple( key, val ) );
-            }
-            else
-            {
-                cursor.before( new Tuple( key, val ) );
-            }
-            return cursor;
-        }
-
-        throw new IllegalStateException( "When using duplicate keys either a TreeSet or BTree is used for values." );
-    }
-    
-
     // ------------------------------------------------------------------------
     // Maintenance Operations 
     // ------------------------------------------------------------------------
@@ -1233,53 +978,30 @@
 
 
     /**
-     * Renders a key using the renderer associated with this table.
-     *
-     * @param obj the key to render.
-     * @return the rendered String representation of obj
-     */
-    private String renderKey( Object obj )
-    {
-        StringBuffer buf = new StringBuffer();
-
-        buf.append( "\'" );
-        if ( null == renderer )
-        {
-            buf.append( obj.toString() );
-        }
-        else
-        {
-            buf.append( renderer.getKeyString( obj ) );
-        }
-
-        buf.append( "\'" );
-        return buf.toString();
-    }
-
-
-    /**
      * Gets a Tuple value from the btree.
      *
      * @param key the key of the Tuple to get the value of 
      * @return the raw value object from the btree
      * @throws IOException if there are any problems accessing the btree.
      */
-    private Object getRaw( Object key ) throws IOException
+    private V getRaw( K key ) throws IOException
     {
-        Object val;
+        V val;
 
         if ( null == key )
         {
             return null;
         }
 
-        if ( !allowsDuplicates )
+        if ( ! allowsDuplicates )
         {
-            val = bt.find( key );
+            //noinspection unchecked
+            val = ( V ) bt.find( key );
         }
         else
         {
-            val = bt.find( key );
+            //noinspection unchecked
+            val = ( V ) bt.find( key );
         }
 
         return val;
@@ -1287,35 +1009,13 @@
 
 
     /**
-     * @todo what's the reason for keeping this?
-     *
-     * Puts a Tuple into the btree.
+     * Returns the main BTree used by this table.
      *
-     * @param key the key of the Tuple to put
-     * @param value the value of the Tuple to put
-     * @param doReplace whether or not to replace the object if it exists
-     * @return the raw value object removed from the btree on replacement
-     * @throws IOException if there are any problems accessing the btree.
-     */
-    private Object putRaw( Object key, Object value, boolean doReplace ) throws IOException
-    {
-        return bt.insert( key, value, doReplace );
-    }
-
-
-    /**
-     * @todo what's the reason for keeping this?
-     *
-     * Removes a entry from the btree while wrapping any IOExceptions with a
-     * NamingException.
-     *
-     * @param key the key of the Tuple to remove
-     * @return the raw value object removed from the btree
-     * @throws IOException if there are any problems accessing the btree.
+     * @return the main JDBM BTree used by this table
      */
-    private Object removeRaw( Object key ) throws IOException
+    BTree getBTree()
     {
-        return bt.remove( key );
+        return bt;
     }
 
 
@@ -1332,14 +1032,15 @@
     }
 
 
-    private Object firstKey ( BTree tree ) throws IOException
+    private V firstKey ( BTree tree ) throws IOException
     {
         jdbm.helper.Tuple tuple = new jdbm.helper.Tuple();
         boolean success = tree.browse().getNext( tuple );
             
         if ( success )
         {
-            return tuple.getKey();
+            //noinspection unchecked
+            return ( V ) tuple.getKey();
         }
         else
         {
@@ -1348,7 +1049,7 @@
     }
 
     
-    private boolean btreeHas( BTree tree, Object key, boolean isGreaterThan ) throws IOException
+    private boolean btreeHas( BTree tree, V key, boolean isGreaterThan ) throws IOException
     {
         jdbm.helper.Tuple tuple = new jdbm.helper.Tuple();
         
@@ -1388,7 +1089,7 @@
     }
 
 
-    private boolean btreeHas( BTree tree, Object key ) throws IOException
+    private boolean btreeHas( BTree tree, V key ) throws IOException
     {
         jdbm.helper.Tuple tuple = new jdbm.helper.Tuple();
         
@@ -1406,14 +1107,14 @@
     }
 
     
-    private boolean insertDupIntoBTree( BTree tree, Object value ) throws IOException
+    private boolean insertDupIntoBTree( BTree tree, V value ) throws IOException
     {
         Object replaced = tree.insert( value, EMPTY_BYTES, true );
         return null == replaced;
     }
     
 
-    private boolean removeDupFromBTree( BTree tree, Object value ) throws IOException
+    private boolean removeDupFromBTree( BTree tree, V value ) throws IOException
     {
         Object removed = null;
         if ( tree.find( value ) != null )
@@ -1435,21 +1136,22 @@
     }
     
     
-    private Object removeAll( BTree tree ) throws IOException
+    private V removeAll( BTree tree ) throws IOException
     {
-        Object first = null;
+        V first = null;
         jdbm.helper.Tuple jdbmTuple = new jdbm.helper.Tuple();
         TupleBrowser browser = tree.browse();
+
         while( browser.getNext( jdbmTuple ) )
         {
             tree.remove( jdbmTuple.getKey() );
             if ( first == null )
             {
-                first = jdbmTuple.getKey();
+                //noinspection unchecked
+                first = ( V ) jdbmTuple.getKey();
             }
         }
 
         return first;
     }
-}
-
+}
\ No newline at end of file



Mime
View raw message