diff --git a/community/index/src/main/java/org/neo4j/index/internal/gbptree/TreeNodeDynamicSize.java b/community/index/src/main/java/org/neo4j/index/internal/gbptree/TreeNodeDynamicSize.java index 7044174e46e42..27d3545282380 100644 --- a/community/index/src/main/java/org/neo4j/index/internal/gbptree/TreeNodeDynamicSize.java +++ b/community/index/src/main/java/org/neo4j/index/internal/gbptree/TreeNodeDynamicSize.java @@ -19,10 +19,13 @@ */ package org.neo4j.index.internal.gbptree; +import org.eclipse.collections.api.stack.primitive.IntStack; +import org.eclipse.collections.api.stack.primitive.MutableIntStack; +import org.eclipse.collections.impl.stack.mutable.primitive.IntArrayStack; + import java.util.Arrays; import java.util.StringJoiner; -import org.neo4j.collection.primitive.PrimitiveIntStack; import org.neo4j.io.pagecache.PageCursor; import static java.lang.String.format; @@ -90,8 +93,8 @@ public class TreeNodeDynamicSize extends TreeNode private static final int LEAST_NUMBER_OF_ENTRIES_PER_PAGE = 2; private static final int MINIMUM_ENTRY_SIZE_CAP = Long.SIZE; private final int keyValueSizeCap; - private final PrimitiveIntStack deadKeysOffset = new PrimitiveIntStack(); - private final PrimitiveIntStack aliveKeysOffset = new PrimitiveIntStack(); + private final MutableIntStack deadKeysOffset = new IntArrayStack(); + private final MutableIntStack aliveKeysOffset = new IntArrayStack(); private final int maxKeyCount = pageSize / (bytesKeyOffset() + SIZE_KEY_SIZE + SIZE_VALUE_SIZE); private final int[] oldOffset = new int[maxKeyCount]; private final int[] newOffset = new int[maxKeyCount]; @@ -471,25 +474,25 @@ For each dead space of size X (can be multiple consecutive dead keys) int deadRangeOffset; // Everything between this point and aliveRangeOffset is dead space // Rightmost alive keys does not need to move - while ( deadKeysOffset.peek() < aliveKeysOffset.peek() ) + while ( peek( deadKeysOffset ) < peek( aliveKeysOffset ) ) { - aliveRangeOffset = aliveKeysOffset.poll(); + aliveRangeOffset = poll( aliveKeysOffset ); } do { // Locate next range of dead keys deadRangeOffset = aliveRangeOffset; - while ( aliveKeysOffset.peek() < deadKeysOffset.peek() ) + while ( peek( aliveKeysOffset ) < peek( deadKeysOffset ) ) { - deadRangeOffset = deadKeysOffset.poll(); + deadRangeOffset = poll( deadKeysOffset ); } // Locate next range of alive keys int moveOffset = deadRangeOffset; - while ( deadKeysOffset.peek() < aliveKeysOffset.peek() ) + while ( peek( deadKeysOffset ) < peek( aliveKeysOffset ) ) { - int moveKey = aliveKeysOffset.poll(); + int moveKey = poll( aliveKeysOffset ); oldOffset[oldOffsetCursor++] = moveKey; moveOffset = moveKey; } @@ -551,6 +554,16 @@ For each dead space of size X (can be multiple consecutive dead keys) setDeadSpace( cursor, 0 ); } + private static int peek( IntStack stack ) + { + return stack.isEmpty() ? -1 : stack.peek(); + } + + private static int poll( MutableIntStack stack ) + { + return stack.isEmpty() ? -1 : stack.pop(); + } + @Override boolean leafUnderflow( PageCursor cursor, int keyCount ) { @@ -855,7 +868,7 @@ private int getAllocSpace( PageCursor cursor, int keyCount, Type type ) return allocOffset - endOfOffsetArray; } - private void recordDeadAndAliveLeaf( PageCursor cursor, PrimitiveIntStack deadKeysOffset, PrimitiveIntStack aliveKeysOffset ) + private void recordDeadAndAliveLeaf( PageCursor cursor, MutableIntStack deadKeysOffset, MutableIntStack aliveKeysOffset ) { int currentOffset = getAllocOffset( cursor ); while ( currentOffset < pageSize ) @@ -878,7 +891,7 @@ private void recordDeadAndAliveLeaf( PageCursor cursor, PrimitiveIntStack deadKe } } - private void recordDeadAndAliveInternal( PageCursor cursor, PrimitiveIntStack deadKeysOffset, PrimitiveIntStack aliveKeysOffset ) + private void recordDeadAndAliveInternal( PageCursor cursor, MutableIntStack deadKeysOffset, MutableIntStack aliveKeysOffset ) { int currentOffset = getAllocOffset( cursor ); while ( currentOffset < pageSize ) diff --git a/community/kernel/src/main/java/org/neo4j/unsafe/impl/batchimport/cache/idmapping/string/ParallelSort.java b/community/kernel/src/main/java/org/neo4j/unsafe/impl/batchimport/cache/idmapping/string/ParallelSort.java index 1f7f5d737994b..3186fa7705a8c 100644 --- a/community/kernel/src/main/java/org/neo4j/unsafe/impl/batchimport/cache/idmapping/string/ParallelSort.java +++ b/community/kernel/src/main/java/org/neo4j/unsafe/impl/batchimport/cache/idmapping/string/ParallelSort.java @@ -19,10 +19,12 @@ */ package org.neo4j.unsafe.impl.batchimport.cache.idmapping.string; +import org.eclipse.collections.api.stack.primitive.MutableLongStack; +import org.eclipse.collections.impl.stack.mutable.primitive.LongArrayStack; + import java.util.Arrays; import java.util.concurrent.ThreadLocalRandom; -import org.neo4j.collection.primitive.PrimitiveLongStack; import org.neo4j.helpers.progress.ProgressListener; import org.neo4j.unsafe.impl.batchimport.Utils; import org.neo4j.unsafe.impl.batchimport.Utils.CompareType; @@ -311,13 +313,13 @@ else if ( comparator.ge( right, pivot ) ) private void qsort( long initialStart, long initialEnd ) { - PrimitiveLongStack stack = new PrimitiveLongStack( 100 ); + final MutableLongStack stack = new LongArrayStack(); stack.push( initialStart ); stack.push( initialEnd ); while ( !stack.isEmpty() ) { - long end = stack.poll(); - long start = stack.poll(); + long end = stack.isEmpty() ? -1 : stack.pop(); + long start = stack.isEmpty() ? -1 : stack.pop(); long diff = end - start; if ( diff < 2 ) { diff --git a/community/primitive-collections/src/main/java/org/neo4j/collection/primitive/PrimitiveIntStack.java b/community/primitive-collections/src/main/java/org/neo4j/collection/primitive/PrimitiveIntStack.java deleted file mode 100644 index bdd52c82a3379..0000000000000 --- a/community/primitive-collections/src/main/java/org/neo4j/collection/primitive/PrimitiveIntStack.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * 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.collection.primitive; - -import java.util.NoSuchElementException; - -import static java.util.Arrays.copyOf; - -/** - * Like a {@code Stack} but for primitive ints. Virtually GC free in that it has an {@code int[]} - * and merely moves a cursor where to {@link #push(int)} and {@link #poll()} values to and from. - * If many items goes in the stack the {@code int[]} will grow to accomodate all of them, but not shrink again. - */ -public class PrimitiveIntStack implements PrimitiveIntCollection -{ - private int[] array; - private int cursor = -1; // where the top most item lives - - public PrimitiveIntStack( ) - { - this( 16 ); - } - - public PrimitiveIntStack( int initialSize ) - { - this.array = new int[initialSize]; - } - - @Override - public boolean isEmpty() - { - return cursor == -1; - } - - @Override - public void clear() - { - cursor = -1; - } - - @Override - public int size() - { - return cursor + 1; - } - - @Override - public void close() - { // Nothing to close - } - - @Override - public PrimitiveIntIterator iterator() - { - return new PrimitiveIntIterator() - { - int idx; - - @Override - public boolean hasNext() - { - return idx <= cursor; - } - - @Override - public int next() - { - if ( !hasNext() ) - { - throw new NoSuchElementException(); - } - - return array[idx++]; - } - }; - } - - @Override - public void visitKeys( PrimitiveIntVisitor visitor ) - { - throw new UnsupportedOperationException( "Please implement" ); - } - - public void push( int value ) - { - ensureCapacity(); - array[++cursor] = value; - } - - private void ensureCapacity() - { - if ( cursor == array.length - 1 ) - { - array = copyOf( array, array.length << 1 ); - } - } - - /** - * @return the top most item and remove it from stack, or -1 if stack is empty - */ - public int poll() - { - return cursor == -1 ? -1 : array[cursor--]; - } - - /** - * @return the top most item, or -1 if stack is empty - */ - public int peek() - { - return cursor == -1 ? -1 : array[cursor]; - } -} diff --git a/community/primitive-collections/src/main/java/org/neo4j/collection/primitive/PrimitiveLongStack.java b/community/primitive-collections/src/main/java/org/neo4j/collection/primitive/PrimitiveLongStack.java deleted file mode 100644 index d3650413bc209..0000000000000 --- a/community/primitive-collections/src/main/java/org/neo4j/collection/primitive/PrimitiveLongStack.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * 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.collection.primitive; - -import java.util.NoSuchElementException; - -import static java.util.Arrays.copyOf; - -/** - * Like a {@code Stack} but for primitive longs. Virtually GC free in that it has an {@code long[]} - * and merely moves a cursor where to {@link #push(long)} and {@link #poll()} values to and from. - * If many items goes in the stack the {@code long[]} will grow to accomodate all of them, but not shrink again. - */ -public class PrimitiveLongStack implements PrimitiveLongCollection -{ - private long[] array; - private int cursor = -1; // where the top most item lives - - public PrimitiveLongStack( ) - { - this( 16 ); - } - - public PrimitiveLongStack( int initialSize ) - { - this.array = new long[initialSize]; - } - - @Override - public boolean isEmpty() - { - return cursor == -1; - } - - @Override - public void clear() - { - cursor = -1; - } - - @Override - public int size() - { - return cursor + 1; - } - - @Override - public void close() - { // Nothing to close - } - - @Override - public PrimitiveLongIterator iterator() - { - return new PrimitiveLongIterator() - { - int idx; - - @Override - public boolean hasNext() - { - return idx <= cursor; - } - - @Override - public long next() - { - if ( !hasNext() ) - { - throw new NoSuchElementException(); - } - - return array[idx++]; - } - }; - } - - @Override - public void visitKeys( PrimitiveLongVisitor visitor ) - { - throw new UnsupportedOperationException( "Please implement" ); - } - - public void push( long value ) - { - ensureCapacity(); - array[++cursor] = value; - } - - private void ensureCapacity() - { - if ( cursor == array.length - 1 ) - { - array = copyOf( array, array.length << 1 ); - } - } - - /** - * @return the top most item, or -1 if stack is empty - */ - public long poll() - { - return cursor == -1 ? -1 : array[cursor--]; - } -} diff --git a/community/primitive-collections/src/test/java/org/neo4j/collection/primitive/PrimitiveIntStackTest.java b/community/primitive-collections/src/test/java/org/neo4j/collection/primitive/PrimitiveIntStackTest.java deleted file mode 100644 index ec635e85937e1..0000000000000 --- a/community/primitive-collections/src/test/java/org/neo4j/collection/primitive/PrimitiveIntStackTest.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * 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.collection.primitive; - -import org.junit.Test; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -public class PrimitiveIntStackTest -{ - @Test - public void shouldPushAndPollSomeEntities() - { - // GIVEN - PrimitiveIntStack stack = new PrimitiveIntStack( 6 ); - - // WHEN/THEN - assertTrue( stack.isEmpty() ); - assertEquals( -1, stack.poll() ); - - stack.push( 123 ); - assertFalse( stack.isEmpty() ); - - stack.push( 456 ); - assertFalse( stack.isEmpty() ); - assertEquals( 456, stack.poll() ); - - assertFalse( stack.isEmpty() ); - assertEquals( 123, stack.poll() ); - - assertTrue( stack.isEmpty() ); - assertEquals( -1, stack.poll() ); - } - - @Test - public void shouldGrowArray() - { - // GIVEN - PrimitiveIntStack stack = new PrimitiveIntStack( 5 ); - - // WHEN - for ( int i = 0; i <= 7; i++ ) - { - stack.push( i ); - } - - // THEN - for ( int i = 7; i >= 0; i-- ) - { - assertFalse( stack.isEmpty() ); - assertEquals( i, stack.poll() ); - } - assertTrue( stack.isEmpty() ); - assertEquals( -1, stack.poll() ); - } - - @Test - public void shouldIterate() - { - // GIVEN - PrimitiveIntStack stack = new PrimitiveIntStack(); - - // WHEN - for ( int i = 0; i < 7; i++ ) - { - stack.push( i ); - } - - // THEN - PrimitiveIntIterator iterator = stack.iterator(); - int i = 0; - while ( iterator.hasNext() ) - { - assertEquals( i++, iterator.next() ); - } - assertEquals( 7, i ); - } -} diff --git a/community/primitive-collections/src/test/java/org/neo4j/collection/primitive/PrimitiveLongStackTest.java b/community/primitive-collections/src/test/java/org/neo4j/collection/primitive/PrimitiveLongStackTest.java deleted file mode 100644 index 82ca437297116..0000000000000 --- a/community/primitive-collections/src/test/java/org/neo4j/collection/primitive/PrimitiveLongStackTest.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * 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.collection.primitive; - -import org.junit.Test; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -public class PrimitiveLongStackTest -{ - @Test - public void shouldPushAndPollSomeEntities() - { - // GIVEN - PrimitiveLongStack stack = new PrimitiveLongStack( 6 ); - - // WHEN/THEN - assertTrue( stack.isEmpty() ); - assertEquals( -1, stack.poll() ); - - stack.push( 123 ); - assertFalse( stack.isEmpty() ); - - stack.push( 456 ); - assertFalse( stack.isEmpty() ); - assertEquals( 456, stack.poll() ); - - assertFalse( stack.isEmpty() ); - assertEquals( 123, stack.poll() ); - - assertTrue( stack.isEmpty() ); - assertEquals( -1, stack.poll() ); - } - - @Test - public void shouldGrowArray() - { - // GIVEN - PrimitiveLongStack stack = new PrimitiveLongStack( 5 ); - - // WHEN - for ( int i = 0; i <= 7; i++ ) - { - stack.push( i ); - } - - // THEN - for ( int i = 7; i >= 0; i-- ) - { - assertFalse( stack.isEmpty() ); - assertEquals( i, stack.poll() ); - } - assertTrue( stack.isEmpty() ); - assertEquals( -1, stack.poll() ); - } - - @Test - public void shouldStoreLongs() - { - // GIVEN - PrimitiveLongStack stack = new PrimitiveLongStack( 5 ); - long value1 = 10L * Integer.MAX_VALUE; - long value2 = 101L * Integer.MAX_VALUE; - stack.push( value1 ); - stack.push( value2 ); - - // WHEN - long firstPolledValue = stack.poll(); - long secondPolledValue = stack.poll(); - - // THEN - assertEquals( value2, firstPolledValue ); - assertEquals( value1, secondPolledValue ); - assertTrue( stack.isEmpty() ); - } - - @Test - public void shouldIterate() - { - // GIVEN - PrimitiveLongStack stack = new PrimitiveLongStack(); - - // WHEN - for ( int i = 0; i < 7; i++ ) - { - stack.push( i ); - } - - // THEN - PrimitiveLongIterator iterator = stack.iterator(); - long i = 0; - while ( iterator.hasNext() ) - { - assertEquals( i++, iterator.next() ); - } - assertEquals( 7L, i ); - } -}