From 15d537d27c0116138191b0a60ac03b54eb00d4e5 Mon Sep 17 00:00:00 2001
From: coulbeck <coulbeck@localhost>
Date: Wed, 07 Feb 2007 16:51:16 +0000
Subject: [PATCH] An extra synchronization unit test and a number of bug fixes for attributes with options.
---
opends/src/server/org/opends/server/synchronization/plugin/Historical.java | 193 +++++++++++++++++++++++++++++++++--------------
1 files changed, 134 insertions(+), 59 deletions(-)
diff --git a/opends/src/server/org/opends/server/synchronization/plugin/Historical.java b/opends/src/server/org/opends/server/synchronization/plugin/Historical.java
index fe95ffa..1831ef3 100644
--- a/opends/src/server/org/opends/server/synchronization/plugin/Historical.java
+++ b/opends/src/server/org/opends/server/synchronization/plugin/Historical.java
@@ -96,6 +96,17 @@
= new HashMap<AttributeType,AttrInfoWithOptions>();
/**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString()
+ {
+ StringBuilder builder = new StringBuilder();
+ builder.append(encode());
+ return builder.toString();
+ }
+
+ /**
* Duplicates an Historical Object.
* attributesInfo are nor duplicated but used as references.
* @return The duplicate of the Historical Object
@@ -131,12 +142,16 @@
Attribute modAttr = m.getAttribute();
Set<String> options = modAttr.getOptions();
if (options.isEmpty())
+ {
options = null;
+ }
AttributeType type = modAttr.getAttributeType();
AttrInfoWithOptions attrInfoWithOptions = attributesInfo.get(type);
AttrInfo attrInfo = null;
if (attrInfoWithOptions != null)
+ {
attrInfo = attrInfoWithOptions.get(options);
+ }
if (this.hasConflict(attrInfo, changeNumber))
{
@@ -148,68 +163,72 @@
switch (m.getModificationType())
{
- case DELETE:
- if (changeNumber.older(attrInfo.getDeleteTime()))
- {
- /* this delete is already obsoleted by a more recent delete
- * skip this mod
- */
- modsIterator.remove();
+ case DELETE:
+ if (changeNumber.older(attrInfo.getDeleteTime()))
+ {
+ /* this delete is already obsoleted by a more recent delete
+ * skip this mod
+ */
+ modsIterator.remove();
+ break;
+ }
+
+ this.conflictDelete(changeNumber,
+ type, m, modifiedEntry, attrInfo, modAttr);
break;
- }
- this.conflictDelete(changeNumber,
- type, m, modifiedEntry, attrInfo, modAttr);
- break;
-
- case ADD:
- this.conflictAdd(modsIterator, changeNumber, attrInfo,
- modAttr.getValues(), modAttr.getOptions());
- break;
-
- case REPLACE:
- if (changeNumber.older(attrInfo.getDeleteTime()))
- {
- /* this replace is already obsoleted by a more recent delete
- * skip this mod
- */
- modsIterator.remove();
+ case ADD:
+ this.conflictAdd(modsIterator, changeNumber, attrInfo,
+ modAttr.getValues(), modAttr.getOptions());
break;
- }
- /* save the values that are added by the replace operation
- * into addedValues
- * first process the replace as a delete operation -> this generate
- * a list of values that should be kept
- * then process the addedValues as if they were coming from a add
- * -> 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>());
- this.conflictDelete(changeNumber, type, m, modifiedEntry,
- attrInfo, modAttr);
+ case REPLACE:
+ if (changeNumber.older(attrInfo.getDeleteTime()))
+ {
+ /* this replace is already obsoleted by a more recent delete
+ * skip this mod
+ */
+ 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
+ * a list of values that should be kept
+ * then process the addedValues as if they were coming from a add
+ * -> 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>());
- LinkedHashSet<AttributeValue> keptValues = modAttr.getValues();
- this.conflictAdd(modsIterator, changeNumber, attrInfo, addedValues,
- modAttr.getOptions());
- keptValues.addAll(addedValues);
- break;
+ this.conflictDelete(changeNumber, type, m, modifiedEntry,
+ attrInfo, modAttr);
- case INCREMENT:
- // TODO : FILL ME
- break;
+ LinkedHashSet<AttributeValue> keptValues = modAttr.getValues();
+ this.conflictAdd(modsIterator, changeNumber, attrInfo, addedValues,
+ modAttr.getOptions());
+ keptValues.addAll(addedValues);
+ break;
+
+ case INCREMENT:
+ // TODO : FILL ME
+ break;
}
}
else
+ {
processLocalOrNonConflictModification(changeNumber, m);
+ }
}
// TODO : now purge old historical information
if (moreRecentChangenumber == null ||
- moreRecentChangenumber.older(changeNumber))
+ moreRecentChangenumber.older(changeNumber))
+ {
moreRecentChangenumber = changeNumber;
+ }
}
/**
@@ -240,17 +259,25 @@
Attribute modAttr = mod.getAttribute();
if (modAttr.getAttributeType().equals(historicalAttrType))
+ {
return;
+ }
Set<String> options = modAttr.getOptions();
if (options.isEmpty())
+ {
options = null;
+ }
AttributeType type = modAttr.getAttributeType();
AttrInfoWithOptions attrInfoWithOptions = attributesInfo.get(type);
AttrInfo attrInfo;
if (attrInfoWithOptions != null)
+ {
attrInfo = attrInfoWithOptions.get(options);
+ }
else
+ {
attrInfo = null;
+ }
/*
* The following code only works for multi-valued attributes.
@@ -260,7 +287,9 @@
{
attrInfo = new AttrInfo();
if (attrInfoWithOptions == null)
+ {
attrInfoWithOptions = new AttrInfoWithOptions();
+ }
attrInfoWithOptions.put(options, attrInfo);
attributesInfo.put(type, attrInfoWithOptions);
}
@@ -268,9 +297,13 @@
{
case DELETE:
if (modAttr.getValues().isEmpty())
+ {
attrInfo.delete(changeNumber);
+ }
else
+ {
attrInfo.delete(modAttr.getValues(), changeNumber);
+ }
break;
case ADD:
@@ -319,10 +352,26 @@
processLocalOrNonConflictModification(changeNumber, mod);
}
if (moreRecentChangenumber == null ||
- moreRecentChangenumber.older(changeNumber))
+ moreRecentChangenumber.older(changeNumber))
+ {
moreRecentChangenumber = changeNumber;
+ }
}
+ Attribute attr = encode();
+ Modification mod;
+ mod = new Modification(ModificationType.REPLACE, attr);
+ mods.add(mod);
+ modifiedEntry.removeAttribute(historicalAttrType);
+ modifiedEntry.addAttribute(attr, null);
+ }
+
+ /**
+ * Encode the historical information in an operational attribute.
+ * @return The historical information encoded in an operational attribute.
+ */
+ public Attribute encode()
+ {
LinkedHashSet<AttributeValue> hist = new LinkedHashSet<AttributeValue>();
for (Map.Entry<AttributeType, AttrInfoWithOptions> entryWithOptions :
@@ -330,7 +379,7 @@
{
AttributeType type = entryWithOptions.getKey();
- HashMap<Set<String> ,AttrInfo> attrwithoptions =
+ HashMap<Set<String> , AttrInfo> attrwithoptions =
entryWithOptions.getValue().getAttributesInfo();
for (Map.Entry<Set<String>, AttrInfo> entry : attrwithoptions.entrySet())
@@ -342,8 +391,15 @@
ChangeNumber deleteTime = info.getDeleteTime();
if (options != null)
+ {
+ StringBuilder optionsBuilder = new StringBuilder();
for (String s : options)
- optionsString.concat(";"+s);
+ {
+ optionsBuilder.append(';');
+ optionsBuilder.append(s);
+ }
+ optionsString = optionsBuilder.toString();
+ }
/* generate the historical information for deleted attributes */
if (deleteTime != null)
@@ -391,7 +447,6 @@
String strValue = type.getNormalizedPrimaryName()
+ optionsString + ":" + deleteTime.toString()
+ ":attrDel";
- delAttr = false;
AttributeValue val = new AttributeValue(historicalAttrType, strValue);
hist.add(val);
}
@@ -399,16 +454,16 @@
}
Attribute attr;
- Modification mod;
if (hist.isEmpty())
+ {
attr = new Attribute(historicalAttrType, HISTORICALATTRIBUTENAME, null);
+ }
else
+ {
attr = new Attribute(historicalAttrType, HISTORICALATTRIBUTENAME, hist);
- mod = new Modification(ModificationType.REPLACE, attr);
- mods.add(mod);
- modifiedEntry.removeAttribute(historicalAttrType);
- modifiedEntry.addAttribute(attr, null);
+ }
+ return attr;
}
/**
@@ -428,15 +483,22 @@
if (ChangeNumber.compare(newChange, moreRecentChangenumber) <= 0)
{
if (info == null)
+ {
return false; // the attribute was never modified -> no conflict
- else
- if (ChangeNumber.compare(newChange, info.getLastUpdateTime()) <= 0)
+ }
+ else if (ChangeNumber.compare(newChange, info.getLastUpdateTime()) <= 0)
+ {
return true; // the attribute was modified after this change -> conflict
+ }
else
+ {
return false;// the attribute was not modified more recently
+ }
}
else
+ {
return false;
+ }
}
/**
@@ -515,9 +577,13 @@
modAttr.setValues(replValues);
if (changeNumber.newer(attrInfo.getDeleteTime()))
+ {
attrInfo.setDeleteTime(changeNumber);
+ }
if (changeNumber.newer(attrInfo.getLastUpdateTime()))
+ {
attrInfo.setLastUpdateTime(changeNumber);
+ }
}
else
{
@@ -566,7 +632,9 @@
}
}
if (changeNumber.newer(attrInfo.getLastUpdateTime()))
+ {
attrInfo.setLastUpdateTime(changeNumber);
+ }
}
return true;
}
@@ -668,10 +736,14 @@
}
}
if (addValues.isEmpty())
+ {
modsIterator.remove();
+ }
if (changeNumber.newer(attrInfo.getLastUpdateTime()))
+ {
attrInfo.setLastUpdateTime(changeNumber);
+ }
return true;
}
@@ -691,7 +763,9 @@
AttrInfoWithOptions attrInfoWithOptions = null;
if (hist == null)
+ {
return histObj;
+ }
for (Attribute attr : hist)
{
@@ -734,8 +808,7 @@
}
else
{
- attrType = lastAttrType;
- if (options != lastOptions)
+ if (!options.equals(lastOptions))
{
attrInfo = new AttrInfo();
attrInfoWithOptions.put(options, attrInfo);
@@ -782,6 +855,8 @@
/* set the reference to the historical information in the entry */
return histObj;
}
+
+
/**
* Use this historical information to generate fake operations that would
* result in this historical information.
--
Gitblit v1.10.0