From e25d897908d93ab4f9cabadb1029ad3352602d5d Mon Sep 17 00:00:00 2001
From: boli <boli@localhost>
Date: Wed, 31 Oct 2007 22:19:14 +0000
Subject: [PATCH] This set of fixes mainly address the issues where the JE backend does not handle attributes with options and subtypes correctly when they are being indexed.  With this fix: - All values of an indexed attribute type will be indexed correctly on modifies, adds, and deletes.  - Updates to subordinate types will now update the superior type if its indexed.  - Adding and deleting superior attribute types that are not allowed by any object classes (ie. name) will be correctly handled - Deleting all values from an attribute with no options will no longer delete the values from the same attribute but with options.  

---
 opends/src/server/org/opends/server/backends/jeb/EqualityIndexer.java |  159 ++++++++++------------------------------------------
 1 files changed, 31 insertions(+), 128 deletions(-)

diff --git a/opends/src/server/org/opends/server/backends/jeb/EqualityIndexer.java b/opends/src/server/org/opends/server/backends/jeb/EqualityIndexer.java
index 83f2079..e684c0a 100644
--- a/opends/src/server/org/opends/server/backends/jeb/EqualityIndexer.java
+++ b/opends/src/server/org/opends/server/backends/jeb/EqualityIndexer.java
@@ -45,7 +45,6 @@
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
-import java.util.ArrayList;
 
 /**
  * An implementation of an Indexer for attribute equality.
@@ -191,140 +190,44 @@
                           Set<ASN1OctetString> delKeys)
        throws DatabaseException
   {
-    // Optimize for the case where there are no attribute options
-    // involved and only simple addition and deletion of individual values.
-    // An issue with attribute options is that the values can not be assumed
-    // to be unique.
+    List<Attribute> newAttributes = newEntry.getAttribute(attributeType, true);
+    List<Attribute> oldAttributes = oldEntry.getAttribute(attributeType, true);
+    HashSet<AttributeValue> newValues;
+    HashSet<AttributeValue> oldValues;
 
-    List<Attribute> beforeList;
-    List<Attribute> afterList;
-    beforeList = oldEntry.getAttribute(attributeType);
-    afterList = newEntry.getAttribute(attributeType);
-
-    boolean hasOptions = false;
-
-    if (beforeList != null)
+    if(newAttributes == null)
     {
-      for (Attribute a : beforeList)
-      {
-        if (a.hasOptions())
-        {
-          hasOptions = true;
-          break;
-        }
-      }
-    }
-
-    if (afterList != null)
-    {
-      for (Attribute a : afterList)
-      {
-        if (a.hasOptions())
-        {
-          hasOptions = true;
-          break;
-        }
-      }
-    }
-
-    boolean hasOnlySimpleMods = true;
-    List<Modification> simpleMods = new ArrayList<Modification>();
-    for (Modification mod : mods)
-    {
-      Attribute modAttr = mod.getAttribute();
-      AttributeType modAttrType = modAttr.getAttributeType();
-      if (modAttrType.equals(attributeType))
-      {
-        if (modAttr.hasOptions())
-        {
-          hasOptions = true;
-        }
-        switch (mod.getModificationType())
-        {
-          case ADD:
-            simpleMods.add(mod);
-            break;
-
-          case DELETE:
-            if (!modAttr.hasValue())
-            {
-              hasOnlySimpleMods = false;
-            }
-            else
-            {
-              simpleMods.add(mod);
-            }
-            break;
-
-          default:
-            hasOnlySimpleMods = false;
-            break;
-        }
-      }
-    }
-
-    if (hasOnlySimpleMods && !hasOptions)
-    {
-      // This is the optimized case where there are no attribute options
-      // involved and only simple addition and deletion of individual values.
-      // It should be efficient for adding and/or deleting a few values of an
-      // attribute with lots of values.
-      for (Modification mod : simpleMods)
-      {
-        Set<AttributeValue> values = mod.getAttribute().getValues();
-        Set<ASN1OctetString> keys =
-             new HashSet<ASN1OctetString>(values.size());
-        indexValues(values, keys);
-
-        switch (mod.getModificationType())
-        {
-          case ADD:
-            for (ASN1OctetString key : keys)
-            {
-              if (delKeys.contains(key))
-              {
-                delKeys.remove(key);
-              }
-              else
-              {
-                addKeys.add(key);
-              }
-            }
-            break;
-
-          case DELETE:
-            for (ASN1OctetString key : keys)
-            {
-              if (addKeys.contains(key))
-              {
-                addKeys.remove(key);
-              }
-              else
-              {
-                delKeys.add(key);
-              }
-            }
-            break;
-        }
-      }
+      indexAttribute(oldAttributes, delKeys);
     }
     else
     {
-      // This is the non-optimized case that should be correct in all cases.
+      if(oldAttributes == null)
+      {
+        indexAttribute(newAttributes, addKeys);
+      }
+      else
+      {
+        newValues = new HashSet<AttributeValue>();
+        oldValues = new HashSet<AttributeValue>();
+        for(Attribute a : newAttributes)
+        {
+          newValues.addAll(a.getValues());
+        }
+        for(Attribute a : oldAttributes)
+        {
+          oldValues.addAll(a.getValues());
+        }
 
-      Set<ASN1OctetString> oldSet = new HashSet<ASN1OctetString>();
-      indexAttribute(beforeList, oldSet);
+        HashSet<AttributeValue> valuesToAdd =
+            new HashSet<AttributeValue>(newValues);
+        HashSet<AttributeValue> valuesToDel =
+            new HashSet<AttributeValue>(oldValues);
+        valuesToAdd.removeAll(oldValues);
+        valuesToDel.removeAll(newValues);
 
-      Set<ASN1OctetString> newSet = new HashSet<ASN1OctetString>();
-      indexAttribute(afterList, newSet);
-
-      HashSet<ASN1OctetString> removeSet = new HashSet<ASN1OctetString>(oldSet);
-      removeSet.removeAll(newSet);
-      delKeys.addAll(removeSet);
-
-      HashSet<ASN1OctetString> addSet = new HashSet<ASN1OctetString>(newSet);
-      addSet.removeAll(oldSet);
-      addKeys.addAll(addSet);
+        indexValues(valuesToDel, delKeys);
+        indexValues(valuesToAdd, addKeys);
+      }
     }
   }
 

--
Gitblit v1.10.0