You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by md...@apache.org on 2011/12/29 17:39:16 UTC
svn commit: r1225586 - in /jackrabbit/sandbox/jackrabbit-microkernel/src:
main/java/org/apache/jackrabbit/
main/java/org/apache/jackrabbit/configuration/
main/java/org/apache/jackrabbit/state/ test/java/org/apache/jackrabbit/
Author: mduerig
Date: Thu Dec 29 16:39:15 2011
New Revision: 1225586
URL: http://svn.apache.org/viewvc?rev=1225586&view=rev
Log:
Microkernel based prototype of JCR implementation (WIP)
- add configurable node state cache
Added:
jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/CacheFactory.java
jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/NodeStateCache.java
jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/NodeStateCacheImpl.java
Modified:
jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/GlobalContext.java
jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/SessionContext.java
jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/SessionImpl.java
jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/configuration/RepositoryConfiguration.java
jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/configuration/RepositoryConfigurationImpl.java
jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/NodeState.java
jackrabbit/sandbox/jackrabbit-microkernel/src/test/java/org/apache/jackrabbit/RepositoryTest.java
Added: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/CacheFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/CacheFactory.java?rev=1225586&view=auto
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/CacheFactory.java (added)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/CacheFactory.java Thu Dec 29 16:39:15 2011
@@ -0,0 +1,8 @@
+package org.apache.jackrabbit;
+
+import org.apache.jackrabbit.configuration.RepositoryConfiguration;
+import org.apache.jackrabbit.state.NodeStateCache;
+
+public interface CacheFactory {
+ NodeStateCache create(RepositoryConfiguration configuration);
+}
Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/GlobalContext.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/GlobalContext.java?rev=1225586&r1=1225585&r2=1225586&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/GlobalContext.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/GlobalContext.java Thu Dec 29 16:39:15 2011
@@ -19,13 +19,14 @@
package org.apache.jackrabbit;
+import org.apache.jackrabbit.commons.SimpleValueFactory;
import org.apache.jackrabbit.configuration.RepositoryConfiguration;
+import org.apache.jackrabbit.mk.MicroKernelFactory;
+import org.apache.jackrabbit.mk.api.MicroKernel;
import org.apache.jackrabbit.security.Authenticator;
import org.apache.jackrabbit.security.AuthenticatorImpl;
+import org.apache.jackrabbit.state.NodeStateCacheImpl;
import org.apache.jackrabbit.utils.Unchecked;
-import org.apache.jackrabbit.commons.SimpleValueFactory;
-import org.apache.jackrabbit.mk.MicroKernelFactory;
-import org.apache.jackrabbit.mk.api.MicroKernel;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
@@ -48,6 +49,7 @@ public class GlobalContext {
put(Repository.class, RepositoryImpl.create(this));
put(Authenticator.class, AuthenticatorImpl.INSTANCE);
put(SessionFactory.class, SessionImpl.FACTORY);
+ put(CacheFactory.class, NodeStateCacheImpl.FACTORY);
}
public <T> T getInstance(Class<T> forClass) {
Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/SessionContext.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/SessionContext.java?rev=1225586&r1=1225585&r2=1225586&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/SessionContext.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/SessionContext.java Thu Dec 29 16:39:15 2011
@@ -21,6 +21,7 @@ package org.apache.jackrabbit;
import org.apache.jackrabbit.mk.api.MicroKernel;
import org.apache.jackrabbit.security.CredentialsInfo;
+import org.apache.jackrabbit.state.NodeStateCache;
import org.apache.jackrabbit.state.TransientSpace;
import javax.jcr.Session;
@@ -35,4 +36,5 @@ public interface SessionContext<T extend
String getRevision();
ValueFactory getValueFactory();
TransientSpace getTransientSpace();
+ NodeStateCache getNodeStateCache();
}
Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/SessionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/SessionImpl.java?rev=1225586&r1=1225585&r2=1225586&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/SessionImpl.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/SessionImpl.java Thu Dec 29 16:39:15 2011
@@ -19,10 +19,12 @@
package org.apache.jackrabbit;
+import org.apache.jackrabbit.configuration.RepositoryConfiguration;
import org.apache.jackrabbit.mk.api.MicroKernel;
import org.apache.jackrabbit.security.Authenticator;
import org.apache.jackrabbit.security.CredentialsInfo;
import org.apache.jackrabbit.state.NodeState;
+import org.apache.jackrabbit.state.NodeStateCache;
import org.apache.jackrabbit.state.TransientSpace;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
@@ -53,6 +55,7 @@ public class SessionImpl implements Sess
private final String workspaceName;
private final MicroKernel microKernel;
private final TransientSpace transientSpace;
+ private final NodeStateCache nodeStateCache;
private String revision;
private boolean live = true;
@@ -99,6 +102,11 @@ public class SessionImpl implements Sess
public TransientSpace getTransientSpace() {
return transientSpace;
}
+
+ @Override
+ public NodeStateCache getNodeStateCache() {
+ return nodeStateCache;
+ }
};
public static final SessionFactory FACTORY = new SessionFactory() {
@@ -138,6 +146,8 @@ public class SessionImpl implements Sess
this.revision = revision;
microKernel = globalContext.getInstance(MicroKernel.class);
transientSpace = new TransientSpace(workspaceName, microKernel, revision);
+ nodeStateCache = globalContext.getInstance(CacheFactory.class)
+ .create(globalContext.getInstance(RepositoryConfiguration.class));
}
//------------------------------------------< Session >---
@@ -266,12 +276,14 @@ public class SessionImpl implements Sess
public void save() throws RepositoryException {
checkLive();
revision = transientSpace.save();
+ nodeStateCache.clear();
}
@Override
public void refresh(boolean keepChanges) throws RepositoryException {
checkLive();
revision = transientSpace.refresh(keepChanges);
+ nodeStateCache.clear();
}
@Override
@@ -426,6 +438,7 @@ public class SessionImpl implements Sess
//------------------------------------------< private >---
+ // todo: we need to checkLive from ops on nodes and properties too.
private void checkLive() throws RepositoryException {
if (!isLive()) {
throw new RepositoryException("Session has already been closed");
Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/configuration/RepositoryConfiguration.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/configuration/RepositoryConfiguration.java?rev=1225586&r1=1225585&r2=1225586&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/configuration/RepositoryConfiguration.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/configuration/RepositoryConfiguration.java Thu Dec 29 16:39:15 2011
@@ -24,7 +24,9 @@ import java.util.Map;
public interface RepositoryConfiguration {
String MICROKERNEL_URL = RepositoryConfiguration.class.getName() + ".microkernel-url";
+ String NODE_STATE_CACHE_SIZE = RepositoryConfiguration.class.getName() + ".node-state-cache-size";
Map<String, String> getParameterMap();
String getMicrokernelUrl() throws RepositoryException;
+ int getNodeStateCacheSize();
}
Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/configuration/RepositoryConfigurationImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/configuration/RepositoryConfigurationImpl.java?rev=1225586&r1=1225585&r2=1225586&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/configuration/RepositoryConfigurationImpl.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/configuration/RepositoryConfigurationImpl.java Thu Dec 29 16:39:15 2011
@@ -27,28 +27,44 @@ import static java.text.MessageFormat.fo
public class RepositoryConfigurationImpl implements RepositoryConfiguration {
private final Map<String, String> parameters;
+ private final String microkernelUrl;
+ private final int nodeStateCacheSize;
- private RepositoryConfigurationImpl(Map<String, String> parameters) {
+ private RepositoryConfigurationImpl(Map<String, String> parameters) throws RepositoryException {
this.parameters = Collections.unmodifiableMap(parameters);
+
+ microkernelUrl = getParameterMap().get(MICROKERNEL_URL);
+ if (microkernelUrl == null) {
+ throw new RepositoryException(format("Missing configuration value for {0}", MICROKERNEL_URL));
+ }
+
+ String size = getParameterMap().get(NODE_STATE_CACHE_SIZE);
+ try {
+ nodeStateCacheSize = size == null ? 0 : Integer.parseInt(size);
+ }
+ catch (NumberFormatException e) {
+ throw new RepositoryException(format("Invalid configuration value {0} for {1}",
+ size, NODE_STATE_CACHE_SIZE), e);
+ }
+
}
- public static RepositoryConfiguration create(Map<String, String> parameters) {
+ public static RepositoryConfiguration create(Map<String, String> parameters) throws RepositoryException {
return new RepositoryConfigurationImpl(parameters);
}
@Override
- public Map<String, String> getParameterMap() {
+ public final Map<String, String> getParameterMap() {
return parameters;
}
@Override
public String getMicrokernelUrl() throws RepositoryException {
- String microkernelUrl = getParameterMap().get(RepositoryConfiguration.MICROKERNEL_URL);
- if (microkernelUrl == null) {
- throw new RepositoryException(
- format("Missing configuration value for {0}", RepositoryConfiguration.MICROKERNEL_URL));
- }
-
return microkernelUrl;
}
+
+ @Override
+ public int getNodeStateCacheSize() {
+ return nodeStateCacheSize;
+ }
}
Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/NodeState.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/NodeState.java?rev=1225586&r1=1225585&r2=1225586&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/NodeState.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/NodeState.java Thu Dec 29 16:39:15 2011
@@ -26,6 +26,7 @@ import org.apache.jackrabbit.json.JsonVa
import org.apache.jackrabbit.json.JsonValue.JsonObject;
import org.apache.jackrabbit.json.JsonValue.Type;
import org.apache.jackrabbit.json.UnescapingJsonTokenizer;
+import org.apache.jackrabbit.mk.api.MicroKernel;
import org.apache.jackrabbit.spi.commons.iterator.Iterators;
import org.apache.jackrabbit.spi.commons.iterator.Predicate;
import org.apache.jackrabbit.spi.commons.iterator.Transformer;
@@ -72,17 +73,19 @@ public class NodeState {
public NodeState addNode(String name) throws ItemExistsException {
NodeDelta child = nodeDelta.addNode(name);
- return new NodeState(sessionContext, child);
+ return getNodeState(sessionContext, child);
}
public void remove() throws ItemNotFoundException {
nodeDelta.remove();
+ nodeStateCache().remove(getPath());
}
public void move(String name, Path destination) throws ItemExistsException, PathNotFoundException,
ItemNotFoundException {
nodeDelta.moveNode(name, destination);
+ nodeStateCache().remove(getPath().concat(name));
}
public void setProperty(String name, JsonValue value) {
@@ -107,7 +110,7 @@ public class NodeState {
new Transformer<NodeDelta, NodeState>() {
@Override
public NodeState transform(NodeDelta delta) {
- return new NodeState(sessionContext, nodeDelta);
+ return getNodeState(sessionContext, nodeDelta);
}
});
@@ -157,15 +160,44 @@ public class NodeState {
public static NodeState getNodeState(Context sessionContext, Path path) {
NodeDelta delta = sessionContext.getTransientSpace().getNode(path);
- return delta == null ? null : new NodeState(sessionContext, delta);
+ return delta == null ? null : getNodeState(sessionContext, delta);
}
public static boolean hasNodeState(Context sessionContext, Path path) {
return getNodeState(sessionContext, path) != null;
}
+ @Override
+ public String toString() {
+ return getPath().toString();
+ }
+
//------------------------------------------< private >---
+ private NodeStateCache nodeStateCache() {
+ return sessionContext.getNodeStateCache();
+ }
+
+ private MicroKernel getMicrokernel() {
+ return sessionContext.getMicrokernel();
+ }
+
+ private String getBaseRevision() {
+ return sessionContext.getRevision();
+ }
+
+ private static NodeState getNodeState(Context sessionContext, NodeDelta nodeDelta) {
+ NodeStateCache cache = sessionContext.getNodeStateCache();
+ Path path = nodeDelta.getPath();
+
+ NodeState nodeState = cache.get(path);
+ if (nodeState == null) {
+ nodeState = new NodeState(sessionContext, nodeDelta);
+ cache.put(path, nodeState);
+ }
+ return nodeState;
+ }
+
private static final Predicate<Entry<String, JsonValue>> IS_NODE = new Predicate<Entry<String, JsonValue>>() {
@Override
public boolean evaluate(Entry<String, JsonValue> entry) {
@@ -185,7 +217,7 @@ public class NodeState {
return Iterators.transformIterator(nodeEntries, new Transformer<Entry<String, JsonValue>, NodeState>() {
@Override
public NodeState transform(Entry<String, JsonValue> entry) {
- return new NodeState(sessionContext, nodeDelta.getNode(entry.getKey()));
+ return getNodeState(sessionContext, nodeDelta.getNode(entry.getKey()));
}
});
}
@@ -225,14 +257,14 @@ public class NodeState {
private synchronized JsonObject getJsonObject() {
Path path = nodeDelta.getPersistentPath();
- String baseRevision = sessionContext.getRevision();
+ String baseRevision = getBaseRevision();
if (jsonObject == null || !revision.equals(baseRevision)) {
revision = baseRevision;
if (path == null) {
jsonObject = JsonObject.EMPTY;
}
else {
- String json = sessionContext.getMicrokernel().getNodes(nodeDelta.getPersistentPath().toMkPath(), revision);
+ String json = getMicrokernel().getNodes(nodeDelta.getPersistentPath().toMkPath(), revision);
jsonObject = FullJsonParser.parseObject(new UnescapingJsonTokenizer(json));
}
}
Added: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/NodeStateCache.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/NodeStateCache.java?rev=1225586&view=auto
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/NodeStateCache.java (added)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/NodeStateCache.java Thu Dec 29 16:39:15 2011
@@ -0,0 +1,10 @@
+package org.apache.jackrabbit.state;
+
+import org.apache.jackrabbit.Path;
+
+public interface NodeStateCache {
+ NodeState get(Path path);
+ void put(Path path, NodeState nodeState);
+ void remove(Path path);
+ void clear();
+}
Added: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/NodeStateCacheImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/NodeStateCacheImpl.java?rev=1225586&view=auto
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/NodeStateCacheImpl.java (added)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/NodeStateCacheImpl.java Thu Dec 29 16:39:15 2011
@@ -0,0 +1,61 @@
+package org.apache.jackrabbit.state;
+
+import org.apache.commons.collections.map.LRUMap;
+import org.apache.jackrabbit.CacheFactory;
+import org.apache.jackrabbit.Path;
+import org.apache.jackrabbit.configuration.RepositoryConfiguration;
+import org.apache.jackrabbit.utils.Unchecked;
+
+import java.util.Map;
+
+public class NodeStateCacheImpl implements NodeStateCache {
+ public static final CacheFactory FACTORY = new CacheFactory() {
+ @Override
+ public NodeStateCache create(RepositoryConfiguration configuration) {
+ int size = configuration.getNodeStateCacheSize();
+ return size > 0 ? new NodeStateCacheImpl(size) : NO_CACHE;
+ }
+ };
+
+ private static final NodeStateCache NO_CACHE = new NodeStateCache() {
+ @Override
+ public NodeState get(Path path) {
+ return null;
+ }
+
+ @Override
+ public void put(Path path, NodeState nodeState) { }
+
+ @Override
+ public void remove(Path path) { }
+
+ @Override
+ public void clear() { }
+ };
+
+ private final Map<Path, NodeState> cache;
+
+ public NodeStateCacheImpl(int size) {
+ cache = Unchecked.cast(new LRUMap(size));
+ }
+
+ @Override
+ public NodeState get(Path path) {
+ return cache.get(path);
+ }
+
+ @Override
+ public void put(Path path, NodeState nodeState) {
+ cache.put(path, nodeState);
+ }
+
+ @Override
+ public void remove(Path path) {
+ cache.remove(path);
+ }
+
+ @Override
+ public void clear() {
+ cache.clear();
+ }
+}
Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/test/java/org/apache/jackrabbit/RepositoryTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/test/java/org/apache/jackrabbit/RepositoryTest.java?rev=1225586&r1=1225585&r2=1225586&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/test/java/org/apache/jackrabbit/RepositoryTest.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/test/java/org/apache/jackrabbit/RepositoryTest.java Thu Dec 29 16:39:15 2011
@@ -59,7 +59,7 @@ import java.io.InputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
-import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@@ -80,6 +80,7 @@ import static org.junit.Assert.assertTru
import static org.junit.Assert.fail;
public class RepositoryTest {
+ private static final String NODE_STATE_CACHE_SIZE = "65536";
private static final String URL = "fs:target/repository-test/repository";
// private static final String URL = "mem:";
@@ -1692,8 +1693,10 @@ public class RepositoryTest {
Iterator<RepositoryFactory> factories = ServiceRegistry.lookupProviders(RepositoryFactory.class);
while (repository == null && factories.hasNext()) {
RepositoryFactory factory = factories.next();
- repository = factory.getRepository(Collections.singletonMap(
- RepositoryConfiguration.MICROKERNEL_URL, URL));
+ repository = factory.getRepository(new HashMap<String, String>() {{
+ put(RepositoryConfiguration.MICROKERNEL_URL, URL);
+ put(RepositoryConfiguration.NODE_STATE_CACHE_SIZE, NODE_STATE_CACHE_SIZE);
+ }});
}
}