You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by th...@apache.org on 2008/05/05 10:59:26 UTC

svn commit: r653367 - in /jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core: persistence/bundle/util/ value/

Author: thomasm
Date: Mon May  5 01:59:26 2008
New Revision: 653367

URL: http://svn.apache.org/viewvc?rev=653367&view=rev
Log:
JCR-1563: Data Store: UTFDataFormatException when using large minRecordLength

Modified:
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/BundleBinding.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/BLOBFileValue.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/BLOBInDataStore.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/BLOBInMemory.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/BLOBInResource.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/BLOBInTempFile.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/BLOBValue.java

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/BundleBinding.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/BundleBinding.java?rev=653367&r1=653366&r2=653367&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/BundleBinding.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/BundleBinding.java Mon May  5 01:59:26 2008
@@ -48,6 +48,9 @@
  */
 public class BundleBinding extends ItemStateBinding {
 
+    private static final int BINARY_IN_BLOB_STORE = -1;
+    private static final int BINARY_IN_DATA_STORE = -2;
+
     /**
      * default logger
      */
@@ -131,7 +134,7 @@
         if (version >= VERSION_1) {
             bundle.setModCount(readModCount(in));
         }
-        
+
         // read shared set, since version 2.0
         Set sharedSet = new HashSet();
         if (version >= VERSION_2) {
@@ -143,7 +146,7 @@
             }
         }
         bundle.setSharedSet(sharedSet);
-        
+
         return bundle;
     }
 
@@ -299,7 +302,7 @@
 
         // write mod count
         writeModCount(out, bundle.getModCount());
