Skip to content

Commit

Permalink
Uniqueness constraint verification moved in LuceneSchemaIndex
Browse files Browse the repository at this point in the history
Verification of uniqueness constraint happens inside IndexPopulationJob after
all nodes are indexed and present in lucene the corresponding lucene index.
Currently verification logic is exposed by IndexReader interface which is used
by IndexPopulator to actually perform the validation. This is a temporary state
and was introduces while moving schema indexes to partitioned lucene
infrastructure.

This commit moves methods for uniqueness constraint verification from
IndexReader to LuceneSchemaIndex where they actually belong. It also
introduces UniquenessVerifier interface with two implementations -
SimpleUniquenessVerifier and PartitionedUniquenessVerifier that contain actual
verification logic and use lucene API. Later verifier is not yet implemented.
  • Loading branch information
lutovich authored and MishaDemianenko committed Jan 21, 2016
1 parent 6dbabfc commit 1efd647
Show file tree
Hide file tree
Showing 13 changed files with 281 additions and 202 deletions.
Expand Up @@ -33,7 +33,6 @@
import org.neo4j.collection.primitive.PrimitiveLongIterator; import org.neo4j.collection.primitive.PrimitiveLongIterator;
import org.neo4j.graphdb.ResourceIterator; import org.neo4j.graphdb.ResourceIterator;
import org.neo4j.helpers.collection.MapUtil; import org.neo4j.helpers.collection.MapUtil;
import org.neo4j.storageengine.api.schema.BoundedIterable;
import org.neo4j.kernel.api.index.IndexAccessor; import org.neo4j.kernel.api.index.IndexAccessor;
import org.neo4j.kernel.api.index.IndexUpdater; import org.neo4j.kernel.api.index.IndexUpdater;
import org.neo4j.kernel.api.index.SchemaIndexProvider.Descriptor; import org.neo4j.kernel.api.index.SchemaIndexProvider.Descriptor;
Expand All @@ -45,6 +44,7 @@
import org.neo4j.legacy.consistency.checking.CheckerEngine; import org.neo4j.legacy.consistency.checking.CheckerEngine;
import org.neo4j.legacy.consistency.checking.index.IndexAccessors; import org.neo4j.legacy.consistency.checking.index.IndexAccessors;
import org.neo4j.legacy.consistency.report.ConsistencyReport; import org.neo4j.legacy.consistency.report.ConsistencyReport;
import org.neo4j.storageengine.api.schema.BoundedIterable;
import org.neo4j.storageengine.api.schema.IndexReader; import org.neo4j.storageengine.api.schema.IndexReader;
import org.neo4j.storageengine.api.schema.IndexSampler; import org.neo4j.storageengine.api.schema.IndexSampler;


Expand Down Expand Up @@ -277,19 +277,6 @@ public IndexSampler createSampler()
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }


@Override
public void verifyDeferredConstraints( Object accessor, int propertyKeyId )
throws Exception
{
}

@Override
public void verifyDeferredConstraints( Object accessor, int propertyKeyId,
List<Object> updatedPropertyValues ) throws Exception
{
}

@Override
public void close() public void close()
{ {
} }
Expand Down
Expand Up @@ -36,7 +36,6 @@
import org.neo4j.consistency.report.ConsistencyReport; import org.neo4j.consistency.report.ConsistencyReport;
import org.neo4j.graphdb.ResourceIterator; import org.neo4j.graphdb.ResourceIterator;
import org.neo4j.helpers.collection.MapUtil; import org.neo4j.helpers.collection.MapUtil;
import org.neo4j.storageengine.api.schema.BoundedIterable;
import org.neo4j.kernel.api.index.IndexAccessor; import org.neo4j.kernel.api.index.IndexAccessor;
import org.neo4j.kernel.api.index.IndexUpdater; import org.neo4j.kernel.api.index.IndexUpdater;
import org.neo4j.kernel.api.index.SchemaIndexProvider.Descriptor; import org.neo4j.kernel.api.index.SchemaIndexProvider.Descriptor;
Expand All @@ -45,6 +44,7 @@
import org.neo4j.kernel.impl.store.record.IndexRule; import org.neo4j.kernel.impl.store.record.IndexRule;
import org.neo4j.kernel.impl.store.record.NodeRecord; import org.neo4j.kernel.impl.store.record.NodeRecord;
import org.neo4j.kernel.impl.store.record.PropertyBlock; import org.neo4j.kernel.impl.store.record.PropertyBlock;
import org.neo4j.storageengine.api.schema.BoundedIterable;
import org.neo4j.storageengine.api.schema.IndexReader; import org.neo4j.storageengine.api.schema.IndexReader;
import org.neo4j.storageengine.api.schema.IndexSampler; import org.neo4j.storageengine.api.schema.IndexSampler;


