Permalink
Browse files

Fixed Neo4j SPI changes, works now with 1.8.0, 1.8.1 and 1.9.M04

- locking, added indirection Helper class with different implementations for 1.8 and 1.9, used reflection for 1.8 (LockReleaser is gone, LockManager changed type)
- SPI changes for TimelineIndexProvider: IndexProvider -> KernelExtensionFactory
  • Loading branch information...
1 parent ce39c8f commit fbe93c8dd6376eaa5c93fb43fc048c3980eb271c @jexp jexp committed Feb 4, 2013
View
@@ -1,3 +1,4 @@
+.idea
*.iml
*.ipr
*.iws
View
@@ -3,9 +3,9 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
- <artifactId>parent-pom</artifactId>
+ <artifactId>parent-central</artifactId>
<groupId>org.neo4j.build</groupId>
- <version>35</version>
+ <version>36</version>
</parent>
<groupId>org.neo4j</groupId>
@@ -18,7 +18,7 @@
<properties>
<bundle.namespace>org.neo4j.collections</bundle.namespace>
<short-name>collections</short-name>
- <neo4j.version>1.8.1</neo4j.version>
+ <neo4j.version>1.9.M04</neo4j.version>
<license-text.header>GPL-3-header.txt</license-text.header>
</properties>
@@ -53,11 +53,13 @@
<groupId>org.neo4j</groupId>
<artifactId>neo4j</artifactId>
<version>${neo4j.version}</version>
+ <scope>provided</scope>
</dependency>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-lucene-index</artifactId>
<version>${neo4j.version}</version>
+ <scope>provided</scope>
</dependency>
<dependency>
<groupId>org.neo4j</groupId>
@@ -0,0 +1,75 @@
+/**
+ * Copyright (c) 2002-2013 "Neo Technology,"
+ * Network Engine for Objects in Lund AB [http://neotechnology.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.neo4j.collections.indexprovider;
+
+import org.neo4j.graphdb.GraphDatabaseService;
+import org.neo4j.graphdb.index.IndexProviders;
+import org.neo4j.kernel.extension.KernelExtensionFactory;
+import org.neo4j.kernel.lifecycle.Lifecycle;
+
+import static org.neo4j.collections.indexprovider.TimelineIndexProvider.TimelineIndexImplementation;
+
+public class TimelineIndexKernelExtensionFactory extends KernelExtensionFactory<TimelineIndexKernelExtensionFactory.Depencies> {
+
+ public TimelineIndexKernelExtensionFactory() {
+ super(TimelineIndexProvider.SERVICE_NAME);
+ }
+
+ @Override
+ public Lifecycle newKernelExtension(Depencies depencies) throws Throwable {
+ return new TimelineIndexKerneExtension(depencies.getGraphDatabaseService(), depencies.getIndexProviders());
+ }
+
+ public static interface Depencies {
+ IndexProviders getIndexProviders();
+
+ GraphDatabaseService getGraphDatabaseService();
+
+ }
+
+ public static class TimelineIndexKerneExtension implements Lifecycle {
+ private final GraphDatabaseService graphDatabaseService;
+ private final IndexProviders indexProviders;
+
+ public TimelineIndexKerneExtension(GraphDatabaseService graphDatabaseService, IndexProviders indexProviders) {
+ this.graphDatabaseService = graphDatabaseService;
+ this.indexProviders = indexProviders;
+ }
+
+ @Override
+ public void init() throws Throwable {
+ }
+
+ @Override
+ public void start() throws Throwable {
+ TimelineIndexImplementation indexImplementation = new TimelineIndexImplementation(graphDatabaseService);
+ indexProviders.registerIndexProvider(TimelineIndexProvider.SERVICE_NAME, indexImplementation);
+ }
+
+ @Override
+ public void stop() throws Throwable {
+ indexProviders.unregisterIndexProvider(TimelineIndexProvider.SERVICE_NAME);
+ }
+
+ @Override
+ public void shutdown() throws Throwable {
+ }
+ }
+}
@@ -1,5 +1,5 @@
/**
- * Copyright (c) 2002-2012 "Neo Technology,"
+ * Copyright (c) 2002-2013 "Neo Technology,"
* Network Engine for Objects in Lund AB [http://neotechnology.com]
*
* This file is part of Neo4j.
@@ -31,12 +31,9 @@
import org.neo4j.graphdb.index.IndexManager;
import org.neo4j.graphdb.index.IndexProvider;
import org.neo4j.graphdb.index.RelationshipIndex;
-import org.neo4j.helpers.Service;
import org.neo4j.helpers.collection.MapUtil;
-import org.neo4j.kernel.KernelExtension;
import org.neo4j.kernel.configuration.Config;
-@Service.Implementation( KernelExtension.class )
public class TimelineIndexProvider extends IndexProvider
{
@@ -54,7 +51,7 @@ public IndexImplementation load(DependencyResolver dependencyResolver) throws Ex
return new TimelineIndexImplementation(gds);
}
- private class TimelineIndexImplementation implements IndexImplementation
+ static class TimelineIndexImplementation implements IndexImplementation
{
private GraphDatabaseService db;
@@ -1,5 +1,5 @@
/**
- * Copyright (c) 2002-2012 "Neo Technology,"
+ * Copyright (c) 2002-2013 "Neo Technology,"
* Network Engine for Objects in Lund AB [http://neotechnology.com]
*
* This file is part of Neo4j.
@@ -27,13 +27,13 @@
import org.neo4j.collections.GraphCollection;
import org.neo4j.collections.NodeCollection;
-import org.neo4j.graphdb.Direction;
-import org.neo4j.graphdb.GraphDatabaseService;
-import org.neo4j.graphdb.Node;
-import org.neo4j.graphdb.Relationship;
-import org.neo4j.graphdb.RelationshipType;
-import org.neo4j.kernel.AbstractGraphDatabase;
+import org.neo4j.graphdb.*;
+import org.neo4j.kernel.GraphDatabaseAPI;
import org.neo4j.kernel.impl.transaction.LockType;
+import org.neo4j.kernel.impl.transaction.Locker;
+
+import javax.transaction.SystemException;
+import javax.transaction.TransactionManager;
/**
* Implementation of an UnrolledLinkedList for storage of nodes. This collection is primarily for use within an
@@ -65,6 +65,8 @@
*/
public class UnrolledLinkedList implements NodeCollection
{
+ private final Locker locker;
+
private static enum RelationshipTypes implements RelationshipType
{
NEXT_PAGE, HEAD
@@ -110,6 +112,7 @@ public int compare( Relationship o1, Relationship o2 )
{
throw new IllegalStateException( "Unable to re-instantiate UnrolledLinkedList from graph data structure.", e );
}
+ locker = Locker.getInstance(baseNode.getGraphDatabase());
}
/**
@@ -156,6 +159,7 @@ public int compare( Relationship o1, Relationship o2 )
};
this.pageSize = pageSize;
this.margin = margin;
+ locker = Locker.getInstance(graphDb);
}
@Override
@@ -499,18 +503,38 @@ private void moveValueRelationship( Relationship valueRelationship, Node targetP
private void acquireLock( LockType lockType )
{
- GraphDatabaseService graphDb = baseNode.getGraphDatabase();
- if ( lockType == LockType.READ && graphDb instanceof AbstractGraphDatabase )
+ locker.acquireLock(lockType, baseNode);
+ }
+
+ private void acquireLock(LockType lockType, PropertyContainer element) {
+ GraphDatabaseService graphDb = element.getGraphDatabase();
+ if ( lockType == LockType.READ)
{
- final AbstractGraphDatabase graphDatabase = (AbstractGraphDatabase) baseNode.getGraphDatabase();
- graphDatabase.getLockManager().getReadLock( baseNode );
- graphDatabase.getLockReleaser().addLockToTransaction( baseNode, LockType.READ );
+ Transaction tx = getCurrentTransaction(graphDb);
+ tx.acquireReadLock(element);
+ //graphDatabase.getLockManager().getReadLock( baseNode );
+ //graphDatabase.getLockReleaser().addLockToTransaction( baseNode, LockType.READ );
}
else
{
// default to write lock if read locks unavailable
- baseNode.removeProperty( "___dummy_property_to_acquire_lock___" );
+ element.removeProperty("___dummy_property_to_acquire_lock___");
+ }
+ }
+
+
+ private Transaction getCurrentTransaction(GraphDatabaseService graphDatabaseService) {
+ try {
+ if (graphDatabaseService instanceof GraphDatabaseAPI) {
+ GraphDatabaseAPI graphDatabaseAPI = (GraphDatabaseAPI) graphDatabaseService;
+ TransactionManager txManager = graphDatabaseAPI.getTxManager();
+ return (Transaction)txManager.getTransaction();
+
+ }
+ } catch (SystemException e) {
+ throw new RuntimeException("Error accessing current transaction",e);
}
+ throw new RuntimeException("Error accessing current transaction, not a GraphDatabaseAPI "+graphDatabaseService);
}
private static abstract class ItemIterator<T> implements Iterator<T>
@@ -0,0 +1,46 @@
+/**
+ * Copyright (c) 2002-2013 "Neo Technology,"
+ * Network Engine for Objects in Lund AB [http://neotechnology.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.neo4j.kernel.impl.transaction;
+
+import org.neo4j.graphdb.GraphDatabaseService;
+import org.neo4j.graphdb.PropertyContainer;
+
+import java.lang.reflect.InvocationTargetException;
+
+public abstract class Locker {
+ public static Locker getInstance(GraphDatabaseService graphDatabaseService) {
+ try {
+ return newLockerInstance("Neo4j19Locker", graphDatabaseService);
+ } catch (Exception e) {
+ // ignore
+ }
+ return newLockerInstance("Neo4j18Locker", graphDatabaseService);
+ }
+
+ private static Locker newLockerInstance(String subClass, GraphDatabaseService graphDatabaseService) {
+ try {
+ return (Locker)Class.forName("org.neo4j.kernel.impl.transaction." + subClass).getConstructor(GraphDatabaseService.class).newInstance(graphDatabaseService);
+ } catch (Exception e) {
+ throw new RuntimeException("Error creating Locker "+subClass,e);
+ }
+ }
+
+ public abstract void acquireLock(LockType lockType, PropertyContainer element);
+}
@@ -0,0 +1,68 @@
+package org.neo4j.kernel.impl.transaction;
+
+import org.neo4j.graphdb.GraphDatabaseService;
+import org.neo4j.graphdb.PropertyContainer;
+import org.neo4j.helpers.Pair;
+import org.neo4j.kernel.AbstractGraphDatabase;
+
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+import java.lang.reflect.Method;
+
+class Neo4j18Locker extends Locker {
+
+ private final Object lockManager;
+ private final Object lockReleaser;
+ private final TransactionManager txManager;
+
+ public Neo4j18Locker(GraphDatabaseService graphDatabaseService) {
+ if (!(graphDatabaseService instanceof AbstractGraphDatabase)) throw new RuntimeException("Error accessing transaction management, not a AbstractGraphDatabase " + graphDatabaseService);
+ final AbstractGraphDatabase graphDatabase = (AbstractGraphDatabase) graphDatabaseService;
+ lockManager = graphDatabase.getLockManager();
+ txManager = graphDatabase.getTxManager();
+ lockReleaser = invoke(graphDatabase,"getLockReleaser");
+ }
+
+ private Object invoke(Object target, String methodName,Pair<Class,?>...params) {
+ try {
+ Class[] types=new Class[params.length];
+ Object[] values=new Object[params.length];
+ for (int i = 0; i < params.length; i++) {
+ types[i] = params[i].first();
+ values[i] = params[i].other();
+ }
+ Method method = target.getClass().getMethod(methodName,types);
+ return method.invoke(target,values);
+ } catch(Exception e) {
+ System.out.println(target);
+ System.out.println(target.getClass());
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public void acquireLock(LockType lockType, PropertyContainer element) {
+ TransactionImpl tx = getCurrentTransaction();
+ switch (lockType) {
+ case READ:
+ invoke(lockManager, "getReadLock", Pair.<Class,Object>of(Object.class,element), Pair.<Class,Object>of(Transaction.class,tx));
+ invoke(lockReleaser, "addLockToTransaction", Pair.<Class,Object>of(Object.class,element),Pair.<Class,Object>of(LockType.class,LockType.READ), Pair.<Class,Object>of(Transaction.class,tx));
+ break;
+ case WRITE:
+ invoke(lockManager, "getWriteLock", Pair.<Class,Object>of(Object.class,element), Pair.<Class,Object>of(Transaction.class,tx));
+ invoke(lockReleaser, "addLockToTransaction", Pair.<Class,Object>of(Object.class,element),Pair.<Class,Object>of(LockType.class,LockType.WRITE), Pair.<Class,Object>of(Transaction.class,tx));
+ break;
+ default: throw new IllegalStateException("Unknown lock type "+lockType);
+ }
+ }
+
+ private TransactionImpl getCurrentTransaction() {
+ try {
+ return (TransactionImpl) txManager.getTransaction();
+ } catch (SystemException e) {
+ throw new RuntimeException("Error accessing current transaction", e);
+ }
+}
+
+}
Oops, something went wrong.

0 comments on commit fbe93c8

Please sign in to comment.