-        
+
         // write shared set
         iter = bundle.getSharedSet().iterator();
         while (iter.hasNext()) {
@@ -341,9 +344,9 @@
             switch (type) {
                 case PropertyType.BINARY:
                     int size = in.readInt();
-                    if (InternalValue.USE_DATA_STORE && size == -2) {
+                    if (size == BINARY_IN_DATA_STORE) {
                         val = InternalValue.create(dataStore, in.readUTF());
-                    } else if (size == -1) {
+                    } else if (size == BINARY_IN_BLOB_STORE) {
                         blobIds[i] = in.readUTF();
                         try {
                             if (blobStore instanceof ResourceBasedBLOBStore) {
@@ -452,7 +455,7 @@
                         log.error("Error while reading size of binary: " + e);
                         return false;
                     }
-                    if (InternalValue.USE_DATA_STORE && size == -2) {
+                    if (size == BINARY_IN_DATA_STORE) {
                         try {
                             String s = in.readUTF();
                             // truncate log output
@@ -464,7 +467,7 @@
                             log.error("Error while reading blob id: " + e);
                             return false;
                         }
-                    } else if (size == -1) {
+                    } else if (size == BINARY_IN_BLOB_STORE) {
                         try {
                             String s = in.readUTF();
                             log.debug("  blobid: " + s);
@@ -581,22 +584,26 @@
             InternalValue val = values[i];
             switch (state.getType()) {
                 case PropertyType.BINARY:
+                    BLOBFileValue blobVal = val.getBLOBFileValue();
                     if (InternalValue.USE_DATA_STORE && dataStore != null) {
-                        out.writeInt(-2);
-                        try {
-                            val.store(dataStore);
-                        } catch (RepositoryException e) {
-                            String msg = "Error while storing blob. id="
-                                + state.getId() + " idx=" + i + " size=" + val.getBLOBFileValue().getLength();
-                            log.error(msg, e);
-                            throw new IOException(msg);
+                        if (blobVal.isSmall()) {
+                            writeSmallBinary(out, blobVal, state, i);
+                        } else {
+                            out.writeInt(BINARY_IN_DATA_STORE);
+                            try {
+                                val.store(dataStore);
+                            } catch (RepositoryException e) {
+                                String msg = "Error while storing blob. id="
+                                    + state.getId() + " idx=" + i + " size=" + val.getBLOBFileValue().getLength();
+                                log.error(msg, e);
+                                throw new IOException(msg);
+                            }
+                            out.writeUTF(val.toString());
                         }
-                        out.writeUTF(val.toString());
                         break;
                     }
                     // special handling required for binary value:
                     // spool binary value to file in blob store
-                    BLOBFileValue blobVal = val.getBLOBFileValue();
                     long size = blobVal.getLength();
                     if (size < 0) {
                         log.warn("Blob has negative size. Potential loss of data. "
@@ -605,7 +612,7 @@
                         values[i] = InternalValue.create(new byte[0]);
                         blobVal.discard();
                     } else if (size > minBlobSize) {
-                        out.writeInt(-1);
+                        out.writeInt(BINARY_IN_BLOB_STORE);
                         String blobId = state.getBlobId(i);
                         if (blobId == null) {
                             try {
@@ -642,23 +649,7 @@
                         out.writeUTF(blobId);   // value
                     } else {
                         // delete evt. blob
-                        out.writeInt((int) size);
-                        byte[] data = new byte[(int) size];
-                        try {
-                            DataInputStream in =
-                                new DataInputStream(blobVal.getStream());
-                            try {
-                                in.readFully(data);
-                            } finally {
-                                IOUtils.closeQuietly(in);
-                            }
-                        } catch (Exception e) {
-                            String msg = "Error while storing blob. id="
-                                    + state.getId() + " idx=" + i + " size=" + size;
-                            log.error(msg, e);
-                            throw new IOException(msg);
-                        }
-                        out.write(data, 0, data.length);
+                        byte[] data = writeSmallBinary(out, blobVal, state, i);
                         // replace value instance with value
                         // backed by resource in blob store and delete temp file
                         values[i] = InternalValue.create(data);
@@ -689,4 +680,37 @@
             }
         }
     }
+
+    /**
+     * Write a small binary value and return the data.
+     *
+     * @param out the output stream to write
+     * @param size the size
+     * @param blobVal the binary value
+     * @param state the property state (for error messages)
+     * @param i the index (for error messages)
+     * @return the data
+     * @throws IOException if the data could not be read
+     */
+    private byte[] writeSmallBinary(DataOutputStream out, BLOBFileValue blobVal, NodePropBundle.PropertyEntry state, int i) throws IOException {
+        int size = (int) blobVal.getLength();
+        out.writeInt(size);
+        byte[] data = new byte[size];
+        try {
+            DataInputStream in =
+                new DataInputStream(blobVal.getStream());
+            try {
+                in.readFully(data);
+            } finally {
+                IOUtils.closeQuietly(in);
+            }
+        } catch (Exception e) {
+            String msg = "Error while storing blob. id="
+                    + state.getId() + " idx=" + i + " size=" + size;
+            log.error(msg, e);
+            throw new IOException(msg);
+        }
+        out.write(data, 0, data.length);
+        return data;
+    }
 }

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/BLOBFileValue.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/BLOBFileValue.java?rev=653367&r1=653366&r2=653367&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/BLOBFileValue.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/BLOBFileValue.java Mon May  5 01:59:26 2008
@@ -111,4 +111,12 @@
      */
     public abstract int hashCode();
 
+    /**
+     * Check if the value is small (contains a low number of bytes) and should
+     * be stored inline.
+     *
+     * @return true if the value is small
+     */
+    public abstract boolean isSmall();
+
 }

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/BLOBInDataStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/BLOBInDataStore.java?rev=653367&r1=653366&r2=653367&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/BLOBInDataStore.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/BLOBInDataStore.java Mon May  5 01:59:26 2008
@@ -136,4 +136,8 @@
         return store.getRecord(identifier);
     }
 
+    public boolean isSmall() {
+        return false;
+    }
+
 }

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/BLOBInMemory.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/BLOBInMemory.java?rev=653367&r1=653366&r2=653367&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/BLOBInMemory.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/BLOBInMemory.java Mon May  5 01:59:26 2008
@@ -194,4 +194,8 @@
         return 0;
     }
 
+    public boolean isSmall() {
+        return true;
+    }
+
 }

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/BLOBInResource.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/BLOBInResource.java?rev=653367&r1=653366&r2=653367&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/BLOBInResource.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/BLOBInResource.java Mon May  5 01:59:26 2008
@@ -159,4 +159,11 @@
         return 0;
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    public boolean isSmall() {
+        return false;
+    }
+
 }

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/BLOBInTempFile.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/BLOBInTempFile.java?rev=653367&r1=653366&r2=653367&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/BLOBInTempFile.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/BLOBInTempFile.java Mon May  5 01:59:26 2008
@@ -177,4 +177,11 @@
         return 0;
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    public boolean isSmall() {
+        return false;
+    }
+
 }

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/BLOBValue.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/BLOBValue.java?rev=653367&r1=653366&r2=653367&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/BLOBValue.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/BLOBValue.java Mon May  5 01:59:26 2008
@@ -237,7 +237,7 @@
      * @see #delete(boolean)
      */
     public void discard() {
-        if (!temp){
+        if (!temp) {
             // do nothing if this instance is not backed by temporarily
             // allocated resource/buffer
             return;
@@ -367,4 +367,11 @@
         }
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    public boolean isSmall() {
+        return false;
+    }
+
 }