From 0a9f8b5b08f995ee284445bc0afffc8556df6f03 Mon Sep 17 00:00:00 2001
From: abobrov <abobrov@localhost>
Date: Thu, 26 Mar 2009 16:44:59 +0000
Subject: [PATCH] - [Issue 3894] possible data corruption issues when writing binary attributes/blobs : move blobs to active state before writing the actual data, use new writeData API, optimize add operation to invoke execute/NoCommit past insert only when necessary ie when batching.

---
 opends/src/server/org/opends/server/backends/ndb/OperationContainer.java |   25 ++++++++++++++++++++++---
 1 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/opends/src/server/org/opends/server/backends/ndb/OperationContainer.java b/opends/src/server/org/opends/server/backends/ndb/OperationContainer.java
index 3154152..18bc508 100644
--- a/opends/src/server/org/opends/server/backends/ndb/OperationContainer.java
+++ b/opends/src/server/org/opends/server/backends/ndb/OperationContainer.java
@@ -161,6 +161,8 @@
     Map<ObjectClass, String> ocMap = entry.getObjectClasses();
     Map<AttributeType, List<Attribute>> userAttrMap =
       entry.getUserAttributes();
+    Map<NdbBlob, byte[]> blobMap =
+      new HashMap<NdbBlob, byte[]>(BackendImpl.blobAttributes.size());
     ArrayList<AttributeType> userAttributes =
       new ArrayList<AttributeType>();
 
@@ -252,7 +254,9 @@
               }
               if (BackendImpl.blobAttributes.contains(attrName)) {
                 NdbBlob blob = attrOp.getBlobHandle(attrName);
-                blob.setValue(attrVal.getValue().toByteArray());
+                blob.setValue(new byte[0]);
+                byte[] blobBytes = attrVal.getValue().toByteArray();
+                blobMap.put(blob, blobBytes);
               } else {
                 attrOp.setString(attrName, attrStringVal);
               }
@@ -328,7 +332,9 @@
               }
               if (BackendImpl.blobAttributes.contains(attrName)) {
                 NdbBlob blob = attrOp.getBlobHandle(attrName);
-                blob.setValue(attrVal.getValue().toByteArray());
+                blob.setValue(new byte[0]);
+                byte[] blobBytes = attrVal.getValue().toByteArray();
+                blobMap.put(blob, blobBytes);
               } else {
                 attrOp.setString(attrName, attrStringVal);
               }
@@ -421,7 +427,9 @@
               }
               if (BackendImpl.blobAttributes.contains(attrName)) {
                 NdbBlob blob = attrOp.getBlobHandle(attrName);
-                blob.setValue(attrVal.getValue().toByteArray());
+                blob.setValue(new byte[0]);
+                byte[] blobBytes = attrVal.getValue().toByteArray();
+                blobMap.put(blob, blobBytes);
               } else {
                 attrOp.setString(attrName, attrStringVal);
               }
@@ -477,6 +485,17 @@
       }
     }
 
+    // Move this txn into the active state and write blob data if any.
+    if (!blobMap.isEmpty()) {
+      ndbDATxn.execute(ExecType.NoCommit, AbortOption.AbortOnError, true);
+      Set<Map.Entry<NdbBlob, byte[]>> blobEntrySet = blobMap.entrySet();
+      for (Map.Entry blobEntry : blobEntrySet) {
+        NdbBlob blob = (NdbBlob) blobEntry.getKey();
+        byte[] blobBytes = (byte[]) blobEntry.getValue();
+        blob.writeData(blobBytes);
+      }
+    }
+
     // Update dn2id table.
     NdbTransaction ndbTxn = txn.getNdbTransaction();
     if (overwrite) {

--
Gitblit v1.10.0