jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From thom...@apache.org
Subject svn commit: r768982 - in /jackrabbit/trunk/jackrabbit-core/src: main/java/org/apache/jackrabbit/core/data/ test/java/org/apache/jackrabbit/core/data/
Date Mon, 27 Apr 2009 13:50:56 GMT
Author: thomasm
Date: Mon Apr 27 13:50:55 2009
New Revision: 768982

URL: http://svn.apache.org/viewvc?rev=768982&view=rev
Log:
JCR-2067 FileDataStore: only open a stream when really necessary

Added:
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/LazyFileInputStream.java
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/OpenFilesTest.java
Modified:
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/FileDataRecord.java
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/TestAll.java

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/FileDataRecord.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/FileDataRecord.java?rev=768982&r1=768981&r2=768982&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/FileDataRecord.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/FileDataRecord.java
Mon Apr 27 13:50:55 2009
@@ -17,8 +17,6 @@
 package org.apache.jackrabbit.core.data;
 
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
 import java.io.InputStream;
 
 /**
@@ -54,11 +52,7 @@
      * {@inheritDoc}
      */
     public InputStream getStream() throws DataStoreException {
-        try {
-            return new FileInputStream(file);
-        } catch (IOException e) {
-            throw new DataStoreException("Error opening input stream of " + file.getAbsolutePath(),
e);
-        }
+        return new LazyFileInputStream(file);
     }
 
     /**

Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/LazyFileInputStream.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/LazyFileInputStream.java?rev=768982&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/LazyFileInputStream.java
(added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/LazyFileInputStream.java
Mon Apr 27 13:50:55 2009
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.core.data;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+import org.apache.commons.io.input.AutoCloseInputStream;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This input stream delays opening the file until the first byte is read, and
+ * closes and discards the underlying stream as soon as the end of input has
+ * been reached or when the stream is explicitly closed.
+ */
+public class LazyFileInputStream extends AutoCloseInputStream {
+
+    private static Logger log = LoggerFactory.getLogger(LazyFileInputStream.class);
+
+    /**
+     * The file to read from.
+     */
+    protected final File file;
+
+    /**
+     * True if the input stream was opened. It is also set to true if the stream
+     * was closed without reading (to avoid opening the file after the stream
+     * was closed).
+     */
+    protected boolean opened;
+
+    /**
+     * Create a lazy input stream for the given file.
+     * The file is not opened until the first byte is read from the stream.
+     * 
+     * @param file the file
+     */
+    protected LazyFileInputStream(File file) {
+        super(null);
+        this.file = file;
+    }
+
+    /**
+     * Open the stream if required.
+     * 
+     * @throws IOException
+     */
+    protected void openStream() throws IOException {
+        if (!opened) {
+            opened = true;
+            in = new FileInputStream(file);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     * When the stream is consumed, the database objects held by the instance are closed.
+     */
+    public int read() throws IOException {
+        openStream();
+        return super.read();
+    }
+
+    public int read(byte[] b) throws IOException {
+        return read(b, 0, b.length);
+    }
+
+    public int read(byte[] b, int off, int len) throws IOException {
+        openStream();
+        return super.read(b, off, len);
+    }
+
+    public void close() throws IOException {
+        // make sure the file is not opened afterwards
+        opened = true;
+        super.close();
+    }
+
+    public long skip(long n) throws IOException {
+        openStream();
+        return super.skip(n);
+    }
+
+    public int available() throws IOException {
+        openStream();
+        return super.available();
+    }
+
+    public void mark(int readlimit) {
+        try {
+            openStream();
+        } catch (IOException e) {
+            log.info("Error getting underlying stream: ", e);
+        }
+        super.mark(readlimit);
+    }
+
+    public void reset() throws IOException {
+        openStream();
+        super.reset();
+    }
+
+    public boolean markSupported() {
+        try {
+            openStream();
+        } catch (IOException e) {
+            log.info("Error getting underlying stream: ", e);
+            return false;
+        }
+        return super.markSupported();
+    }
+
+}

Added: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/OpenFilesTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/OpenFilesTest.java?rev=768982&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/OpenFilesTest.java
(added)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/OpenFilesTest.java
Mon Apr 27 13:50:55 2009
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.core.data;
+
+import java.io.ByteArrayInputStream;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.apache.jackrabbit.test.AbstractJCRTest;
+
+/**
+ * Test if getting the value from a binary property opens the file.
+ */
+public class OpenFilesTest extends AbstractJCRTest {
+    
+    /**
+     * Test opening a large number of streams.
+     */
+    public void testStreams() throws RepositoryException {
+        Session session = helper.getReadWriteSession();
+        try {
+            Node test = session.getRootNode().addNode("test");
+            test.setProperty("data", new ByteArrayInputStream(new byte[10 * 1024]));
+            session.save();
+            for (int i = 0; i < 10000; i++) {
+                test.getProperty("data").getValue();
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            assertFalse(e.getMessage(), true);
+        } finally {
+            session.logout();
+        }
+    }
+
+}

Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/TestAll.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/TestAll.java?rev=768982&r1=768981&r2=768982&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/TestAll.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/TestAll.java
Mon Apr 27 13:50:55 2009
@@ -32,6 +32,7 @@
      */
     public static Test suite() {
         TestSuite suite = new TestSuite("Data tests");
+        suite.addTestSuite(OpenFilesTest.class);
         suite.addTestSuite(DataStoreTest.class);
         suite.addTestSuite(NodeTypeTest.class);
         suite.addTestSuite(ExportImportTest.class);



Mime
View raw message