jackrabbit-oak-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From resc...@apache.org
Subject svn commit: r1556867 - in /jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/sqlpersistence: SQLBlobStore.java SQLDocumentStore.java
Date Thu, 09 Jan 2014 16:46:22 GMT
Author: reschke
Date: Thu Jan  9 16:46:22 2014
New Revision: 1556867

URL: http://svn.apache.org/r1556867
Log:
OAK-1266 - BLOB store

Added:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/sqlpersistence/SQLBlobStore.java
Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/sqlpersistence/SQLDocumentStore.java

Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/sqlpersistence/SQLBlobStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/sqlpersistence/SQLBlobStore.java?rev=1556867&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/sqlpersistence/SQLBlobStore.java
(added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/sqlpersistence/SQLBlobStore.java
Thu Jan  9 16:46:22 2014
@@ -0,0 +1,195 @@
+/*
+ * 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.oak.plugins.sqlpersistence;
+
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+
+import org.apache.jackrabbit.mk.api.MicroKernelException;
+import org.apache.jackrabbit.mk.blobs.AbstractBlobStore;
+import org.apache.jackrabbit.mk.util.StringUtils;
+
+// mostly copied from DbBlobStore, removing the ConnectionPool dependency
+
+public class SQLBlobStore extends AbstractBlobStore {
+
+    /**
+     * Creates a {@linkplain SQLBlobStore} instance using an embedded H2
+     * database in in-memory mode.
+     */
+    public SQLBlobStore() {
+        try {
+            String jdbcurl = "jdbc:h2:mem:oaknodes";
+            initialize(jdbcurl, "sa", "");
+        } catch (Exception ex) {
+            throw new MicroKernelException("initializing SQL blob store", ex);
+        }
+    }
+
+    /**
+     * Creates a {@linkplain SQLBlobStore} instance using the provided JDBC
+     * connection information.
+     */
+    public SQLBlobStore(String jdbcurl, String username, String password) {
+        try {
+            initialize(jdbcurl, username, password);
+        } catch (Exception ex) {
+            throw new MicroKernelException("initializing SQL blob store", ex);
+        }
+    }
+
+    private Connection connection;
+
+    private void initialize(String jdbcurl, String username, String password) throws Exception
{
+        connection = DriverManager.getConnection(jdbcurl, username, password);
+        connection.setAutoCommit(false);
+        Statement stmt = connection.createStatement();
+
+        stmt.execute("create table if not exists datastore_meta" + "(id varchar primary key,
level int, lastMod bigint)");
+        stmt.execute("create table if not exists datastore_data" + "(id varchar primary key,
data binary)");
+        stmt.close();
+    }
+
+    private long minLastModified;
+
+    @Override
+    protected synchronized void storeBlock(byte[] digest, int level, byte[] data) throws
SQLException {
+        String id = StringUtils.convertBytesToHex(digest);
+        long now = System.currentTimeMillis();
+        PreparedStatement prep = connection.prepareStatement("update datastore_meta set lastMod
= ? where id = ?");
+        int count;
+        try {
+            prep.setLong(1, now);
+            prep.setString(2, id);
+            count = prep.executeUpdate();
+        } finally {
+            prep.close();
+        }
+        if (count == 0) {
+            try {
+                prep = connection.prepareStatement("insert into datastore_data(id, data)
values(?, ?)");
+                try {
+                    prep.setString(1, id);
+                    prep.setBytes(2, data);
+                    prep.execute();
+                } finally {
+                    prep.close();
+                }
+            } catch (SQLException e) {
+                // already exists - ok
+            }
+            try {
+                prep = connection.prepareStatement("insert into datastore_meta(id, level,
lastMod) values(?, ?, ?)");
+                try {
+                    prep.setString(1, id);
+                    prep.setInt(2, level);
+                    prep.setLong(3, now);
+                    prep.execute();
+                } finally {
+                    prep.close();
+                }
+            } catch (SQLException e) {
+                // already exists - ok
+            }
+        }
+    }
+
+    @Override
+    protected byte[] readBlockFromBackend(BlockId blockId) throws Exception {
+        PreparedStatement prep = connection.prepareStatement("select data from datastore_data
where id = ?");
+        try {
+            String id = StringUtils.convertBytesToHex(blockId.getDigest());
+            prep.setString(1, id);
+            ResultSet rs = prep.executeQuery();
+            if (!rs.next()) {
+                throw new IOException("Datastore block " + id + " not found");
+            }
+            byte[] data = rs.getBytes(1);
+            // System.out.println("    read block " + id + " blockLen: " +
+            // data.length + " [0]: " + data[0]);
+            if (blockId.getPos() == 0) {
+                return data;
+            }
+            int len = (int) (data.length - blockId.getPos());
+            if (len < 0) {
+                return new byte[0];
+            }
+            byte[] d2 = new byte[len];
+            System.arraycopy(data, (int) blockId.getPos(), d2, 0, len);
+            return d2;
+        } finally {
+            prep.close();
+        }
+    }
+
+    @Override
+    public void startMark() throws Exception {
+        minLastModified = System.currentTimeMillis();
+        markInUse();
+    }
+
+    @Override
+    protected boolean isMarkEnabled() {
+        return minLastModified != 0;
+    }
+
+    @Override
+    protected void mark(BlockId blockId) throws Exception {
+        if (minLastModified == 0) {
+            return;
+        }
+        String id = StringUtils.convertBytesToHex(blockId.getDigest());
+        PreparedStatement prep = connection.prepareStatement("update datastore_meta set lastMod
= ? where id = ? and lastMod < ?");
+        prep.setLong(1, System.currentTimeMillis());
+        prep.setString(2, id);
+        prep.setLong(3, minLastModified);
+        prep.executeUpdate();
+        prep.close();
+    }
+
+    @Override
+    public int sweep() throws Exception {
+        int count = 0;
+        PreparedStatement prep = connection.prepareStatement("select id from datastore_meta
where lastMod < ?");
+        prep.setLong(1, minLastModified);
+        ResultSet rs = prep.executeQuery();
+        ArrayList<String> ids = new ArrayList<String>();
+        while (rs.next()) {
+            ids.add(rs.getString(1));
+        }
+        prep = connection.prepareStatement("delete from datastore_meta where id = ?");
+        PreparedStatement prepData = connection.prepareStatement("delete from datastore_data
where id = ?");
+        for (String id : ids) {
+            prep.setString(1, id);
+            prep.execute();
+            prepData.setString(1, id);
+            prepData.execute();
+            count++;
+        }
+        prepData.close();
+        prep.close();
+        minLastModified = 0;
+        return count;
+    }
+
+}

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/sqlpersistence/SQLDocumentStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/sqlpersistence/SQLDocumentStore.java?rev=1556867&r1=1556866&r2=1556867&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/sqlpersistence/SQLDocumentStore.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/sqlpersistence/SQLDocumentStore.java
Thu Jan  9 16:46:22 2014
@@ -166,6 +166,8 @@ public class SQLDocumentStore implements
         stmt.execute("drop table if exists NODES");
         stmt.execute("create table if not exists CLUSTERNODES(ID varchar primary key, MODIFIED
bigint, MODCOUNT bigint, DATA varchar)");
         stmt.execute("create table if not exists NODES(ID varchar primary key, MODIFIED bigint,
MODCOUNT bigint, DATA varchar)");
+
+        connection.commit();
     }
 
     @CheckForNull



Mime
View raw message