Expand Down Expand Up @@ -277,19 +277,6 @@ public IndexSampler createSampler()
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }


@Override
public void verifyDeferredConstraints( Object accessor, int propertyKeyId )
throws Exception
{
}

@Override
public void verifyDeferredConstraints( Object accessor, int propertyKeyId,
List<Object> updatedPropertyValues ) throws Exception
{
}

@Override
public void close() public void close()
{ {
} }
Expand Down
Expand Up @@ -19,8 +19,6 @@
*/ */
package org.neo4j.kernel.api.index; package org.neo4j.kernel.api.index;


import java.util.List;

import org.neo4j.collection.primitive.PrimitiveLongIterator; import org.neo4j.collection.primitive.PrimitiveLongIterator;
import org.neo4j.storageengine.api.schema.IndexReader; import org.neo4j.storageengine.api.schema.IndexReader;
import org.neo4j.storageengine.api.schema.IndexSampler; import org.neo4j.storageengine.api.schema.IndexSampler;
Expand Down Expand Up @@ -76,20 +74,6 @@ public IndexSampler createSampler()
{ {
return delegate.createSampler(); return delegate.createSampler();
} }

@Override
public void verifyDeferredConstraints( Object accessor, int propertyKeyId )
throws Exception
{
delegate.verifyDeferredConstraints( accessor, propertyKeyId );
}

@Override
public void verifyDeferredConstraints( Object accessor, int propertyKeyId, List<Object> updatedPropertyValues )
throws Exception
{
delegate.verifyDeferredConstraints( accessor, propertyKeyId, updatedPropertyValues );
}


@Override @Override
public void close() public void close()
Expand Down
Expand Up @@ -19,7 +19,6 @@
*/ */
package org.neo4j.storageengine.api.schema; package org.neo4j.storageengine.api.schema;


import java.util.List;


import org.neo4j.collection.primitive.PrimitiveLongCollections; import org.neo4j.collection.primitive.PrimitiveLongCollections;
import org.neo4j.collection.primitive.PrimitiveLongIterator; import org.neo4j.collection.primitive.PrimitiveLongIterator;
Expand Down Expand Up @@ -84,13 +83,6 @@ public interface IndexReader extends Resource


IndexSampler createSampler(); IndexSampler createSampler();


//TODO:

void verifyDeferredConstraints( Object accessor, int propertyKeyId ) throws Exception;

void verifyDeferredConstraints( Object accessor, int propertyKeyId, List<Object> updatedPropertyValues )
throws Exception;

IndexReader EMPTY = new IndexReader() IndexReader EMPTY = new IndexReader()
{ {
@Override @Override
Expand Down Expand Up @@ -136,18 +128,6 @@ public IndexSampler createSampler()
{ {
return IndexSampler.EMPTY; return IndexSampler.EMPTY;
} }

@Override
public void verifyDeferredConstraints( Object accessor, int propertyKeyId )
throws Exception
{
}

@Override
public void verifyDeferredConstraints( Object accessor, int propertyKeyId,
List<Object> updatedPropertyValues ) throws Exception
{
}


@Override @Override
public void close() public void close()
Expand Down
Expand Up @@ -22,7 +22,6 @@
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
Expand Down Expand Up @@ -249,17 +248,4 @@ public IndexSampler createSampler()
{ {
return new HashBasedIndexSampler( data ); return new HashBasedIndexSampler( data );
} }

@Override
public void verifyDeferredConstraints( Object accessor, int propertyKeyId ) throws Exception
{
// TODO:
}

@Override
public void verifyDeferredConstraints( Object accessor, int propertyKeyId, List<Object> updatedPropertyValues )
throws Exception
{
// TODO:
}
} }
Expand Up @@ -28,12 +28,17 @@
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;


