diff --git a/community/index/src/main/java/org/neo4j/index/internal/gbptree/RecoveryCleanupWorkCollector.java b/community/index/src/main/java/org/neo4j/index/internal/gbptree/RecoveryCleanupWorkCollector.java index 6aca12764abf7..9ede1c13306cb 100644 --- a/community/index/src/main/java/org/neo4j/index/internal/gbptree/RecoveryCleanupWorkCollector.java +++ b/community/index/src/main/java/org/neo4j/index/internal/gbptree/RecoveryCleanupWorkCollector.java @@ -45,6 +45,11 @@ public interface RecoveryCleanupWorkCollector extends Lifecycle */ RecoveryCleanupWorkCollector IMMEDIATE = new ImmediateRecoveryCleanupWorkCollector(); + /** + * Ignore all clean jobs. + */ + RecoveryCleanupWorkCollector NULL = new NullRecoveryCleanupWorkCollector(); + /** * {@link RecoveryCleanupWorkCollector} which runs added {@link CleanupJob} as part of the {@link #add(CleanupJob)} * call in the caller thread. @@ -57,4 +62,12 @@ public void add( CleanupJob job ) job.run(); } } + + class NullRecoveryCleanupWorkCollector extends LifecycleAdapter implements RecoveryCleanupWorkCollector + { + @Override + public void add( CleanupJob job ) + { // no-op + } + } } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/NativeNonUniqueSchemaNumberIndexPopulator.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/NativeNonUniqueSchemaNumberIndexPopulator.java index dbe230f027d1f..2922cad4d049c 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/NativeNonUniqueSchemaNumberIndexPopulator.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/NativeNonUniqueSchemaNumberIndexPopulator.java @@ -44,7 +44,7 @@ class NativeNonUniqueSchemaNumberIndexPopulator layout, RecoveryCleanupWorkCollector recoveryCleanupWorkCollector, IndexSamplingConfig samplingConfig ) { - super( pageCache, storeFile, layout, recoveryCleanupWorkCollector ); + super( pageCache, storeFile, layout ); this.samplingConfig = samplingConfig; } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/NativeSchemaNumberIndex.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/NativeSchemaNumberIndex.java new file mode 100644 index 0000000000000..471a109d1c378 --- /dev/null +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/NativeSchemaNumberIndex.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2002-2017 "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.kernel.impl.index.schema; + +import java.io.Closeable; +import java.io.File; +import java.io.IOException; + +import org.neo4j.index.internal.gbptree.GBPTree; +import org.neo4j.index.internal.gbptree.Layout; +import org.neo4j.index.internal.gbptree.RecoveryCleanupWorkCollector; +import org.neo4j.io.pagecache.PageCache; + +import static org.neo4j.index.internal.gbptree.GBPTree.NO_HEADER_READER; +import static org.neo4j.index.internal.gbptree.GBPTree.NO_HEADER_WRITER; +import static org.neo4j.index.internal.gbptree.GBPTree.NO_MONITOR; + +class NativeSchemaNumberIndex +{ + final PageCache pageCache; + final File storeFile; + final Layout layout; + + GBPTree tree; + + NativeSchemaNumberIndex( PageCache pageCache, File storeFile, Layout layout ) + { + this.pageCache = pageCache; + this.storeFile = storeFile; + this.layout = layout; + } + + void instantiateTree( RecoveryCleanupWorkCollector recoveryCleanupWorkCollector ) throws IOException + { + tree = new GBPTree<>( pageCache, storeFile, layout, 0, NO_MONITOR, NO_HEADER_READER, NO_HEADER_WRITER, + recoveryCleanupWorkCollector ); + } + + void closeTree() throws IOException + { + tree = closeIfPresent( tree ); + } + + T closeIfPresent( T closeable ) throws IOException + { + if ( closeable != null ) + { + closeable.close(); + } + return null; + } +} diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/NativeSchemaNumberIndexPopulator.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/NativeSchemaNumberIndexPopulator.java index a80d8f4f0149c..5c461e1b95e60 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/NativeSchemaNumberIndexPopulator.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/NativeSchemaNumberIndexPopulator.java @@ -19,13 +19,11 @@ */ package org.neo4j.kernel.impl.index.schema; -import java.io.Closeable; import java.io.File; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.Collection; -import org.neo4j.collection.primitive.PrimitiveLongSet; import org.neo4j.index.internal.gbptree.GBPTree; import org.neo4j.index.internal.gbptree.Layout; import org.neo4j.index.internal.gbptree.RecoveryCleanupWorkCollector; @@ -38,11 +36,6 @@ import org.neo4j.kernel.api.index.IndexUpdater; import org.neo4j.kernel.api.index.PropertyAccessor; import org.neo4j.kernel.impl.index.GBPTreeUtil; -import org.neo4j.values.ValueTuple; - -import static org.neo4j.index.internal.gbptree.GBPTree.NO_HEADER_READER; -import static org.neo4j.index.internal.gbptree.GBPTree.NO_HEADER_WRITER; -import static org.neo4j.index.internal.gbptree.GBPTree.NO_MONITOR; /** * {@link IndexPopulator} backed by a {@link GBPTree}. @@ -51,55 +44,41 @@ * @param type of {@link NumberValue}. */ public abstract class NativeSchemaNumberIndexPopulator - implements IndexPopulator + extends NativeSchemaNumberIndex implements IndexPopulator { static final byte BYTE_ONLINE = 1; static final byte BYTE_FAILED = 0; - private final PageCache pageCache; - private final File storeFile; private final KEY treeKey; private final VALUE treeValue; - private final RecoveryCleanupWorkCollector recoveryCleanupWorkCollector; private final ConflictDetectingValueMerger conflictDetectingValueMerger; - protected final Layout layout; + private final NativeSchemaNumberIndexUpdater singleUpdater; - private Writer singleWriter; + private Writer singleTreeWriter; private byte[] failureBytes; private boolean dropped; - GBPTree tree; - - NativeSchemaNumberIndexPopulator( PageCache pageCache, File storeFile, Layout layout, - RecoveryCleanupWorkCollector recoveryCleanupWorkCollector ) + NativeSchemaNumberIndexPopulator( PageCache pageCache, File storeFile, Layout layout ) { - this.pageCache = pageCache; - this.storeFile = storeFile; - this.layout = layout; + super( pageCache, storeFile, layout ); this.treeKey = layout.newKey(); this.treeValue = layout.newValue(); - this.recoveryCleanupWorkCollector = recoveryCleanupWorkCollector; this.conflictDetectingValueMerger = new ConflictDetectingValueMerger<>(); + singleUpdater = new NativeSchemaNumberIndexUpdater<>( layout.newKey(), layout.newValue() ); } @Override public synchronized void create() throws IOException { GBPTreeUtil.deleteIfPresent( pageCache, storeFile ); - instantiateTree(); + instantiateTree( RecoveryCleanupWorkCollector.IMMEDIATE ); instantiateWriter(); } - private void instantiateTree() throws IOException - { - tree = new GBPTree<>( pageCache, storeFile, layout, 0, NO_MONITOR, NO_HEADER_READER, - NO_HEADER_WRITER, recoveryCleanupWorkCollector ); - } - void instantiateWriter() throws IOException { - assert singleWriter == null; - singleWriter = tree.writer(); + assert singleTreeWriter == null; + singleTreeWriter = tree.writer(); } @Override @@ -129,15 +108,8 @@ public void add( Collection> updates ) throws Inde @Override public void add( IndexEntryUpdate update ) throws IndexEntryConflictException, IOException { - treeKey.from( update.getEntityId(), update.values() ); - treeValue.from( update.getEntityId(), update.values() ); - singleWriter.merge( treeKey, treeValue, conflictDetectingValueMerger ); - if ( conflictDetectingValueMerger.wasConflict() ) - { - long existingNodeId = conflictDetectingValueMerger.existingNodeId(); - long addedNodeId = conflictDetectingValueMerger.addedNodeId(); - throw new IndexEntryConflictException( existingNodeId, addedNodeId, ValueTuple.of( update.values() ) ); - } + NativeSchemaNumberIndexUpdater + .processAdd( treeKey, treeValue, update, singleTreeWriter, conflictDetectingValueMerger ); } @Override @@ -150,7 +122,7 @@ public void verifyDeferredConstraints( PropertyAccessor propertyAccessor ) @Override public IndexUpdater newPopulatingUpdater( PropertyAccessor accessor ) throws IOException { - return new NativeSchemaIndexUpdater(); + return singleUpdater.initialize( singleTreeWriter, false ); } @Override @@ -199,7 +171,7 @@ private void ensureTreeInstantiated() throws IOException { if ( tree == null ) { - instantiateTree(); + instantiateTree( RecoveryCleanupWorkCollector.NULL ); } } @@ -225,49 +197,8 @@ private void markTreeAsOnline() throws IOException tree.checkpoint( IOLimiter.unlimited(), ( pc ) -> pc.putByte( BYTE_ONLINE ) ); } - private T closeIfPresent( T closeable ) throws IOException - { - if ( closeable != null ) - { - closeable.close(); - } - return null; - } - void closeWriter() throws IOException { - singleWriter = closeIfPresent( singleWriter ); - } - - private void closeTree() throws IOException - { - tree = closeIfPresent( tree ); - } - - private class NativeSchemaIndexUpdater implements IndexUpdater - { - private boolean closed; - - @Override - public void process( IndexEntryUpdate update ) throws IOException, IndexEntryConflictException - { - if ( closed ) - { - throw new IllegalStateException( "Index updater has been closed." ); - } - add( update ); - } - - @Override - public void remove( PrimitiveLongSet nodeIds ) throws IOException - { - throw new UnsupportedOperationException( "Implement me" ); - } - - @Override - public void close() throws IOException, IndexEntryConflictException - { - closed = true; - } + singleTreeWriter = closeIfPresent( singleTreeWriter ); } } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/NativeSchemaNumberIndexUpdater.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/NativeSchemaNumberIndexUpdater.java new file mode 100644 index 0000000000000..5f0079ce8d74c --- /dev/null +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/NativeSchemaNumberIndexUpdater.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2002-2017 "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.kernel.impl.index.schema; + +import java.io.IOException; + +import org.neo4j.collection.primitive.PrimitiveLongSet; +import org.neo4j.index.internal.gbptree.Writer; +import org.neo4j.kernel.api.exceptions.index.IndexEntryConflictException; +import org.neo4j.kernel.api.index.IndexEntryUpdate; +import org.neo4j.kernel.api.index.IndexUpdater; +import org.neo4j.values.ValueTuple; + +class NativeSchemaNumberIndexUpdater + implements IndexUpdater +{ + private final KEY treeKey; + private final VALUE treeValue; + private final ConflictDetectingValueMerger conflictDetectingValueMerger; + private Writer writer; + + private boolean closed = true; + private boolean manageClosingOfWriter; + + NativeSchemaNumberIndexUpdater( KEY treeKey, VALUE treeValue ) + { + this.treeKey = treeKey; + this.treeValue = treeValue; + this.conflictDetectingValueMerger = new ConflictDetectingValueMerger(); + } + + NativeSchemaNumberIndexUpdater initialize( Writer writer, boolean manageClosingOfWriter ) + { + if ( !closed ) + { + throw new IllegalStateException( "Updater still open" ); + } + + this.manageClosingOfWriter = manageClosingOfWriter; + this.writer = writer; + closed = false; + return this; + } + + @Override + public void process( IndexEntryUpdate update ) throws IOException, IndexEntryConflictException + { + assertOpen(); + processAdd( treeKey, treeValue, update, writer, conflictDetectingValueMerger ); + } + + @Override + public void close() throws IOException, IndexEntryConflictException + { + if ( manageClosingOfWriter ) + { + writer.close(); + } + closed = true; + } + + @Override + public void remove( PrimitiveLongSet nodeIds ) throws IOException + { + assertOpen(); + } + + private void assertOpen() + { + if ( closed ) + { + throw new IllegalStateException( "Updater has been closed" ); + } + } + + static void processAdd( KEY treeKey, VALUE treeValue, + IndexEntryUpdate update, Writer singleWriter, + ConflictDetectingValueMerger conflictDetectingValueMerger ) + throws IOException, IndexEntryConflictException + { + treeKey.from( update.getEntityId(), update.values() ); + treeValue.from( update.getEntityId(), update.values() ); + singleWriter.merge( treeKey, treeValue, conflictDetectingValueMerger ); + if ( conflictDetectingValueMerger.wasConflict() ) + { + long existingNodeId = conflictDetectingValueMerger.existingNodeId(); + long addedNodeId = conflictDetectingValueMerger.addedNodeId(); + throw new IndexEntryConflictException( existingNodeId, addedNodeId, ValueTuple.of( update.values() ) ); + } + } +} diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/NativeUniqueSchemaNumberIndexPopulator.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/NativeUniqueSchemaNumberIndexPopulator.java index a93cfcad1ebe3..2a57f161818bf 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/NativeUniqueSchemaNumberIndexPopulator.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/NativeUniqueSchemaNumberIndexPopulator.java @@ -39,7 +39,7 @@ class NativeUniqueSchemaNumberIndexPopulator layout, RecoveryCleanupWorkCollector recoveryCleanupWorkCollector ) { - super( pageCache, storeFile, layout, recoveryCleanupWorkCollector ); + super( pageCache, storeFile, layout ); this.sampler = new UniqueIndexSampler(); } diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/NativeNonUniqueSchemaNumberIndexPopulatorTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/NativeNonUniqueSchemaNumberIndexPopulatorTest.java index c62222425f511..8207814718290 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/NativeNonUniqueSchemaNumberIndexPopulatorTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/NativeNonUniqueSchemaNumberIndexPopulatorTest.java @@ -176,7 +176,7 @@ public void shouldSampleUpdatesIfConfiguredForOnlineSampling() throws Exception } @Override - protected LayoutTestUtil createLayoutTestUtil() + protected LayoutTestUtil createLayoutTestUtil() { return new NonUniqueLayoutTestUtil(); } diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/NativeSchemaIndexPopulatorTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/NativeSchemaIndexPopulatorTest.java index af94c23cbcd7e..c457c5d0da4d5 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/NativeSchemaIndexPopulatorTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/NativeSchemaIndexPopulatorTest.java @@ -49,7 +49,6 @@ import org.neo4j.kernel.api.index.IndexUpdater; import org.neo4j.kernel.api.index.PropertyAccessor; import org.neo4j.kernel.api.schema.index.IndexDescriptor; -import org.neo4j.kernel.api.schema.index.IndexDescriptorFactory; import org.neo4j.kernel.configuration.Config; import org.neo4j.kernel.impl.api.index.sampling.IndexSamplingConfig; import org.neo4j.test.rule.RandomRule; @@ -69,7 +68,6 @@ public abstract class NativeSchemaIndexPopulatorTest { static final int LARGE_AMOUNT_OF_UPDATES = 1_000; - private static final IndexDescriptor indexDescriptor = IndexDescriptorFactory.forLabel( 42, 666 ); static final PropertyAccessor null_property_accessor = ( nodeId, propKeyId ) -> { throw new RuntimeException( "Did not expect an attempt to go to store" ); @@ -502,26 +500,6 @@ private void assertFileNotPresent() assertFalse( fs.fileExists( indexFile ) ); } - static IndexEntryUpdate[] someIndexEntryUpdates() - { - return new IndexEntryUpdate[]{ - add( 0, 0 ), - add( 1, 4 ), - add( 2, Double.MAX_VALUE ), - add( 3, -Double.MAX_VALUE ), - add( 4, Float.MAX_VALUE ), - add( 5, -Float.MAX_VALUE ), - add( 6, Long.MAX_VALUE ), - add( 7, Long.MIN_VALUE ), - add( 8, Integer.MAX_VALUE ), - add( 9, Integer.MIN_VALUE ), - add( 10, Short.MAX_VALUE ), - add( 11, Short.MIN_VALUE ), - add( 12, Byte.MAX_VALUE ), - add( 13, Byte.MIN_VALUE ) - }; - } - int interleaveLargeAmountOfUpdates( Random updaterRandom, Iterator> updates ) throws IOException, IndexEntryConflictException { @@ -593,41 +571,6 @@ private Number existingNonUniqueValue( RandomRule randomRule ) }; } - @SuppressWarnings( "rawtypes" ) - static IndexEntryUpdate[] someDuplicateIndexEntryUpdates() - { - return new IndexEntryUpdate[]{ - add( 0, 0 ), - add( 1, 4 ), - add( 2, Double.MAX_VALUE ), - add( 3, -Double.MAX_VALUE ), - add( 4, Float.MAX_VALUE ), - add( 5, -Float.MAX_VALUE ), - add( 6, Long.MAX_VALUE ), - add( 7, Long.MIN_VALUE ), - add( 8, Integer.MAX_VALUE ), - add( 9, Integer.MIN_VALUE ), - add( 10, Short.MAX_VALUE ), - add( 11, Short.MIN_VALUE ), - add( 12, Byte.MAX_VALUE ), - add( 13, Byte.MIN_VALUE ), - add( 14, 0 ), - add( 15, 4 ), - add( 16, Double.MAX_VALUE ), - add( 17, -Double.MAX_VALUE ), - add( 18, Float.MAX_VALUE ), - add( 19, -Float.MAX_VALUE ), - add( 20, Long.MAX_VALUE ), - add( 21, Long.MIN_VALUE ), - add( 22, Integer.MAX_VALUE ), - add( 23, Integer.MIN_VALUE ), - add( 24, Short.MAX_VALUE ), - add( 25, Short.MIN_VALUE ), - add( 26, Byte.MAX_VALUE ), - add( 27, Byte.MIN_VALUE ) - }; - } - private void assertHeader( boolean online, String failureMessage, boolean messageTruncated ) throws IOException { NativeSchemaIndexHeaderReader headerReader = new NativeSchemaIndexHeaderReader(); @@ -713,11 +656,6 @@ public void read( ByteBuffer headerData ) } } - protected static IndexEntryUpdate add( long nodeId, Object value ) - { - return IndexEntryUpdate.add( nodeId, indexDescriptor, Values.of( value ) ); - } - private byte[] fileWithContent() throws IOException { int size = 1000; diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/NativeUniqueSchemaNumberIndexPopulatorTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/NativeUniqueSchemaNumberIndexPopulatorTest.java index 8932a3e5665a1..c6d3f7d8efb2b 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/NativeUniqueSchemaNumberIndexPopulatorTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/NativeUniqueSchemaNumberIndexPopulatorTest.java @@ -51,7 +51,7 @@ NativeSchemaNumberIndexPopulator createPopula } @Override - protected LayoutTestUtil createLayoutTestUtil() + protected LayoutTestUtil createLayoutTestUtil() { return new UniqueLayoutTestUtil(); } @@ -59,7 +59,7 @@ protected LayoutTestUtil createLayoutTestUtil() @Override protected int compareValue( UniqueNumberValue value1, UniqueNumberValue value2 ) { - int valueCompare = compareIndexedPropertyValue( value1, value2 ); + int valueCompare = layoutUtil.compareIndexedPropertyValue( value1, value2 ); if ( valueCompare == 0 ) { return Long.compare( value1.getEntityId(), value2.getEntityId() ); diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/SchemaNumberIndexTestUtil.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/SchemaNumberIndexTestUtil.java index 1ca57b9504834..807e40870f23a 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/SchemaNumberIndexTestUtil.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/SchemaNumberIndexTestUtil.java @@ -39,18 +39,20 @@ import org.neo4j.io.pagecache.PageCache; import org.neo4j.kernel.api.index.IndexEntryUpdate; import org.neo4j.kernel.api.schema.index.IndexDescriptor; +import org.neo4j.kernel.api.schema.index.IndexDescriptorFactory; import org.neo4j.test.rule.PageCacheRule; import org.neo4j.test.rule.RandomRule; import org.neo4j.test.rule.TestDirectory; import org.neo4j.test.rule.fs.DefaultFileSystemRule; import org.neo4j.test.rule.fs.FileSystemRule; +import org.neo4j.values.Values; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.rules.RuleChain.outerRule; -import static org.neo4j.kernel.impl.index.schema.NumberValue.DOUBLE; -import static org.neo4j.kernel.impl.index.schema.NumberValue.FLOAT; -import static org.neo4j.kernel.impl.index.schema.NumberValue.LONG; + +import static org.neo4j.index.internal.gbptree.GBPTree.NO_HEADER_READER; +import static org.neo4j.index.internal.gbptree.GBPTree.NO_HEADER_WRITER; import static org.neo4j.test.rule.PageCacheRule.config; public abstract class SchemaNumberIndexTestUtil @@ -63,6 +65,7 @@ public abstract class SchemaNumberIndexTestUtil layoutUtil; + private IndexDescriptor indexDescriptor; Layout layout; File indexFile; PageCache pageCache; @@ -71,6 +74,7 @@ public abstract class SchemaNumberIndexTestUtil createLayoutTestUtil(); - protected void copyValue( VALUE value, VALUE intoValue ) + private IndexDescriptor createIndexDescriptor() + { + return IndexDescriptorFactory.forLabel( 42, 666 ); + } + + private void copyValue( VALUE value, VALUE intoValue ) { layoutUtil.copyValue( value, intoValue ); } @@ -120,7 +129,7 @@ void verifyUpdates( IndexEntryUpdate[] updates ) GBPTree getTree() throws IOException { return new GBPTree<>( pageCache, indexFile, layout, 0, GBPTree.NO_MONITOR, - GBPTree.NO_HEADER, RecoveryCleanupWorkCollector.IMMEDIATE ); + NO_HEADER_READER, NO_HEADER_WRITER, RecoveryCleanupWorkCollector.IMMEDIATE ); } private RawCursor, IOException> scan( GBPTree tree ) throws IOException @@ -132,32 +141,6 @@ private RawCursor, IOException> scan( GBPTree tree ) t return tree.seek( lowest, highest ); } - int compareIndexedPropertyValue( NumberValue value1, NumberValue value2 ) - { - int typeCompare = Byte.compare( value1.type(), value2.type() ); - if ( typeCompare == 0 ) - { - switch ( value1.type() ) - { - case LONG: - return Long.compare( value1.rawValueBits(), value2.rawValueBits() ); - case FLOAT: - return Float.compare( - Float.intBitsToFloat( (int) value1.rawValueBits() ), - Float.intBitsToFloat( (int) value2.rawValueBits() ) ); - case DOUBLE: - return Double.compare( - Double.longBitsToDouble( value1.rawValueBits() ), - Double.longBitsToDouble( value2.rawValueBits() ) ); - default: - throw new IllegalArgumentException( - "Expected type to be LONG, FLOAT or DOUBLE (" + LONG + "," + FLOAT + "," + DOUBLE + - "). But was " + value1.type() ); - } - } - return typeCompare; - } - private void assertSameHits( Hit[] expectedHits, Hit[] actualHits, Comparator> comparator ) { @@ -255,4 +238,70 @@ public String toString() return "[" + key + "," + value + "]"; } } + + IndexEntryUpdate[] someIndexEntryUpdates() + { + return new IndexEntryUpdate[]{ + add( 0, 0 ), + add( 1, 4 ), + add( 2, Double.MAX_VALUE ), + add( 3, -Double.MAX_VALUE ), + add( 4, Float.MAX_VALUE ), + add( 5, -Float.MAX_VALUE ), + add( 6, Long.MAX_VALUE ), + add( 7, Long.MIN_VALUE ), + add( 8, Integer.MAX_VALUE ), + add( 9, Integer.MIN_VALUE ), + add( 10, Short.MAX_VALUE ), + add( 11, Short.MIN_VALUE ), + add( 12, Byte.MAX_VALUE ), + add( 13, Byte.MIN_VALUE ), + add( 14, Double.POSITIVE_INFINITY ), + add( 15, Double.NEGATIVE_INFINITY ), + }; + } + + @SuppressWarnings( "rawtypes" ) + IndexEntryUpdate[] someDuplicateIndexEntryUpdates() + { + return new IndexEntryUpdate[]{ + add( 0, 0 ), + add( 1, 4 ), + add( 2, Double.MAX_VALUE ), + add( 3, -Double.MAX_VALUE ), + add( 4, Float.MAX_VALUE ), + add( 5, -Float.MAX_VALUE ), + add( 6, Long.MAX_VALUE ), + add( 7, Long.MIN_VALUE ), + add( 8, Integer.MAX_VALUE ), + add( 9, Integer.MIN_VALUE ), + add( 10, Short.MAX_VALUE ), + add( 11, Short.MIN_VALUE ), + add( 12, Byte.MAX_VALUE ), + add( 13, Byte.MIN_VALUE ), + add( 14, 0 ), + add( 15, 4 ), + add( 16, Double.MAX_VALUE ), + add( 17, -Double.MAX_VALUE ), + add( 18, Float.MAX_VALUE ), + add( 19, -Float.MAX_VALUE ), + add( 20, Long.MAX_VALUE ), + add( 21, Long.MIN_VALUE ), + add( 22, Integer.MAX_VALUE ), + add( 23, Integer.MIN_VALUE ), + add( 24, Short.MAX_VALUE ), + add( 25, Short.MIN_VALUE ), + add( 26, Byte.MAX_VALUE ), + add( 27, Byte.MIN_VALUE ), + add( 28, Double.POSITIVE_INFINITY ), + add( 29, Double.NEGATIVE_INFINITY ), + add( 30, Double.POSITIVE_INFINITY ), + add( 31, Double.NEGATIVE_INFINITY ) + }; + } + + protected IndexEntryUpdate add( long nodeId, Object value ) + { + return IndexEntryUpdate.add( nodeId, indexDescriptor, Values.of( value ) ); + } }