From 0f3b60e95abeb9ab7163729eef368924d3ff15af Mon Sep 17 00:00:00 2001 From: GW Date: Wed, 6 May 2026 15:31:04 +0100 Subject: [PATCH] Ensure deep array quality for underlying vector array --- .../driver/internal/AbstractArrayVector.java | 17 +++++- .../driver/internal/InternalVectorTest.java | 52 +++++++++++++++++++ 2 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 driver/src/test/java/org/neo4j/driver/internal/InternalVectorTest.java diff --git a/driver/src/main/java/org/neo4j/driver/internal/AbstractArrayVector.java b/driver/src/main/java/org/neo4j/driver/internal/AbstractArrayVector.java index 4be4eec9f..ff66561a1 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/AbstractArrayVector.java +++ b/driver/src/main/java/org/neo4j/driver/internal/AbstractArrayVector.java @@ -17,6 +17,7 @@ package org.neo4j.driver.internal; import java.lang.reflect.Array; +import java.util.Arrays; import java.util.Objects; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -61,12 +62,12 @@ public boolean equals(Object o) { var that = (AbstractArrayVector) o; return length == that.length && Objects.equals(elementType, that.elementType) - && Objects.equals(elements, that.elements); + && Objects.deepEquals(elements, that.elements); } @Override public int hashCode() { - return Objects.hash(elementType, length, elements); + return Objects.hash(elementType, length, arrayHashCode(elements)); } @Override @@ -81,4 +82,16 @@ private T arraycopy(T elements) { System.arraycopy(elements, 0, result, 0, length); return result; } + + private static int arrayHashCode(Object array) { + if (array instanceof byte[] value) return Arrays.hashCode(value); + if (array instanceof short[] value) return Arrays.hashCode(value); + if (array instanceof int[] value) return Arrays.hashCode(value); + if (array instanceof long[] value) return Arrays.hashCode(value); + if (array instanceof float[] value) return Arrays.hashCode(value); + if (array instanceof double[] value) return Arrays.hashCode(value); + if (array instanceof char[] value) return Arrays.hashCode(value); + if (array instanceof boolean[] value) return Arrays.hashCode(value); + return Arrays.deepHashCode((Object[]) array); + } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/InternalVectorTest.java b/driver/src/test/java/org/neo4j/driver/internal/InternalVectorTest.java new file mode 100644 index 000000000..32dcac2a7 --- /dev/null +++ b/driver/src/test/java/org/neo4j/driver/internal/InternalVectorTest.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) "Neo4j" + * Neo4j Sweden AB [https://neo4j.com] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.neo4j.driver.internal; + +import java.util.stream.Stream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class InternalVectorTest { + + @ParameterizedTest + @MethodSource("vectors") + void shouldRespectEqualityAndHashCode(AbstractArrayVector vector1, AbstractArrayVector vector2) { + assertEquals(vector1, vector2); + assertEquals(vector1.hashCode(), vector2.hashCode()); + } + + private static Stream vectors() { + return Stream.of( + Arguments.of(new InternalInt8Vector(new byte[] {1, 2, 3}), new InternalInt8Vector(new byte[] {1, 2, 3})), + Arguments.of( + new InternalInt16Vector(new short[] {1, 2, 3}), + new InternalInt16Vector(new short[] {1, 2, 3})), + Arguments.of(new InternalInt32Vector(new int[] {1, 2, 3}), new InternalInt32Vector(new int[] {1, 2, 3})), + Arguments.of( + new InternalInt64Vector(new long[] {1L, 2L, 3L}), + new InternalInt64Vector(new long[] {1L, 2L, 3L})), + Arguments.of( + new InternalFloat32Vector(new float[] {1.1F, 2.2F, 3.3F}), + new InternalFloat32Vector(new float[] {1.1F, 2.2F, 3.3F})), + Arguments.of( + new InternalFloat64Vector(new double[] {1.1D, 2.2D, 3.3D}), + new InternalFloat64Vector(new double[] {1.1D, 2.2D, 3.3D}))); + } +} \ No newline at end of file