import org.neo4j.helpers.TaskCoordinator; import org.neo4j.helpers.TaskCoordinator;
import org.neo4j.kernel.api.exceptions.index.IndexEntryConflictException;
import org.neo4j.kernel.api.impl.index.partition.IndexPartition; import org.neo4j.kernel.api.impl.index.partition.IndexPartition;
import org.neo4j.kernel.api.impl.index.partition.PartitionSearcher; import org.neo4j.kernel.api.impl.index.partition.PartitionSearcher;
import org.neo4j.kernel.api.impl.index.reader.PartitionedIndexReader; import org.neo4j.kernel.api.impl.index.reader.PartitionedIndexReader;
import org.neo4j.kernel.api.impl.index.reader.SimpleIndexReader; import org.neo4j.kernel.api.impl.index.reader.SimpleIndexReader;
import org.neo4j.kernel.api.impl.index.storage.PartitionedIndexStorage; import org.neo4j.kernel.api.impl.index.storage.PartitionedIndexStorage;
import org.neo4j.kernel.api.impl.index.verification.PartitionedUniquenessVerifier;
import org.neo4j.kernel.api.impl.index.verification.SimpleUniquenessVerifier;
import org.neo4j.kernel.api.impl.index.verification.UniquenessVerifier;
import org.neo4j.kernel.api.index.IndexConfiguration; import org.neo4j.kernel.api.index.IndexConfiguration;
import org.neo4j.kernel.api.index.PropertyAccessor;
import org.neo4j.kernel.impl.api.index.sampling.IndexSamplingConfig; import org.neo4j.kernel.impl.api.index.sampling.IndexSamplingConfig;
import org.neo4j.storageengine.api.schema.IndexReader; import org.neo4j.storageengine.api.schema.IndexReader;


Expand Down Expand Up @@ -80,25 +85,71 @@ public IndexReader getIndexReader() throws IOException
} }
} }


public void verifyUniqueness( PropertyAccessor accessor, int propertyKeyId )
throws IOException, IndexEntryConflictException
{
try ( UniquenessVerifier verifier = createUniquenessVerifier() )
{
verifier.verify( accessor, propertyKeyId );
}
}

public void verifyUniqueness( PropertyAccessor accessor, int propertyKeyId, List<Object> updatedPropertyValues )
throws IOException, IndexEntryConflictException
{
try ( UniquenessVerifier verifier = createUniquenessVerifier() )
{
verifier.verify( accessor, propertyKeyId, updatedPropertyValues );
}
}

private UniquenessVerifier createUniquenessVerifier() throws IOException
{
ensureOpen();
maybeRefresh();
List<IndexPartition> partitions = getPartitions();
return hasSinglePartition( partitions ) ? createSimpleUniquenessVerifier( partitions )
: createPartitionedUniquenessVerifier( partitions );
}

private boolean hasSinglePartition( List<IndexPartition> partitions ) private boolean hasSinglePartition( List<IndexPartition> partitions )
{ {
return partitions.size() == 1; return partitions.size() == 1;
} }


private SimpleIndexReader createSimpleReader( List<IndexPartition> partitions ) throws IOException private SimpleIndexReader createSimpleReader( List<IndexPartition> partitions ) throws IOException
{ {
return new SimpleIndexReader( partitions.get( 0 ).acquireSearcher(), config, IndexPartition singlePartition = partitions.get( 0 );
samplingConfig, taskCoordinator ); return new SimpleIndexReader( singlePartition.acquireSearcher(), config, samplingConfig, taskCoordinator );
} }


