From 325b2ee4a27d0c24aa0a539f7bd0a8cf24905ff7 Mon Sep 17 00:00:00 2001
From: boli <boli@localhost>
Date: Tue, 10 Apr 2007 20:41:27 +0000
Subject: [PATCH] Added the following capabilities to OpenDS: - Index rebuilding capabilities. All indexes including system and attribute indexes can  be rebuilt. Each index will be rebuilt by a seperate thread to increase performance. A  max number of rebuild threads could be set to limit the resources used by large rebuild  jobs. Partial rebuilds of attribute indexes could also be done by specifying the  attribute index type after the attribute type (ie. sn.approximate). - Index rebuilding standalone tool. Rebuilding of attribute indexes could be done with  the backend online. However, rebuilds including system indexes must be done with the  backend offline. - Index rebuilding task. Rebuilding of attribute indexes are done with the backend  online. Rebuilds that include system indexes will be performed after bring the backend  offline. The user must have index-rebuild privilages to rebuild indexes. - Approxitae indexing capability. The value of the attribute will be normalized using  the approximate maching rule of that attribute type. This is used as the key for the  index. Approximate indexes are fully supported by the index verify, rebuild, and import  jobs. - Fixed bug in build.xml where weave is enabled even if a test.* property is set. - Consolidated some common tool messages. - Consolidated some JE backend methods common to all tools. - Added unit tests for rebuild job and approximate indexes.

---
 opends/src/server/org/opends/server/backends/jeb/AttributeIndex.java |  163 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 158 insertions(+), 5 deletions(-)

diff --git a/opends/src/server/org/opends/server/backends/jeb/AttributeIndex.java b/opends/src/server/org/opends/server/backends/jeb/AttributeIndex.java
index 2ec9bfb..53515d7 100644
--- a/opends/src/server/org/opends/server/backends/jeb/AttributeIndex.java
+++ b/opends/src/server/org/opends/server/backends/jeb/AttributeIndex.java
@@ -40,6 +40,7 @@
 
 import org.opends.server.api.SubstringMatchingRule;
 import org.opends.server.api.OrderingMatchingRule;
+import org.opends.server.api.ApproximateMatchingRule;
 import org.opends.server.protocols.asn1.ASN1OctetString;
 import org.opends.server.types.AttributeType;
 import org.opends.server.types.AttributeValue;
@@ -106,6 +107,11 @@
   Index orderingIndex = null;
 
   /**
+   * The index database for attribute approximate.
+   */
+  Index approximateIndex = null;
+
+  /**
    * Create a new attribute index object.
    * @param entryContainer The entryContainer of this attribute index.
    * @param indexConfig The attribute index configuration.
@@ -153,6 +159,15 @@
                                      indexConfig.getEqualityEntryLimit(),
                                      indexConfig.getCursorEntryLimit());
     }
+    if (indexConfig.isApproximateIndex())
+    {
+      Indexer approximateIndexer = new ApproximateIndexer(indexConfig);
+      this.approximateIndex = new Index(this.entryContainer,
+                                        name + ".approximate",
+                                        approximateIndexer,
+                                        indexConfig.getEqualityEntryLimit(),
+                                        indexConfig.getCursorEntryLimit());
+    }
   }
 
   /**
@@ -185,6 +200,11 @@
     {
       orderingIndex.open(dbConfig);
     }
+
+    if (approximateIndex != null)
+    {
+      approximateIndex.open(dbConfig);
+    }
   }
 
   /**
@@ -204,38 +224,65 @@
     return indexConfig.getAttributeType();
   }
 
+  //TODO: Make all modify/add methods return success boolean
   /**
    * Update the attribute index for a new entry.
    *
    * @param txn         The database transaction to be used for the insertions.
    * @param entryID     The entry ID.
    * @param entry       The contents of the new entry.
+   * @return True if all the index keys for the entry are added. False if the
+   *         entry ID alreadly exists for some keys.
    * @throws DatabaseException If an error occurs in the JE database.
    * @throws DirectoryException If a Directory Server error occurs.
    * @throws JebException If an error occurs in the JE backend.
    */
