Skip to content

Commit

Permalink
Merge branch 'master' of github.com:neo4j/community
Browse files Browse the repository at this point in the history
  • Loading branch information
jakewins committed May 26, 2011
2 parents cc734d6 + d58d59b commit 8bd63cf
Show file tree
Hide file tree
Showing 14 changed files with 691 additions and 37 deletions.
4 changes: 4 additions & 0 deletions graph-algo/CHANGES.txt
@@ -1,3 +1,7 @@
1.4.M03 (2011-05-26)
--------------------
o No Changes.

1.3.M05 (2011-03-24)
--------------------
o Fixed a bug regarding creation of invalid paths.
Expand Down
5 changes: 5 additions & 0 deletions jmx/CHANGES.txt
@@ -1,3 +1,8 @@
1.4.M03 (2011-05-25)
--------------------
o No changes.

--------------------
o Split up the management component in two, one ("jmx" - this component) with basic support and one ("management") with advanced support.

1.3.M05 (2011-03-24)
Expand Down
9 changes: 9 additions & 0 deletions kernel/CHANGES.txt
@@ -1,3 +1,12 @@
1.4.M03 (2011-05-26)
--------------------
o Kernel now supports self relationships or "loops".
o Added new relationship direction aware cache on nodes speeding up traversals by direction.
o Reduced memory usage by relationships.
o Reduced call stack removing the EventConsumer/ResourceConnection wrappers glue between nioneo and kernel.
o Fixed bug in global tx log that did not mark transactions finished when closed then crashed.
o Fixed cache invalidation when applying external transaction.

1.4.M02 (2011-05-12)
--------------------
o Changed the default implementation of the logical log to a DirectMappedLogBuffer.
Expand Down
Expand Up @@ -128,63 +128,63 @@ public RelationshipTypeData[] loadAllRelationshipTypes()

public ArrayMap<Integer,PropertyData> nodeDelete( long nodeId )
{
return getResource().nodeDelete( nodeId );
return getResource( true ).nodeDelete( nodeId );
}

public long nodeAddProperty( long nodeId, PropertyIndex index, Object value )
{
return getResource().nodeAddProperty( nodeId, index, value );
return getResource( true ).nodeAddProperty( nodeId, index, value );
}

public void nodeChangeProperty( long nodeId, long propertyId, Object value )
{
getResource().nodeChangeProperty( nodeId, propertyId, value );
getResource( true ).nodeChangeProperty( nodeId, propertyId, value );
}

public void nodeRemoveProperty( long nodeId, long propertyId )
{
getResource().nodeRemoveProperty( nodeId, propertyId );
getResource( true ).nodeRemoveProperty( nodeId, propertyId );
}

public void nodeCreate( long id )
{
getResource().nodeCreate( id );
getResource( true ).nodeCreate( id );
}

public void relationshipCreate( long id, int typeId, long startNodeId,
long endNodeId )
{
getResource().relationshipCreate( id, typeId, startNodeId, endNodeId );
getResource( true ).relationshipCreate( id, typeId, startNodeId, endNodeId );
}

public ArrayMap<Integer,PropertyData> relDelete( long relId )
{
return getResource().relDelete( relId );
return getResource( true ).relDelete( relId );
}

public long relAddProperty( long relId, PropertyIndex index, Object value )
{
return getResource().relAddProperty( relId, index, value );
return getResource( true ).relAddProperty( relId, index, value );
}

public void relChangeProperty( long relId, long propertyId, Object value )
{
getResource().relChangeProperty( relId, propertyId, value );
getResource( true ).relChangeProperty( relId, propertyId, value );
}

public void relRemoveProperty( long relId, long propertyId )
{
getResource().relRemoveProperty( relId, propertyId );
getResource( true ).relRemoveProperty( relId, propertyId );
}

public void createPropertyIndex( String key, int id )
{
getResource().createPropertyIndex( key, id );
getResource( true ).createPropertyIndex( key, id );
}

public void createRelationshipType( int id, String name )
{
getResource().createRelationshipType( id, name );
getResource( false ).createRelationshipType( id, name );
}

private NeoStoreTransaction getReadOnlyResource()
Expand All @@ -208,7 +208,7 @@ private NeoStoreTransaction getReadOnlyResource()
return con;
}

private NeoStoreTransaction getResource()
private NeoStoreTransaction getResource( boolean registerEventHooks )
{
NeoStoreTransaction con = null;

Expand All @@ -233,7 +233,7 @@ private NeoStoreTransaction getResource()
con = persistenceSource.createTransaction( xaConnection );

tx.registerSynchronization( new TxCommitHook( tx ) );
registerTransactionEventHookIfNeeded();
if ( registerEventHooks ) registerTransactionEventHookIfNeeded();
txConnectionMap.put( tx, con );
}
catch ( javax.transaction.RollbackException re )
Expand Down Expand Up @@ -359,17 +359,17 @@ void releaseResourceConnectionsForTransaction( Transaction tx )

public RelIdArray getCreatedNodes()
{
return getResource().getCreatedNodes();
return getResource( true ).getCreatedNodes();
}

public boolean isNodeCreated( long nodeId )
{
return getResource().isNodeCreated( nodeId );
return getResource( true ).isNodeCreated( nodeId );
}

public boolean isRelationshipCreated( long relId )
{
return getResource().isRelationshipCreated( relId );
return getResource( true ).isRelationshipCreated( relId );
}

public int getKeyIdForProperty( long propertyId )
Expand Down
@@ -0,0 +1,105 @@
/**
* Copyright (c) 2002-2011 "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;

import static org.junit.Assert.assertEquals;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.neo4j.graphdb.DynamicRelationshipType;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Transaction;
import org.neo4j.graphdb.event.TransactionData;
import org.neo4j.graphdb.event.TransactionEventHandler;
import org.neo4j.test.TargetDirectory;

public class TestTransactionEventDeadlocks
{
public TargetDirectory target = TargetDirectory.forTest( getClass() );
private EmbeddedGraphDatabase graphdb;

@Before
public void startGraphdb()
{
this.graphdb = new EmbeddedGraphDatabase( target.graphDbDir( true ).getPath() );
}

@After
public void stopGraphdb()
{
if ( graphdb != null ) graphdb.shutdown();
graphdb = null;
}

@Test
public void canAvoidDeadlockThatWouldHappenIfTheRelationshipTypeCreationTransactionModifiedData() throws Exception
{
final Node root = graphdb.getReferenceNode();
Transaction tx = graphdb.beginTx();
try
{
root.setProperty( "counter", Long.valueOf( 0L ) );
tx.success();
}
finally
{
tx.finish();
}

graphdb.registerTransactionEventHandler( new TransactionEventHandler<Void>()
{
@SuppressWarnings( "boxing" )
@Override
public Void beforeCommit( TransactionData data ) throws Exception
{
root.setProperty( "counter", ( (Long) root.removeProperty( "counter" ) ) + 1 );
return null;
}

@Override
public void afterCommit( TransactionData data, Void state )
{
// nothing
}

@Override
public void afterRollback( TransactionData data, Void state )
{
// nothing
}
} );

tx = graphdb.beginTx();
try
{
root.setProperty( "state", "not broken yet" );
root.createRelationshipTo( graphdb.createNode(), DynamicRelationshipType.withName( "TEST" ) );
root.removeProperty( "state" );
tx.success();
}
finally
{
tx.finish();
}

assertEquals( 1L, root.getProperty( "counter" ) );
}
}

0 comments on commit 8bd63cf

Please sign in to comment.