Skip to content

Commit

Permalink
Merge branch '2.1-maint'
Browse files Browse the repository at this point in the history
Conflicts:
	community/kernel/src/test/java/org/neo4j/kernel/impl/nioneo/store/PersistenceWindowPoolRaceTestIT.java
  • Loading branch information
digitalstain committed Sep 29, 2014
2 parents e346df6 + b602940 commit c16b310
Show file tree
Hide file tree
Showing 12 changed files with 228 additions and 221 deletions.
18 changes: 18 additions & 0 deletions community/kernel/CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,24 @@ o Resolves a recovery issue, where multiple crashes in a row without clean shutd
o BatchImporter properly zeroes out reused buffers, ensuring relationship record backpoints are properly
setup during migration

1.9.9
-----
o Fixes issue in ReferenceCache which could lead to excessive
memory usage
o Fixes potential ommission of relationships of a node when
transactions that affect them are rolled back
o Fixes potential lock leak issue with the Lock Manager
component
o Store files now no longer expand beyond what's necessary
during shutdown and no longer contain spans of zeroe'd
records
o Solves issue with excessive number of Remove commands in
the lucene logs, caused by having auto indexing enabled
and changing properties
o Auto indexing no longer attempts to remove properties that
have been removed from the configuration as candidates for
autoindexing

