From f0a1406468c61269d7ac56fd62b5affede1ff7e4 Mon Sep 17 00:00:00 2001 From: Anton Persson Date: Fri, 5 Jan 2018 14:14:33 +0100 Subject: [PATCH] GBPTreeConcurrencyIT is generic in --- .../GBPTreeConcurrencyFIxedSizeIT.java | 33 ++++++++ ...yIT.java => GBPTreeConcurrencyITBase.java} | 75 +++++++++++-------- 2 files changed, 76 insertions(+), 32 deletions(-) create mode 100644 community/index/src/test/java/org/neo4j/index/internal/gbptree/GBPTreeConcurrencyFIxedSizeIT.java rename community/index/src/test/java/org/neo4j/index/internal/gbptree/{GBPTreeConcurrencyIT.java => GBPTreeConcurrencyITBase.java} (91%) diff --git a/community/index/src/test/java/org/neo4j/index/internal/gbptree/GBPTreeConcurrencyFIxedSizeIT.java b/community/index/src/test/java/org/neo4j/index/internal/gbptree/GBPTreeConcurrencyFIxedSizeIT.java new file mode 100644 index 0000000000000..5606c70082e1c --- /dev/null +++ b/community/index/src/test/java/org/neo4j/index/internal/gbptree/GBPTreeConcurrencyFIxedSizeIT.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2002-2018 "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 . + */ +package org.neo4j.index.internal.gbptree; + +import org.apache.commons.lang3.mutable.MutableLong; + +import org.neo4j.test.rule.RandomRule; + +public class GBPTreeConcurrencyFIxedSizeIT extends GBPTreeConcurrencyITBase +{ + @Override + protected TestLayout getLayout( RandomRule random ) + { + return new SimpleLongLayout( random.intBetween( 0, 10 ) ); + } +} diff --git a/community/index/src/test/java/org/neo4j/index/internal/gbptree/GBPTreeConcurrencyIT.java b/community/index/src/test/java/org/neo4j/index/internal/gbptree/GBPTreeConcurrencyITBase.java similarity index 91% rename from community/index/src/test/java/org/neo4j/index/internal/gbptree/GBPTreeConcurrencyIT.java rename to community/index/src/test/java/org/neo4j/index/internal/gbptree/GBPTreeConcurrencyITBase.java index 4a21ff4a20b7a..a2ef7831ae4e2 100644 --- a/community/index/src/test/java/org/neo4j/index/internal/gbptree/GBPTreeConcurrencyIT.java +++ b/community/index/src/test/java/org/neo4j/index/internal/gbptree/GBPTreeConcurrencyITBase.java @@ -19,7 +19,6 @@ */ package org.neo4j.index.internal.gbptree; -import org.apache.commons.lang3.mutable.MutableLong; import org.junit.After; import org.junit.Rule; import org.junit.Test; @@ -60,7 +59,6 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.junit.rules.RuleChain.outerRule; -import static org.neo4j.index.internal.gbptree.GBPTree.NO_MONITOR; import static org.neo4j.test.rule.PageCacheRule.config; /** @@ -77,7 +75,7 @@ * toAdd and toRemove, prepare the GB+Tree with entries and serve readers and writer with information * about what they should do next. */ -public class GBPTreeConcurrencyIT +public abstract class GBPTreeConcurrencyITBase { private final DefaultFileSystemRule fs = new DefaultFileSystemRule(); private final TestDirectory directory = TestDirectory.testDirectory( getClass(), fs.get() ); @@ -87,27 +85,21 @@ public class GBPTreeConcurrencyIT @Rule public final RuleChain rules = outerRule( fs ).around( directory ).around( pageCacheRule ).around( random ); - private Layout layout; - private GBPTree index; + private TestLayout layout; + private GBPTree index; private final ExecutorService threadPool = Executors.newFixedThreadPool( Runtime.getRuntime().availableProcessors() ); - private GBPTree createIndex() - throws IOException - { - return createIndex( NO_MONITOR ); - } - - private GBPTree createIndex( GBPTree.Monitor monitor ) - throws IOException + private GBPTree createIndex() throws IOException { int pageSize = 512; - layout = new SimpleLongLayout( random.intBetween( 0, 10 ) ); - PageCache pageCache = - pageCacheRule.getPageCache( fs.get(), config().withPageSize( pageSize ).withAccessChecks( true ) ); + layout = getLayout( random ); + PageCache pageCache = pageCacheRule.getPageCache( fs.get(), config().withPageSize( pageSize ).withAccessChecks( true ) ); return index = new GBPTreeBuilder<>( pageCache, directory.file( "index" ), layout ).build(); } + protected abstract TestLayout getLayout( RandomRule random ); + @After public void consistencyCheckAndClose() throws IOException { @@ -200,6 +192,7 @@ private void shouldReadCorrectlyWithConcurrentUpdates( TestCoordinator testCoord threadPool.awaitTermination( 10, TimeUnit.SECONDS ); if ( readerError.get() != null ) { + //noinspection ThrowFromFinallyBlock throw readerError.get(); } } @@ -249,25 +242,25 @@ List shuffleToNewList( List sourceList, Random random ) return shuffledList; } - void prepare( GBPTree index ) throws IOException + void prepare( GBPTree index ) throws IOException { prepareIndex( index, readersShouldSee, toRemove, toAdd, random ); iterationFinished(); } - void prepareIndex( GBPTree index, TreeSet dataInIndex, + void prepareIndex( GBPTree index, TreeSet dataInIndex, Queue toRemove, Queue toAdd, Random random ) throws IOException { List fullRange = LongStream.range( minRange, maxRange ).boxed().collect( Collectors.toList() ); List rangeOutOfOrder = shuffleToNewList( fullRange, random ); - try ( Writer writer = index.writer() ) + try ( Writer writer = index.writer() ) { for ( Long key : rangeOutOfOrder ) { boolean addForRemoval = random.nextDouble() > writePercentage; if ( addForRemoval ) { - writer.put( new MutableLong( key ), new MutableLong( key ) ); + writer.put( key( key ),value( key ) ); dataInIndex.add( key ); toRemove.add( key ); } @@ -282,8 +275,7 @@ void prepareIndex( GBPTree index, TreeSet dataInI void iterationFinished() { // Create new set to not modify set that readers use concurrently - TreeSet tmp = new TreeSet<>( readersShouldSee ); - readersShouldSee = tmp; + readersShouldSee = new TreeSet<>( readersShouldSee ); updateRecentlyInsertedData( readersShouldSee, updatesForNextIteration ); updatesForNextIteration = generateUpdatesForNextIteration(); updateWithSoonToBeRemovedData( readersShouldSee, updatesForNextIteration ); @@ -384,7 +376,7 @@ private abstract static class UpdateOperation this.key = key; } - abstract void apply( Writer writer ) throws IOException; + abstract void apply( Writer writer ) throws IOException; abstract void applyToSet( Set set ); @@ -399,9 +391,9 @@ private static class PutOperation extends UpdateOperation } @Override - void apply( Writer writer ) throws IOException + void apply( Writer writer ) throws IOException { - writer.put( new MutableLong( key ), new MutableLong( key ) ); + writer.put( key( key ), value( key ) ); } @Override @@ -425,9 +417,9 @@ private static class RemoveOperation extends UpdateOperation } @Override - void apply( Writer writer ) throws IOException + void apply( Writer writer ) throws IOException { - writer.remove( new MutableLong( key ) ); + writer.remove( key( key ) ); } @Override @@ -465,7 +457,7 @@ private void writeOneIteration( TestCoordinator testCoordinator, Iterator toWriteIterator = toWrite.iterator(); while ( toWriteIterator.hasNext() ) { - try ( Writer writer = index.writer() ) + try ( Writer writer = index.writer() ) { int inBatch = 0; while ( toWriteIterator.hasNext() && inBatch < batchSize ) @@ -532,8 +524,7 @@ private void doRead() throws IOException long start = readerInstruction.start(); long end = readerInstruction.end(); boolean forward = start <= end; - try ( RawCursor,IOException> cursor = - index.seek( new MutableLong( start ), new MutableLong( end ) ) ) + try ( RawCursor,IOException> cursor = index.seek( key( start ), key( end ) ) ) { if ( expectToSee.hasNext() ) { @@ -541,8 +532,8 @@ private void doRead() throws IOException while ( cursor.next() ) { // Actual - long lastSeenKey = cursor.get().key().longValue(); - long lastSeenValue = cursor.get().value().longValue(); + long lastSeenKey = keySeed( cursor.get().key() ); + long lastSeenValue = valueSeed( cursor.get().value() ); if ( lastSeenKey != lastSeenValue ) { @@ -634,4 +625,24 @@ TreeSet expectToSee() return expectToSee; } } + + private KEY key( long seed ) + { + return layout.key( seed ); + } + + private VALUE value( long seed ) + { + return layout.value( seed ); + } + + private long keySeed( KEY key ) + { + return layout.keySeed( key ); + } + + private long valueSeed( VALUE value ) + { + return layout.valueSeed( value ); + } }