diff --git a/community/kernel-api/src/test/java/org/neo4j/internal/kernel/api/helpers/NodeData.java b/community/kernel-api/src/test/java/org/neo4j/internal/kernel/api/helpers/NodeData.java index afa3fe79ab1cf..0316f74f8799f 100644 --- a/community/kernel-api/src/test/java/org/neo4j/internal/kernel/api/helpers/NodeData.java +++ b/community/kernel-api/src/test/java/org/neo4j/internal/kernel/api/helpers/NodeData.java @@ -33,13 +33,20 @@ class NodeData NodeData( long id, long[] labels, Map properties ) { + if ( labels == null ) + { + throw new IllegalArgumentException(); + } + this.id = id; this.labels = labels; + Arrays.sort( labels ); // needed for quick equality check, most of the time, its already sorted anyway this.properties = properties; } LabelSet labelSet() { + return new LabelSet() { @Override @@ -51,7 +58,7 @@ public int numberOfLabels() @Override public int label( int offset ) { - return labels.length; + return (int) labels[offset]; } @Override @@ -84,7 +91,18 @@ public boolean equals( Object obj ) { if ( obj instanceof LabelSet ) { - return Arrays.equals( labels, ((LabelSet) obj).all() ); + long[] input = ((LabelSet) obj).all(); + + if ( labels == input ) + { + return true; + } + if ( input.length != labels.length ) + { + return false; + } + + return Arrays.equals( labels, input ); } return false; } diff --git a/community/kernel-api/src/test/java/org/neo4j/internal/kernel/api/helpers/NodeDataTest.java b/community/kernel-api/src/test/java/org/neo4j/internal/kernel/api/helpers/NodeDataTest.java new file mode 100644 index 0000000000000..3a35da8526c7f --- /dev/null +++ b/community/kernel-api/src/test/java/org/neo4j/internal/kernel/api/helpers/NodeDataTest.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2002-2018 "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.internal.kernel.api.helpers; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class NodeDataTest +{ + @Test + void testEqualityOfLabelSets() + { + long[] longsA = new long[]{1L,2L,3L}; + long[] longsB = new long[]{3L,2L,1L}; + long[] longsC = new long[]{1L,2L,3L,4L}; + NodeData a = new NodeData( 1, longsA, null ); + NodeData b = new NodeData( 1, longsB, null ); + NodeData c = new NodeData( 1, longsC, null ); + + // self + assertTrue(a.labelSet().equals( a.labelSet() )); + + // unordered self + assertTrue(a.labelSet().equals( b.labelSet() )); + assertTrue(b.labelSet().equals( a.labelSet() )); + + // other + assertFalse(a.labelSet().equals( c.labelSet() )); + assertFalse(c.labelSet().equals( a.labelSet() )); + } + + @Test + void testHashCodeOfLabelSet() + { + long[] longsA = new long[]{1L,2L,3L}; + long[] longsB = new long[]{3L,2L,1L}; + long[] longsC = new long[]{1L,2L,3L,4L}; + NodeData a = new NodeData( 1, longsA, null ); + NodeData b = new NodeData( 1, longsB, null ); + NodeData c = new NodeData( 1, longsC, null ); + + assertEquals( a.labelSet().hashCode(), b.labelSet().hashCode() ); + assertNotEquals( a.labelSet().hashCode(), c.labelSet().hashCode() ); + } +} diff --git a/community/kernel/src/main/java/org/neo4j/kernel/builtinprocs/BuiltInProcedures.java b/community/kernel/src/main/java/org/neo4j/kernel/builtinprocs/BuiltInProcedures.java index a46aa11dfefc2..4157e551915fb 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/builtinprocs/BuiltInProcedures.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/builtinprocs/BuiltInProcedures.java @@ -194,21 +194,13 @@ public void resampleOutdatedIndexes() } } - @Procedure( name = "db.schemaAsTable", mode = Mode.READ ) // I am open about a better name for this. Something like db.propertySchema maybe? - @Description( "Show the schema of the data in tabular form." ) - public Stream schemaAsTable() + @Procedure( name = "db.propertySchema", mode = Mode.READ ) + @Description( "Show the derived property schema of the data in tabular form." ) + public Stream propertySchema() { return new SchemaCalculator( tx ).calculateTabularResultStream(); } - // TODO: Next step -> graph with more info then db.schema currently has -// @Procedure( value = "db.schema.graph", mode = Mode.READ ) -// @Description( "Show the schema of the data." ) // old description -// public Stream schemaAsGraph() -// { -// return new SchemaCalculator( db, tx ).calculateGraphResultStream(); -// } - @Description( "Show the schema of the data." ) @Procedure( name = "db.schema", mode = READ ) public Stream metaGraph() diff --git a/community/kernel/src/main/java/org/neo4j/kernel/builtinprocs/SchemaCalculator.java b/community/kernel/src/main/java/org/neo4j/kernel/builtinprocs/SchemaCalculator.java index 38bba8d6bb19c..7649b9bef6e7d 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/builtinprocs/SchemaCalculator.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/builtinprocs/SchemaCalculator.java @@ -69,8 +69,6 @@ public class SchemaCalculator private final String NODE = "Node"; private final String RELATIONSHIP = "Relationship"; - //TODO: Extend this to support showing how relationships types connect to nodes - SchemaCalculator( KernelTransaction ktx ) { this.ktx = ktx; diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/Labels.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/Labels.java index 19d20098dfd46..9ad347a57c32f 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/Labels.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/Labels.java @@ -36,6 +36,7 @@ public class Labels implements LabelSet private Labels( long[] labels ) { this.labels = labels; + Arrays.sort(labels); // needed for quick equality check, most of the time, its already sorted anyway } public static Labels from( long[] labels ) @@ -100,7 +101,18 @@ public boolean equals( Object obj ) { if ( obj instanceof LabelSet ) { - return Arrays.equals( labels, ((LabelSet) obj).all() ); + long[] input = ((LabelSet) obj).all(); + + if ( labels == input ) + { + return true; + } + if ( input.length != labels.length ) + { + return false; + } + + return Arrays.equals(labels, input); } return false; } diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/integrationtest/BuiltInSchemaProceduresIT.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/integrationtest/BuiltInSchemaProceduresIT.java index b78958bf203a1..44b39b4b47c6b 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/integrationtest/BuiltInSchemaProceduresIT.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/integrationtest/BuiltInSchemaProceduresIT.java @@ -80,7 +80,7 @@ public void testSchemaTableWithNodes() throws Throwable // When RawIterator stream = - procs().procedureCallRead( procs().procedureGet( procedureName( "db", "schemaAsTable" ) ).id(), new Object[0] ); + procs().procedureCallRead( procs().procedureGet( procedureName( "db", "propertySchema" ) ).id(), new Object[0] ); // Then assertThat( asList( stream ), containsInAnyOrder( @@ -115,7 +115,7 @@ public void testSchemaTableWithSimilarNodes() throws Throwable // When RawIterator stream = - procs().procedureCallRead( procs().procedureGet( procedureName( "db", "schemaAsTable" ) ).id(), new Object[0] ); + procs().procedureCallRead( procs().procedureGet( procedureName( "db", "propertySchema" ) ).id(), new Object[0] ); // Then assertThat( asList( stream ), contains( @@ -151,7 +151,7 @@ public void testSchemaTableWithSimilarNodesHavingDifferentPropertyValueTypes() t // When RawIterator stream = - procs().procedureCallRead( procs().procedureGet( procedureName( "db", "schemaAsTable" ) ).id(), new Object[0] ); + procs().procedureCallRead( procs().procedureGet( procedureName( "db", "propertySchema" ) ).id(), new Object[0] ); // Then assertThat( asList( stream ), containsInAnyOrder( @@ -190,7 +190,7 @@ public void testSchemaTableWithRelationships() throws Throwable // When RawIterator stream = - procs().procedureCallRead( procs().procedureGet( procedureName( "db", "schemaAsTable" ) ).id(), new Object[0] ); + procs().procedureCallRead( procs().procedureGet( procedureName( "db", "propertySchema" ) ).id(), new Object[0] ); // Then assertThat( asList( stream ), containsInAnyOrder( equalTo( new Object[]{"Relationship", Arrays.asList( "R" ), "prop1", "STRING"} ), @@ -224,7 +224,7 @@ public void testSchemaTableWithSimilarRelationships() throws Throwable // When RawIterator stream = - procs().procedureCallRead( procs().procedureGet( procedureName( "db", "schemaAsTable" ) ).id(), new Object[0] ); + procs().procedureCallRead( procs().procedureGet( procedureName( "db", "propertySchema" ) ).id(), new Object[0] ); // Then assertThat( asList( stream ), containsInAnyOrder( @@ -264,7 +264,7 @@ public void testSchemaTableWithSimilarRelationshipsHavingDifferentPropertyValueT // When RawIterator stream = - procs().procedureCallRead( procs().procedureGet( procedureName( "db", "schemaAsTable" ) ).id(), new Object[0] ); + procs().procedureCallRead( procs().procedureGet( procedureName( "db", "propertySchema" ) ).id(), new Object[0] ); // Then assertThat( asList( stream ), containsInAnyOrder( @@ -319,7 +319,7 @@ public void testSchemaTableWithNullableProperties() throws Throwable // When RawIterator stream = - procs().procedureCallRead( procs().procedureGet( procedureName( "db", "schemaAsTable" ) ).id(), new Object[0] ); + procs().procedureCallRead( procs().procedureGet( procedureName( "db", "propertySchema" ) ).id(), new Object[0] ); // Then assertThat( asList( stream ), containsInAnyOrder( diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/newapi/LabelsTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/newapi/LabelsTest.java new file mode 100644 index 0000000000000..5341d9a3b0f6c --- /dev/null +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/newapi/LabelsTest.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2002-2018 "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.newapi; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class LabelsTest +{ + @Test + void testEquals() + { + long[] longsA = new long[]{1L, 2L, 3L}; + long[] longsB = new long[]{3L, 2L, 1L}; + long[] longsC = new long[]{1L, 2L, 3L, 4L}; + Labels a = Labels.from( longsA ); + Labels b = Labels.from( longsB ); + Labels c = Labels.from( longsC ); + + // self + //noinspection EqualsWithItself + assertTrue( a.equals( a ) ); + + // unordered self + assertTrue( a.equals( b ) ); + assertTrue( b.equals( a ) ); + + // other + assertFalse( a.equals( c ) ); + assertFalse( c.equals( a ) ); + } + + @Test + void testHashCodeOfLabelSet() + { + long[] longsA = new long[]{1L,2L,3L}; + long[] longsB = new long[]{3L,2L,1L}; + long[] longsC = new long[]{1L,2L,3L,4L}; + Labels a = Labels.from( longsA ); + Labels b = Labels.from( longsB ); + Labels c = Labels.from( longsC ); + + assertEquals( a.hashCode(), b.hashCode() ); + assertNotEquals( a.hashCode(), c.hashCode() ); + } +}