2.1.0
-----
o Fixes potential leak of transaction state in entity locks that could
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,20 +61,23 @@ public void propertyAdded( T primitive, String propertyName,
public void propertyChanged( T primitive, String propertyName,
Object oldValue, Object newValue )
{
if ( oldValue != null )
{
getIndexInternal().remove( primitive, propertyName, oldValue );
}
if ( propertyKeysToInclude.contains( propertyName ) )
{
if ( oldValue != null )
{
getIndexInternal().remove( primitive, propertyName, oldValue );
}
getIndexInternal().add( primitive, propertyName, newValue );
}
}

public void propertyRemoved( T primitive, String propertyName,
Object propertyValue )
{
getIndexInternal().remove( primitive, propertyName );
if ( propertyKeysToInclude.contains( propertyName ) )
{
getIndexInternal().remove( primitive, propertyName );
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/**
* Copyright (c) 2002-2014 "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 org.neo4j.graphdb.Node;
import org.neo4j.kernel.configuration.Config;
import org.neo4j.kernel.impl.core.NodeManager;
import org.neo4j.kernel.impl.coreapi.IndexManagerImpl;
import org.neo4j.kernel.impl.coreapi.NodeAutoIndexerImpl;
import org.junit.Test;

import static org.mockito.Mockito.RETURNS_MOCKS;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verifyZeroInteractions;

public class NodeAutoIndexerImplTest
{
@Test
public void shouldNotRemoveFromIndexForNonAutoIndexedProperty() throws Exception
{
// Given
String indexedPropertyName = "someProperty";
String nonIndexedPropertyName = "someOtherProperty";

IndexManagerImpl indexManager = mock( IndexManagerImpl.class, RETURNS_MOCKS );
NodeAutoIndexerImpl index = new NodeAutoIndexerImpl( mock( Config.class ), indexManager,
mock( NodeManager.class ) );
index.startAutoIndexingProperty( indexedPropertyName );

// When
index.propertyRemoved( mock( Node.class ), nonIndexedPropertyName, new Object() );

// Then
verifyZeroInteractions( indexManager );
}

@Test
public void shouldNotAddToIndexForNonAutoIndexedProperty() throws Exception
{
// Given
String indexedPropertyName = "someProperty";
String nonIndexedPropertyName = "someOtherProperty";

IndexManagerImpl indexManager = mock( IndexManagerImpl.class, RETURNS_MOCKS );
NodeAutoIndexerImpl index = new NodeAutoIndexerImpl( mock( Config.class ), indexManager,
mock( NodeManager.class ) );
index.startAutoIndexingProperty( indexedPropertyName );

// When
index.propertyAdded( mock( Node.class ), nonIndexedPropertyName, new Object() );

// Then
verifyZeroInteractions( indexManager );
}

@Test
public void shouldNotAddOrRemoveFromIndexForNonAutoIndexedProperty() throws Exception
{
// Given
String indexedPropertyName = "someProperty";
String nonIndexedPropertyName = "someOtherProperty";

IndexManagerImpl indexManager = mock( IndexManagerImpl.class, RETURNS_MOCKS );
NodeAutoIndexerImpl index = new NodeAutoIndexerImpl( mock( Config.class ), indexManager,
mock( NodeManager.class ) );
index.startAutoIndexingProperty( indexedPropertyName );

// When
index.propertyChanged( mock( Node.class ), nonIndexedPropertyName, new Object(), new Object() );

// Then
verifyZeroInteractions( indexManager );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,13 @@
*/
package org.neo4j.kernel.lifecycle;

import static org.junit.Assert.assertEquals;

import java.util.LinkedList;
import java.util.List;

import org.neo4j.kernel.impl.util.StringLogger;
import org.junit.Assert;
import org.junit.Test;
import org.neo4j.kernel.impl.util.StringLogger;

import static org.junit.Assert.assertEquals;

/**
* Test LifeSupport lifecycle transitions
Expand Down Expand Up @@ -158,8 +157,6 @@ public void testFailingStartAndFailingStop()
assertEquals( startThrowable, throwable.getCause().getCause().getCause() );
}

lifeSupport.dump( StringLogger.DEV_NULL );

assertEquals( LifecycleStatus.STOPPED, lifeSupport.getStatus() );
assertEquals( LifecycleStatus.STOPPED , instance1.getStatus());
assertEquals( LifecycleStatus.STOPPED , instance2.getStatus() );
Expand Down
20 changes: 3 additions & 17 deletions community/lucene-index/src/docs/dev/index.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -499,21 +499,7 @@ the final configuration is the same regardless of the method used to reach it.

[[auto-indexing-update-removal]]
=== Updating the Automatic Index ===
Updates to the auto indexed properties happen of course automatically as you update them. Removal of properties from the auto index happens for two reasons.
One is that you actually removed the property. The other is that you stopped autoindexing on a property. When the latter happens, any primitive you touch and
it has that property, it is removed from the auto index, regardless of any operations on the property.
When you start or stop auto indexing on a property, no auto update operation happens currently. If you need to change the set of auto indexed properties and
have them re-indexed, you currently have to do this by hand. An example will illustrate the above better:

[snippet,java]
----
component=neo4j-lucene-index
source=examples/AutoIndexerExampleTests.java
tag=Mutations
classifier=test-sources
----

[CAUTION]
If you start the database with auto indexing enabled but different auto indexed properties than the last run, then already auto-indexed properties will be deleted from the index when a value is written to them (assuming the property isn't present in the new configuration).
Make sure that the monitored set is what you want before enabling the functionality.
Updates to the auto indexed properties happen of course automatically as you update them. Removal of properties from the auto index similarly
happens when you remove the actual property, but only while the property is auto indexed. In particular, if you had configured your database
to auto index a property, but later removed it from the configuration, deleting that property will not remove it from the auto index.

Original file line number Diff line number Diff line change
Expand Up @@ -207,89 +207,6 @@ public void testAPI() throws Exception
graphDb.shutdown();
}

@Test
public void testMutations() throws Exception
{
String storeDirectory = getStoreDir( "mutations" );
// START SNIPPET: Mutations
/*
* Creating the configuration
*/
GraphDatabaseService graphDb = new GraphDatabaseFactory().
newEmbeddedDatabaseBuilder( storeDirectory ).
setConfig( GraphDatabaseSettings.node_keys_indexable, "nodeProp1,nodeProp2" ).
setConfig( GraphDatabaseSettings.node_auto_indexing, "true" ).
newGraphDatabase();

Node node1 = null, node2 = null, node3 = null, node4 = null;
try ( Transaction tx = graphDb.beginTx() )
{
// Create the primitives
node1 = graphDb.createNode();
node2 = graphDb.createNode();
node3 = graphDb.createNode();
node4 = graphDb.createNode();

// Add indexable and non-indexable properties
node1.setProperty( "nodeProp1", "nodeProp1Value" );
node2.setProperty( "nodeProp2", "nodeProp2Value" );
node3.setProperty( "nodeProp1", "nodeProp3Value" );
node4.setProperty( "nodeProp2", "nodeProp4Value" );

// Make things persistent
tx.success();
}

/*
* Here both nodes are indexed. To demonstrate removal, we stop
* autoindexing nodeProp1.
*/
AutoIndexer<Node> nodeAutoIndexer = graphDb.index().getNodeAutoIndexer();
nodeAutoIndexer.stopAutoIndexingProperty( "nodeProp1" );

try ( Transaction tx = graphDb.beginTx() )
{
/*
* nodeProp1 is no longer auto indexed. It will be
* removed regardless. Note that node3 will remain.
*/
node1.setProperty( "nodeProp1", "nodeProp1Value2" );
/*
* node2 will be auto updated
*/
node2.setProperty( "nodeProp2", "nodeProp2Value2" );
/*
* remove node4 property nodeProp2 from index.
*/
node4.removeProperty( "nodeProp2" );
// Make things persistent
tx.success();
}

try ( Transaction tx = graphDb.beginTx() )
{
// Verify
ReadableIndex<Node> nodeAutoIndex = nodeAutoIndexer.getAutoIndex();
// node1 is completely gone
assertFalse( nodeAutoIndex.get( "nodeProp1", "nodeProp1Value" ).hasNext() );
assertFalse( nodeAutoIndex.get( "nodeProp1", "nodeProp1Value2" ).hasNext() );
// node2 is updated
assertFalse( nodeAutoIndex.get( "nodeProp2", "nodeProp2Value" ).hasNext() );
assertEquals( node2,
nodeAutoIndex.get( "nodeProp2", "nodeProp2Value2" ).getSingle() );
/*
* node3 is still there, despite its nodeProp1 property not being monitored
* any more because it was not touched, in contrast with node1.
*/
assertEquals( node3,
nodeAutoIndex.get( "nodeProp1", "nodeProp3Value" ).getSingle() );
// Finally, node4 is removed because the property was removed.
assertFalse( nodeAutoIndex.get( "nodeProp2", "nodeProp4Value" ).hasNext() );
}
// END SNIPPET: Mutations
graphDb.shutdown();
}

@Test
@Graph( autoIndexNodes = true,
autoIndexRelationships = true,
Expand Down
Loading

0 comments on commit c16b310

Please sign in to comment.