private PartitionedIndexReader createPartitionedReader( List<IndexPartition> partitions ) throws IOException private PartitionedIndexReader createPartitionedReader( List<IndexPartition> partitions ) throws IOException
{ {
List<PartitionSearcher> searchers = new ArrayList<>(); List<PartitionSearcher> searchers = acquireSearchers( partitions );
return new PartitionedIndexReader( searchers );
}

private UniquenessVerifier createSimpleUniquenessVerifier( List<IndexPartition> partitions ) throws IOException
{
IndexPartition singlePartition = partitions.get( 0 );
PartitionSearcher partitionSearcher = singlePartition.acquireSearcher();
return new SimpleUniquenessVerifier( partitionSearcher );
}

private UniquenessVerifier createPartitionedUniquenessVerifier( List<IndexPartition> partitions ) throws IOException
{
List<PartitionSearcher> searchers = acquireSearchers( partitions );
return new PartitionedUniquenessVerifier( searchers );
}

private static List<PartitionSearcher> acquireSearchers( List<IndexPartition> partitions ) throws IOException
{
List<PartitionSearcher> searchers = new ArrayList<>( partitions.size() );
for ( IndexPartition partition : partitions ) for ( IndexPartition partition : partitions )
{ {
searchers.add( partition.acquireSearcher() ); searchers.add( partition.acquireSearcher() );
} }
return new PartitionedIndexReader( searchers ); return searchers;
} }


@Override @Override
Expand Down
Expand Up @@ -34,7 +34,6 @@
import org.neo4j.kernel.api.index.PropertyAccessor; import org.neo4j.kernel.api.index.PropertyAccessor;
import org.neo4j.kernel.impl.api.index.sampling.UniqueIndexSampler; import org.neo4j.kernel.impl.api.index.sampling.UniqueIndexSampler;
import org.neo4j.register.Register.DoubleLong; import org.neo4j.register.Register.DoubleLong;
import org.neo4j.storageengine.api.schema.IndexReader;


public class DeferredConstraintVerificationUniqueLuceneIndexPopulator extends LuceneIndexPopulator public class DeferredConstraintVerificationUniqueLuceneIndexPopulator extends LuceneIndexPopulator
{ {
Expand Down Expand Up @@ -72,18 +71,7 @@ public void add( long nodeId, Object propertyValue )
@Override @Override
public void verifyDeferredConstraints( PropertyAccessor accessor ) throws IndexEntryConflictException, IOException public void verifyDeferredConstraints( PropertyAccessor accessor ) throws IndexEntryConflictException, IOException
{ {
luceneIndex.maybeRefresh(); luceneIndex.verifyUniqueness( accessor, descriptor.getPropertyKeyId() );
IndexReader indexReader;
try
{
indexReader = luceneIndex.getIndexReader();
indexReader.verifyDeferredConstraints(accessor, descriptor.getPropertyKeyId());
}
catch ( Exception e )
{
throw new IOException( e );
}
indexReader.close();
} }


@Override @Override
Expand Down Expand Up @@ -128,16 +116,7 @@ public void process( NodePropertyUpdate update ) throws IOException, IndexEntryC
@Override @Override
public void close() throws IOException, IndexEntryConflictException public void close() throws IOException, IndexEntryConflictException
{ {
luceneIndex.maybeRefresh(); luceneIndex.verifyUniqueness( accessor, descriptor.getPropertyKeyId(), updatedPropertyValues );
try ( IndexReader indexReader = luceneIndex.getIndexReader() )
{
indexReader.verifyDeferredConstraints( accessor, descriptor.getPropertyKeyId(),
updatedPropertyValues );
}
catch ( Exception e )
{
throw new IOException( e );
}
} }


@Override @Override
Expand Down
Expand Up @@ -84,22 +84,7 @@ public IndexSampler createSampler()
{ {
return null; return null;
} }


@Override
public void verifyDeferredConstraints( Object accessor, int propertyKeyId )
throws Exception
{

}

@Override
public void verifyDeferredConstraints( Object accessor, int propertyKeyId,
List<Object> updatedPropertyValues ) throws Exception
{

}

@Override
public void close() public void close()
{ {
try try
Expand Down

0 comments on commit 1efd647

Please sign in to comment.