-  public void addEntry(Transaction txn, EntryID entryID, Entry entry)
+  public boolean addEntry(Transaction txn, EntryID entryID, Entry entry)
        throws DatabaseException, DirectoryException, JebException
   {
+    boolean success = true;
+
     if (equalityIndex != null)
     {
-      equalityIndex.addEntry(txn, entryID, entry);
+      if(!equalityIndex.addEntry(txn, entryID, entry))
+      {
+        success = false;
+      }
     }
 
     if (presenceIndex != null)
     {
-      presenceIndex.addEntry(txn, entryID, entry);
+      if(!presenceIndex.addEntry(txn, entryID, entry))
+      {
+        success = false;
+      }
     }
 
     if (substringIndex != null)
     {
-      substringIndex.addEntry(txn, entryID, entry);
+      if(!substringIndex.addEntry(txn, entryID, entry))
+      {
+        success = false;
+      }
     }
 
     if (orderingIndex != null)
     {
-      orderingIndex.addEntry(txn, entryID, entry);
+      if(!orderingIndex.addEntry(txn, entryID, entry))
+      {
+        success = false;
+      }
     }
+
+    if (approximateIndex != null)
+    {
+      if(!approximateIndex.addEntry(txn, entryID, entry))
+      {
+        success = false;
+      }
+    }
+
+    return success;
   }
 
   /**
@@ -270,6 +317,11 @@
     {
       orderingIndex.removeEntry(txn, entryID, entry);
     }
+
+    if(approximateIndex != null)
+    {
+      approximateIndex.removeEntry(txn, entryID, entry);
+    }
   }
 
   /**
@@ -310,6 +362,11 @@
     {
       orderingIndex.modifyEntry(txn, entryID, oldEntry, newEntry, mods);
     }
+
+    if (approximateIndex != null)
+    {
+      approximateIndex.modifyEntry(txn, entryID, oldEntry, newEntry, mods);
+    }
   }
 
   /**
@@ -794,6 +851,44 @@
   }
 
   /**
+   * Retrieve the entry IDs that might match an approximate filter.
+   *
+   * @param approximateFilter The approximate filter.
+   * @return The candidate entry IDs that might contain the filter
+   *         assertion value.
+   */
+  public EntryIDSet evaluateApproximateFilter(SearchFilter approximateFilter)
+  {
+    if (!indexConfig.isApproximateIndex())
+    {
+      return new EntryIDSet();
+    }
+
+    try
+    {
+      ApproximateMatchingRule approximateMatchingRule =
+          approximateFilter.getAttributeType().getApproximateMatchingRule();
+      // Make a key from the normalized assertion value.
+      byte[] keyBytes =
+           approximateMatchingRule.normalizeValue(
+               approximateFilter.getAssertionValue().getValue()).value();
+      DatabaseEntry key = new DatabaseEntry(keyBytes);
+
+      // Read the key.
+      return approximateIndex.readKey(key, null, LockMode.DEFAULT);
+    }
+    catch (DirectoryException e)
+    {
+      if (debugEnabled())
+      {
+        debugCaught(DebugLogLevel.ERROR, e);
+      }
+      return new EntryIDSet();
+    }
+  }
+
+
+  /**
    * Remove the index from disk. The index must not be open.
    * @throws DatabaseException If an error occurs in the JE database.
    */
@@ -817,6 +912,10 @@
     {
       entryContainer.removeDatabase(name + ".ordering");
     }
+    if (indexConfig.isApproximateIndex())
+    {
+      entryContainer.removeDatabase(name + ".approximate");
+    }
   }
 
   /**
@@ -849,6 +948,60 @@
       entryLimitExceededCount += orderingIndex.getEntryLimitExceededCount();
     }
 
+    if (approximateIndex != null)
+    {
+      entryLimitExceededCount +=
+          approximateIndex.getEntryLimitExceededCount();
+    }
+
     return entryLimitExceededCount;
   }
+
+  /**
+   * Removes all records related to this attribute index.
+   * @param txn A JE database transaction to be used during the clear operation
+   *            or null if not required. Using transactions increases the chance
+   *            of lock contention.
+   * @return The number of records removed.
+   * @throws DatabaseException If an error occurs while cleaning the database.
+   */
+  public long clear(Transaction txn) throws DatabaseException
+  {
+    long deletedCount = 0;
+
+    if (equalityIndex != null)
+    {
+      deletedCount += equalityIndex.clear(txn);
+    }
+    if (presenceIndex != null)
+    {
+      deletedCount += presenceIndex.clear(txn);
+    }
+    if (substringIndex != null)
+    {
+      deletedCount += substringIndex.clear(txn);
+    }
+    if (orderingIndex != null)
+    {
+      deletedCount += orderingIndex.clear(txn);
+    }
+    if (approximateIndex != null)
+    {
+      deletedCount += approximateIndex.clear(txn);
+    }
+
+    return deletedCount;
+  }
+
+
+  /**
+   * Get a string representation of this object.
+   * @return return A string representation of this object.
+   */
+  public String toString()
+  {
+    return indexConfig.getAttributeType().getNameOrOID();
+  }
+
+
 }

--
Gitblit v1.10.0