diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/BlockEntry.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/BlockEntry.java index c27c351b04ea3..48c7df3c76db0 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/BlockEntry.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/BlockEntry.java @@ -19,6 +19,14 @@ */ package org.neo4j.kernel.impl.index.schema; +import org.neo4j.index.internal.gbptree.Layout; +import org.neo4j.io.pagecache.PageCursor; + +import static org.neo4j.index.internal.gbptree.DynamicSizeUtil.extractKeySize; +import static org.neo4j.index.internal.gbptree.DynamicSizeUtil.extractValueSize; +import static org.neo4j.index.internal.gbptree.DynamicSizeUtil.putKeyValueSize; +import static org.neo4j.index.internal.gbptree.DynamicSizeUtil.readKeyValueSize; + class BlockEntry { private KEY key; @@ -39,4 +47,33 @@ VALUE value() { return value; } + + static BlockEntry read( PageCursor pageCursor, Layout layout ) + { + KEY key = layout.newKey(); + VALUE value = layout.newValue(); + read( pageCursor, layout, key, value ); + return new BlockEntry<>( key, value ); + } + + static void read( PageCursor pageCursor, Layout layout, KEY key, VALUE value ) + { + long entrySize = readKeyValueSize( pageCursor ); + layout.readKey( pageCursor, key, extractKeySize( entrySize ) ); + layout.readValue( pageCursor, value, extractValueSize( entrySize ) ); + } + + static void write( PageCursor pageCursor, Layout layout, BlockEntry entry ) + { + write( pageCursor, layout, entry.key(), entry.value() ); + } + + static void write( PageCursor pageCursor, Layout layout, KEY key, VALUE value ) + { + int keySize = layout.keySize( key ); + int valueSize = layout.valueSize( value ); + putKeyValueSize( pageCursor, keySize, valueSize ); + layout.writeKey( pageCursor, key ); + layout.writeValue( pageCursor, value ); + } } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/BlockReader.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/BlockReader.java index 1f1818ecb6a49..721d6343c51a4 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/BlockReader.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/BlockReader.java @@ -25,10 +25,6 @@ import org.neo4j.index.internal.gbptree.Layout; import org.neo4j.io.pagecache.PageCursor; -import static org.neo4j.index.internal.gbptree.DynamicSizeUtil.extractKeySize; -import static org.neo4j.index.internal.gbptree.DynamicSizeUtil.extractValueSize; -import static org.neo4j.index.internal.gbptree.DynamicSizeUtil.readKeyValueSize; - public class BlockReader implements Closeable { private final long entryCount; @@ -53,11 +49,7 @@ public boolean next() throws IOException { return false; } - - long entrySize = readKeyValueSize( pageCursor ); - layout.readKey( pageCursor, key, extractKeySize( entrySize ) ); - layout.readValue( pageCursor, value, extractValueSize( entrySize ) ); - + BlockEntry.read( pageCursor, layout, key, value ); readEntries++; return true; } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/BlockStorage.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/BlockStorage.java index 2d6f545000d98..7cf9834dd0ef8 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/BlockStorage.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/BlockStorage.java @@ -36,7 +36,6 @@ import org.neo4j.util.Preconditions; import static org.neo4j.index.internal.gbptree.DynamicSizeUtil.getOverhead; -import static org.neo4j.index.internal.gbptree.DynamicSizeUtil.putKeyValueSize; class BlockStorage implements Closeable { @@ -119,11 +118,7 @@ private void flushAndResetBuffer() throws IOException // Entries for ( BlockEntry entry : bufferedEntries ) { - int keySize = layout.keySize( entry.key() ); - int valueSize = layout.valueSize( entry.value() ); - putKeyValueSize( pageCursor, keySize, valueSize ); - layout.writeKey( pageCursor, entry.key() ); - layout.writeValue( pageCursor, entry.value() ); + BlockEntry.write( pageCursor, layout, entry ); } // TODO solve the BIG padding problem diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/BlockEntryTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/BlockEntryTest.java new file mode 100644 index 0000000000000..9740394da7332 --- /dev/null +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/BlockEntryTest.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2002-2019 "Neo4j," + * Neo4j Sweden AB [http://neo4j.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 org.apache.commons.lang3.mutable.MutableLong; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import java.util.ArrayList; +import java.util.List; + +import org.neo4j.index.internal.gbptree.SimpleLongLayout; +import org.neo4j.io.pagecache.ByteArrayPageCursor; +import org.neo4j.io.pagecache.PageCursor; +import org.neo4j.test.extension.Inject; +import org.neo4j.test.extension.RandomExtension; +import org.neo4j.test.rule.RandomRule; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@ExtendWith( RandomExtension.class ) +class BlockEntryTest +{ + @Inject + RandomRule rnd; + + private static final PageCursor pageCursor = ByteArrayPageCursor.wrap( 1000 ); + private static SimpleLongLayout layout; + + @BeforeEach + void setup() + { + layout = SimpleLongLayout.longLayout() + .withFixedSize( rnd.nextBoolean() ) + .withKeyPadding( rnd.nextInt( 10 ) ) + .build(); + } + + @Test + void shouldReadWriteSingleEntry() + { + // given + MutableLong writeKey = layout.key( rnd.nextLong() ); + MutableLong writeValue = layout.value( rnd.nextLong() ); + int offset = pageCursor.getOffset(); + BlockEntry.write( pageCursor, layout, writeKey, writeValue ); + + // when + MutableLong readKey = layout.newKey(); + MutableLong readValue = layout.newValue(); + pageCursor.setOffset( offset ); + BlockEntry.read( pageCursor, layout, readKey, readValue ); + + // then + assertEquals( 0, layout.compare( writeKey, readKey ) ); + assertEquals( 0, layout.compare( writeValue, readValue ) ); + } + + @Test + void shouldReadWriteMultipleEntries() + { + List> expectedEntries = new ArrayList<>(); + int nbrOfEntries = 10; + int offset = pageCursor.getOffset(); + for ( int i = 0; i < nbrOfEntries; i++ ) + { + BlockEntry entry = new BlockEntry<>( layout.key( rnd.nextLong() ), layout.value( rnd.nextLong() ) ); + BlockEntry.write( pageCursor, layout, entry ); + expectedEntries.add( entry ); + } + + pageCursor.setOffset( offset ); + for ( BlockEntry expectedEntry : expectedEntries ) + { + BlockEntry actualEntry = BlockEntry.read( pageCursor, layout ); + assertBlockEquals( expectedEntry, actualEntry ); + } + } + + private void assertBlockEquals( BlockEntry expected, BlockEntry actual ) + { + assertEquals( 0, layout.compare( expected.key(), actual.key() ) ); + assertEquals( 0, layout.compare( expected.value(), actual.value() ) ); + } +} diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/BlockStorageTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/BlockStorageTest.java index f55be102c8e2d..07127a461c477 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/BlockStorageTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/BlockStorageTest.java @@ -1,3 +1,22 @@ +/* + * Copyright (c) 2002-2019 "Neo4j," + * Neo4j Sweden AB [http://neo4j.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 org.apache.commons.lang3.mutable.MutableLong;