From 60eebeca51e75c9d3fdb0a82f0a5b5be6f64dd17 Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Mon, 23 Jan 2012 14:51:36 +0000
Subject: [PATCH] Fix OPENDJ-410: Frequent corruption in ds-sync-hist ordering index

---
 opends/src/server/org/opends/server/replication/plugin/HistoricalCsnOrderingMatchingRule.java |   50 +++++++++++++++++++++++++++++---------------------
 1 files changed, 29 insertions(+), 21 deletions(-)

diff --git a/opends/src/server/org/opends/server/replication/plugin/HistoricalCsnOrderingMatchingRule.java b/opends/src/server/org/opends/server/replication/plugin/HistoricalCsnOrderingMatchingRule.java
index 6c754e6..5949680 100644
--- a/opends/src/server/org/opends/server/replication/plugin/HistoricalCsnOrderingMatchingRule.java
+++ b/opends/src/server/org/opends/server/replication/plugin/HistoricalCsnOrderingMatchingRule.java
@@ -23,15 +23,19 @@
  *
  *
  *      Copyright 2006-2010 Sun Microsystems, Inc.
+ *      Portions copyright 2012 ForgeRock AS.
  */
 package org.opends.server.replication.plugin;
 
+import static org.opends.messages.ReplicationMessages.*;
+import static org.opends.server.util.StaticUtils.hexStringToByteArray;
+
 import java.util.Collection;
 import java.util.Collections;
+
 import org.opends.server.api.AbstractMatchingRule;
 import org.opends.server.api.OrderingMatchingRule;
-import org.opends.server.types.ByteString;
-import org.opends.server.types.ByteSequence;
+import org.opends.server.types.*;
 
 /**
  * Used to establish an order between historical information and index them.
@@ -122,30 +126,34 @@
   }
 
   /**
-   * Normalize historical information representation.
-   * @param value the value that must be normalized
-   * @return The String form that must be used for historical information
-   * comparison
+   * {@inheritDoc}
    */
   @Override
   public ByteString normalizeValue(ByteSequence value)
+      throws DirectoryException
   {
-    String[] token = value.toString().split(":", 3);
-
-    /* Change the format of the value to index and start
-     * with the serverId. In that manner, the search response
-     * time is optimised for a particulare serverId.
-     * The format of the key is now :
-     * serverId + timestamp + seqNum
+    /*
+     * Change the format of the value to index and start with the serverId. In
+     * that manner, the search response time is optimised for a particular
+     * serverId. The format of the key is now : serverId + timestamp + seqNum
      */
-    String timestamp = token[1].substring(0,16);
-    String serverId = token[1].substring(16,20);
-    String seqNumber = token[1].substring(20, 28);
-
-    if (MultimasterReplication.isLocalServerId(Integer.parseInt(serverId, 16)))
-      return ByteString.valueOf(serverId + timestamp + seqNumber);
-    else
-      return (ByteString.valueOf("0"));
+    try
+    {
+      int csnIndex = value.toString().indexOf(':') + 1;
+      String csn = value.subSequence(csnIndex, csnIndex + 28).toString();
+      ByteStringBuilder builder = new ByteStringBuilder(14);
+      builder.append(hexStringToByteArray(csn.substring(16, 20)));
+      builder.append(hexStringToByteArray(csn.substring(00, 16)));
+      builder.append(hexStringToByteArray(csn.substring(20, 28)));
+      return builder.toByteString();
+    }
+    catch (Exception e)
+    {
+      // This should never occur in practice since these attributes are managed
+      // internally.
+      throw new DirectoryException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
+          WARN_INVALID_SYNC_HIST_VALUE.get(String.valueOf(value)), e);
+    }
   }
 
   /**

--
Gitblit v1.10.0