Return-Path: X-Original-To: apmail-jackrabbit-commits-archive@www.apache.org Delivered-To: apmail-jackrabbit-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id DCA6B7065 for ; Thu, 22 Sep 2011 05:55:00 +0000 (UTC) Received: (qmail 27502 invoked by uid 500); 22 Sep 2011 05:55:00 -0000 Delivered-To: apmail-jackrabbit-commits-archive@jackrabbit.apache.org Received: (qmail 27424 invoked by uid 500); 22 Sep 2011 05:54:59 -0000 Mailing-List: contact commits-help@jackrabbit.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@jackrabbit.apache.org Delivered-To: mailing list commits@jackrabbit.apache.org Received: (qmail 27417 invoked by uid 99); 22 Sep 2011 05:54:59 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 22 Sep 2011 05:54:59 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 22 Sep 2011 05:54:56 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 0BEA023888EA; Thu, 22 Sep 2011 05:54:35 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1173953 - in /jackrabbit/sandbox/microkernel/src: main/java/org/apache/jackrabbit/mk/mem/MemoryKernelImpl.java main/java/org/apache/jackrabbit/mk/mem/NodeMapInDb.java test/java/org/apache/jackrabbit/mk/MultiMkTestBase.java Date: Thu, 22 Sep 2011 05:54:34 -0000 To: commits@jackrabbit.apache.org From: thomasm@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20110922055435.0BEA023888EA@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: thomasm Date: Thu Sep 22 05:54:34 2011 New Revision: 1173953 URL: http://svn.apache.org/viewvc?rev=1173953&view=rev Log: Store nodes in a database. Added: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/mem/NodeMapInDb.java Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/mem/MemoryKernelImpl.java jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/MultiMkTestBase.java Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/mem/MemoryKernelImpl.java URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/mem/MemoryKernelImpl.java?rev=1173953&r1=1173952&r2=1173953&view=diff ============================================================================== --- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/mem/MemoryKernelImpl.java (original) +++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/mem/MemoryKernelImpl.java Thu Sep 22 05:54:34 2011 @@ -74,6 +74,7 @@ public class MemoryKernelImpl implements private NodeMap nodeMap; private String lastJournalRevRange, lastJournal; private Server server; + private boolean disposed; private MemoryKernelImpl(String name) { if (DEBUG) { @@ -93,6 +94,7 @@ public class MemoryKernelImpl implements } catch (IOException e) { throw ExceptionFactory.convert(e); } + nodeMap = new NodeMapInDb(dir); } else { ds = new MemoryBlobStore(); } @@ -573,12 +575,15 @@ public class MemoryKernelImpl implements if (DEBUG) { log("dispose"); } - gate.commit("end"); - nodeMap.close(); - INSTANCES.remove(name); - if (server != null) { - server.stop(); - server = null; + if (!disposed) { + disposed = true; + gate.commit("end"); + nodeMap.close(); + INSTANCES.remove(name); + if (server != null) { + server.stop(); + server = null; + } } } Added: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/mem/NodeMapInDb.java URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/mem/NodeMapInDb.java?rev=1173953&view=auto ============================================================================== --- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/mem/NodeMapInDb.java (added) +++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/mem/NodeMapInDb.java Thu Sep 22 05:54:34 2011 @@ -0,0 +1,174 @@ +/* + * 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.mk.mem; + +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 java.util.HashMap; +import java.util.Map; +import java.util.TreeMap; +import java.util.Map.Entry; +import org.apache.jackrabbit.mk.fs.FilePath; +import org.apache.jackrabbit.mk.json.JsopBuilder; +import org.apache.jackrabbit.mk.mem.NodeImpl.ChildVisitor; +import org.apache.jackrabbit.mk.util.Cache; +import org.apache.jackrabbit.mk.util.ExceptionFactory; +import org.apache.jackrabbit.mk.util.SimpleLRUCache; + +/** + * A node map that stores data in a database. + */ +public class NodeMapInDb extends NodeMap implements Cache.Backend { + + final HashMap temp = new HashMap(); + private Connection conn; + private final String url; + private final TreeMap properties = new TreeMap(); + private final Cache cache = Cache.newInstance(this, 10 * 1024 * 1024); + private final Map reuse = SimpleLRUCache.newInstance(10000); + private final HashMap pos = new HashMap(); + private final PreparedStatement select, insert, merge; + private long nextId; + private NodeImpl root = new NodeImpl(this, 0); + + NodeMapInDb(String dir) { + try { + url = "jdbc:h2:" + FilePath.get(dir).resolve("nodes").toRealPath().toString() + System.getProperty("mk.db", ""); + Class.forName("org.h2.Driver"); + conn = DriverManager.getConnection(url); + Statement stat = conn.createStatement(); + stat.execute("create table if not exists nodes(id bigint primary key, data varchar)"); + stat.execute("create table if not exists roots(key bigint primary key, value bigint) as select 0, 0"); + ResultSet rs = stat.executeQuery("select max(id) from nodes"); + rs.next(); + nextId = rs.getLong(1) + 1; + rs = stat.executeQuery("select max(value) from roots"); + rs.next(); + root.setId(rs.getLong(1)); + select = conn.prepareStatement("select * from nodes where id = ?"); + insert = conn.prepareStatement("insert into nodes sorted select ?, ?"); + merge = conn.prepareStatement("update roots set value = ?"); + } catch (Exception e) { + throw ExceptionFactory.convert(e); + } + } + + public synchronized long addNode(NodeImpl node) { + long x = node.getId(); + if (x == 0) { + x = -temp.size() - 1; + node.setId(x); + temp.put(x, node); + } + return x; + } + + public NodeImpl getNode(long x) { + return x < 0 ? temp.get(x) : cache.get(x); + } + + public NodeImpl load(Long key) { + try { + select.setLong(1, key); + ResultSet rs = select.executeQuery(); + if (!rs.next()) { + throw ExceptionFactory.get("Node not found: " + key); + } + return NodeImpl.fromString(this, rs.getString(2)); + } catch (Exception e) { + throw ExceptionFactory.convert(e); + } + } + + public synchronized long commit(NodeImpl newRoot) { + addNode(newRoot); + try { + final ArrayList list = new ArrayList(); + newRoot.visit(new ChildVisitor() { + public void accept(long childId) { + if (childId < 0) { + temp.get(childId).visit(this); + list.add(childId); + } + } + }); + list.add(newRoot.getId()); + for (Long id : list) { + NodeImpl n = temp.get(id); + NodeImpl r = reuse.get(n); + long newId; + if (r != null) { + newId = r.getId(); + pos.put(id, newId); + } else { + newId = nextId++; + n.setId(newId); + pos.put(id, newId); + insert.setLong(1, newId); + insert.setString(2, n.asString()); + insert.execute(); + cache.put(n.getId(), n); + reuse.put(n, n); + } + } + merge.setLong(1, newRoot.getId()); + merge.execute(); + temp.clear(); + pos.clear(); + } catch (Exception e) { + throw ExceptionFactory.convert(e); + } + root = newRoot; + return root.getId(); + } + + public long getId(long id) { + return (id > 0 || !pos.containsKey(id)) ? id : pos.get(id); + } + + public long getRootId() { + return root.getId(); + } + + public NodeImpl getInfo(String path) { + NodeImpl n = new NodeImpl(this, 0); + n.setProperty("url", JsopBuilder.encode(url)); + for (Entry e : properties.entrySet()) { + n.setProperty("property." + e.getKey(), e.getValue()); + } + n.setProperty("cache.size", "" + cache.size()); + n.setProperty("cache.memoryUsed", "" + cache.getMemoryUsed()); + n.setProperty("cache.memoryMax", "" + cache.getMemoryMax()); + n.setProperty("nextId", "" + nextId); + n.setProperty("root", "" + root.getId()); + return n; + } + + public synchronized void close() { + try { + conn.close(); + } catch (SQLException e) { + throw ExceptionFactory.convert(e); + } + } + +} Modified: jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/MultiMkTestBase.java URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/MultiMkTestBase.java?rev=1173953&r1=1173952&r2=1173953&view=diff ============================================================================== --- jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/MultiMkTestBase.java (original) +++ jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/MultiMkTestBase.java Thu Sep 22 05:54:34 2011 @@ -51,7 +51,7 @@ public class MultiMkTestBase { } protected void reconnect() { - if (!url.startsWith("mem:")) { + if (!url.equals("mem:")) { mk.dispose(); mk = MicroKernelFactory.getInstance(url); }