From f73b655466092169abac34833fb628fce1fcdebe Mon Sep 17 00:00:00 2001
From: jcduff <jcduff@localhost>
Date: Thu, 23 Oct 2008 14:04:24 +0000
Subject: [PATCH] The commit will bring the following features : - An updated version of the underlying database. BDB JE 3.3 is now used. - Attribute API refactoring providing a better abstraction and offering improved performances. - A new GUI called the Control-Panel to replace the Status-Panel: the specifications for this GUI are available on OpenDS Wiki and contains a link to a mockup. See <https://www.opends.org/wiki/page/ControlPanelUISpecification>. - Some changes in the replication protocol to implement "Assured Replication Mode". The specifications are on OpenDS Wiki at <https://www.opends.org/wiki/page/AssuredMode> and section 7 described some of the replication changes required to support this. Assured Replication is not finished, but the main replication protocol changes to support it are done. As explained by Gilles on an email on the Dev mailing list (http://markmail.org/message/46rgo3meq3vriy4a), with these changes the newer versions of OpenDS may not be able to replicate with OpenDS 1.0 instances. - Support for Service Tags on the platforms where the functionality is available and enabled. Specifications are published at <https://www.opends.org/wiki/page/OpenDSServiceTagEnabled>. For more information on Service Tags see <http://wikis.sun.com/display/ServiceTag/Sun+Service+Tag+FAQ>. - The Admin Connector service. In order to provide agentry of the OpenDS server at any time, a new service has been added, dedicated to the administration, configuration and monitoring of the server. An overview of the Admin Connector service and it's use is available on the OpenDS wiki <https://www.opends.org/wiki/page/ManagingAdministrationTrafficToTheServer> - Updates to the various command line tools to support the Admin Connector service. - Some internal re-architecting of the server to put the foundation of future developments such as virtual directory services. The new NetworkGroups and WorkFlow internal services which have been specified in <https://www.opends.org/wiki/page/BasicOperationRoutingThroughNetworkGroup> are now implemented. - Many bug fixes...
---
opends/src/server/org/opends/server/replication/plugin/AttrInfoMultiple.java | 237 +++++++++++++++++++++++++++++++----------------------------
1 files changed, 125 insertions(+), 112 deletions(-)
diff --git a/opends/src/server/org/opends/server/replication/plugin/AttrInfoMultiple.java b/opends/src/server/org/opends/server/replication/plugin/AttrInfoMultiple.java
index 813aeb7..a65d036 100644
--- a/opends/src/server/org/opends/server/replication/plugin/AttrInfoMultiple.java
+++ b/opends/src/server/org/opends/server/replication/plugin/AttrInfoMultiple.java
@@ -28,11 +28,10 @@
import java.util.ArrayList;
import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.Set;
import org.opends.server.replication.common.ChangeNumber;
import org.opends.server.types.Attribute;
+import org.opends.server.types.AttributeBuilder;
import org.opends.server.types.AttributeType;
import org.opends.server.types.AttributeValue;
import org.opends.server.types.Entry;
@@ -129,7 +128,8 @@
while (it.hasNext())
{
ValueInfo info = it.next();
- if (CN.newerOrEquals(info.getValueUpdateTime()))
+ if (CN.newerOrEquals(info.getValueUpdateTime()) &&
+ CN.newerOrEquals(info.getValueDeleteTime()))
it.remove();
}
@@ -161,31 +161,37 @@
}
/**
- * Change historical information after a delete of a set of values.
- *
- * @param values values that were deleted
- * @param CN time when the delete was done
- */
- protected void delete(LinkedHashSet<AttributeValue> values, ChangeNumber CN)
- {
- for (AttributeValue val : values)
- {
- ValueInfo info = new ValueInfo(val, null, CN);
- this.valuesInfo.remove(info);
- this.valuesInfo.add(info);
- if (CN.newer(lastUpdateTime))
- {
- lastUpdateTime = CN;
- }
- }
- }
+ * Change historical information after a delete of a set of
+ * values.
+ *
+ * @param attr
+ * the attribute containing the set of values that were
+ * deleted
+ * @param CN
+ * time when the delete was done
+ */
+ protected void delete(Attribute attr, ChangeNumber CN)
+ {
+ for (AttributeValue val : attr)
+ {
+ ValueInfo info = new ValueInfo(val, null, CN);
+ this.valuesInfo.remove(info);
+ this.valuesInfo.add(info);
+ if (CN.newer(lastUpdateTime))
+ {
+ lastUpdateTime = CN;
+ }
+ }
+ }
/**
- * Update the historical information when a value is added.
- *
- * @param val values that was added
- * @param CN time when the value was added
- */
+ * Update the historical information when a value is added.
+ *
+ * @param val
+ * values that was added
+ * @param CN
+ * time when the value was added
+ */
protected void add(AttributeValue val, ChangeNumber CN)
{
ValueInfo info = new ValueInfo(val, CN, null);
@@ -198,25 +204,26 @@
}
/**
- * Update the historical information when values are added.
- *
- * @param values the set of added values
- * @param CN time when the add is done
- */
- private void add(LinkedHashSet<AttributeValue> values,
- ChangeNumber CN)
- {
- for (AttributeValue val : values)
- {
- ValueInfo info = new ValueInfo(val, CN, null);
- this.valuesInfo.remove(info);
- valuesInfo.add(info);
- if (CN.newer(lastUpdateTime))
- {
- lastUpdateTime = CN;
- }
- }
- }
+ * Update the historical information when values are added.
+ *
+ * @param attr
+ * the attribute containing the set of added values
+ * @param CN
+ * time when the add is done
+ */
+ private void add(Attribute attr, ChangeNumber CN)
+ {
+ for (AttributeValue val : attr)
+ {
+ ValueInfo info = new ValueInfo(val, CN, null);
+ this.valuesInfo.remove(info);
+ valuesInfo.add(info);
+ if (CN.newer(lastUpdateTime))
+ {
+ lastUpdateTime = CN;
+ }
+ }
+ }
/**
* Get the List of ValueInfo for this attribute Info.
@@ -240,10 +247,8 @@
// conflict
// with some more recent operations on this same entry
// we need to take the more complex path to solve them
- Attribute modAttr = m.getAttribute();
- AttributeType type = modAttr.getAttributeType();
-
- if (ChangeNumber.compare(changeNumber, getLastUpdateTime()) <= 0)
+ if ((ChangeNumber.compare(changeNumber, getLastUpdateTime()) <= 0) ||
+ (m.getModificationType() != ModificationType.REPLACE))
{
// the attribute was modified after this change -> conflict
@@ -259,12 +264,14 @@
break;
}
- conflictDelete(changeNumber, type, m, modifiedEntry, modAttr);
+ if (!conflictDelete(changeNumber, m, modifiedEntry))
+ {
+ modsIterator.remove();
+ }
break;
case ADD:
- conflictAdd(modsIterator, changeNumber,
- modAttr.getValues(), modAttr.getOptions());
+ conflictAdd(changeNumber, m, modsIterator);
break;
case REPLACE:
@@ -276,6 +283,7 @@
modsIterator.remove();
break;
}
+
/* save the values that are added by the replace operation
* into addedValues
* first process the replace as a delete operation -> this generate
@@ -284,15 +292,18 @@
* -> this generate the list of values that needs to be added
* concatenate the 2 generated lists into a replace
*/
- LinkedHashSet<AttributeValue> addedValues = modAttr.getValues();
- modAttr.setValues(new LinkedHashSet<AttributeValue>());
+ Attribute addedValues = m.getAttribute();
+ m.setAttribute(new AttributeBuilder(addedValues, true).toAttribute());
- this.conflictDelete(changeNumber, type, m, modifiedEntry, modAttr);
+ conflictDelete(changeNumber, m, modifiedEntry);
+ Attribute keptValues = m.getAttribute();
- LinkedHashSet<AttributeValue> keptValues = modAttr.getValues();
- this.conflictAdd(modsIterator, changeNumber, addedValues,
- modAttr.getOptions());
- keptValues.addAll(addedValues);
+ m.setAttribute(addedValues);
+ conflictAdd(changeNumber, m, modsIterator);
+
+ AttributeBuilder builder = new AttributeBuilder(keptValues);
+ builder.addAll(m.getAttribute());
+ m.setAttribute(builder.toAttribute());
break;
case INCREMENT:
@@ -339,13 +350,13 @@
switch (mod.getModificationType())
{
case DELETE:
- if (modAttr.getValues().isEmpty())
+ if (modAttr.isEmpty())
{
delete(changeNumber);
}
else
{
- delete(modAttr.getValues(), changeNumber);
+ delete(modAttr, changeNumber);
}
break;
@@ -354,13 +365,13 @@
{
delete(changeNumber);
}
- add(modAttr.getValues(), changeNumber);
+ add(modAttr, changeNumber);
break;
case REPLACE:
/* TODO : can we replace specific attribute values ????? */
delete(changeNumber);
- add(modAttr.getValues(), changeNumber);
+ add(modAttr, changeNumber);
break;
case INCREMENT:
@@ -374,21 +385,13 @@
* modification.
*
* @param changeNumber The changeNumber of the currently processed change
- * @param type attribute type
* @param m the modification that is being processed
* @param modifiedEntry the entry that is modified (before current mod)
- * @param attrInfo the historical info associated to the entry
- * @param modAttr the attribute modification
* @return false if there is nothing to do
*/
- private boolean conflictDelete(ChangeNumber changeNumber,
- AttributeType type, Modification m,
- Entry modifiedEntry,
- Attribute modAttr )
+ private boolean conflictDelete(ChangeNumber changeNumber, Modification m,
+ Entry modifiedEntry)
{
- LinkedHashSet<AttributeValue> delValues;
- LinkedHashSet<AttributeValue> replValues;
-
/*
* We are processing a conflicting DELETE modification
*
@@ -405,21 +408,18 @@
* it must be removed so we simply ignore them
*/
-
-
- delValues = modAttr.getValues();
- if ((delValues == null) || (delValues.isEmpty()))
+ Attribute modAttr = m.getAttribute();
+ if (modAttr.isEmpty())
{
/*
* We are processing a DELETE attribute modification
*/
m.setModificationType(ModificationType.REPLACE);
- replValues = new LinkedHashSet<AttributeValue>();
+ AttributeBuilder builder = new AttributeBuilder(modAttr, true);
- for (Iterator it = getValuesInfo().iterator();
- it.hasNext();)
+ for (Iterator<ValueInfo> it = getValuesInfo().iterator(); it.hasNext();)
{
- ValueInfo valInfo; valInfo = (ValueInfo) it.next();
+ ValueInfo valInfo; valInfo = it.next();
if (changeNumber.older(valInfo.getValueUpdateTime()))
{
@@ -427,7 +427,7 @@
* this value has been updated after this delete, therefore
* this value must be kept
*/
- replValues.add(valInfo.getValue());
+ builder.add(valInfo.getValue());
}
else
{
@@ -443,7 +443,8 @@
}
}
- modAttr.setValues(replValues);
+ m.setAttribute(builder.toAttribute());
+
if (changeNumber.newer(getDeleteTime()))
{
deleteTime = changeNumber;
@@ -459,11 +460,10 @@
* we are processing DELETE of some attribute values
*/
ArrayList<ValueInfo> valuesInfo = getValuesInfo();
+ AttributeBuilder builder = new AttributeBuilder(modAttr);
- for (Iterator<AttributeValue> delValIterator = delValues.iterator();
- delValIterator.hasNext();)
+ for (AttributeValue val : modAttr)
{
- AttributeValue val = delValIterator.next();
Boolean deleteIt = true; // true if the delete must be done
/* update historical information */
@@ -488,22 +488,35 @@
{
valuesInfo.add(valInfo);
}
+
/* if the attribute value is not to be deleted
* or if attribute value is not present suppress it from the
- * mod to make sure the delete is going to process again
+ * MOD to make sure the delete is going to succeed
*/
- modifiedEntry.getAttribute(type);
if (!deleteIt
- || !modifiedEntry.hasValue(type, modAttr.getOptions(), val))
+ || !modifiedEntry.hasValue(modAttr.getAttributeType(), modAttr
+ .getOptions(), val))
{
- delValIterator.remove();
+ // this value was already deleted before and therefore
+ // this should not be replayed.
+ builder.remove(val);
+ if (builder.isEmpty())
+ {
+ // This was the last values in the set of values to be deleted.
+ // this MOD must therefore be skipped.
+ return false;
+ }
}
}
+
+ m.setAttribute(builder.toAttribute());
+
if (changeNumber.newer(getLastUpdateTime()))
{
lastUpdateTime = changeNumber;
}
}
+
return true;
}
@@ -511,26 +524,22 @@
* Process a add attribute values that is conflicting with a previous
* modification.
*
- * @param modsIterator iterator on the list of modification
* @param changeNumber the historical info associated to the entry
- * @param addValues the values that are added
- * @param options the options that are added
+ * @param m the modification that is being processed
+ * @param modsIterator iterator on the list of modification
* @return false if operation becomes empty and must not be processed
*/
- private boolean conflictAdd(Iterator modsIterator, ChangeNumber changeNumber,
- LinkedHashSet<AttributeValue> addValues,
- Set<String> options)
+ private boolean conflictAdd(ChangeNumber changeNumber, Modification m,
+ Iterator<Modification> modsIterator)
{
- /* if historicalattributedelete is newer forget this mod
- * else find attr value
- * if does not exist
- * add historicalvalueadded timestamp
- * add real value in entry
- * else if timestamp older and already was historicalvalueadded
- * update historicalvalueadded
- * else if timestamp older and was historicalvaluedeleted
- * change historicalvaluedeleted into historicalvalueadded
- * add value in real entry
+ /*
+ * if historicalattributedelete is newer forget this mod else find
+ * attr value if does not exist add historicalvalueadded timestamp
+ * add real value in entry else if timestamp older and already was
+ * historicalvalueadded update historicalvalueadded else if
+ * timestamp older and was historicalvaluedeleted change
+ * historicalvaluedeleted into historicalvalueadded add value in
+ * real entry
*/
if (changeNumber.older(getDeleteTime()))
@@ -542,10 +551,9 @@
return false;
}
- for (Iterator<AttributeValue> valIterator = addValues.iterator();
- valIterator.hasNext();)
+ AttributeBuilder builder = new AttributeBuilder(m.getAttribute());
+ for (AttributeValue addVal : m.getAttribute())
{
- AttributeValue addVal= valIterator.next();
ArrayList<ValueInfo> valuesInfo = getValuesInfo();
ValueInfo valInfo = new ValueInfo(addVal, changeNumber, null);
int index = valuesInfo.indexOf(valInfo);
@@ -572,7 +580,7 @@
valuesInfo.remove(index);
valuesInfo.add(valInfo);
}
- valIterator.remove();
+ builder.remove(addVal);
}
else
{
@@ -596,12 +604,16 @@
* remove this value from the list of values to add
* don't update the historical information
*/
- valIterator.remove();
+ builder.remove(addVal);
}
}
}
}
- if (addValues.isEmpty())
+
+ Attribute attr = builder.toAttribute();
+ m.setAttribute(attr);
+
+ if (attr.isEmpty())
{
modsIterator.remove();
}
@@ -610,6 +622,7 @@
{
lastUpdateTime = changeNumber;
}
+
return true;
}
--
Gitblit v1.10.0