This is an automated email from the ASF dual-hosted git repository. aherbert pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-collections.git
commit 55cb720ccf2138dc230f27f5db123122a0388ba0 Author: aherbert <a.herb...@sussex.ac.uk> AuthorDate: Tue Feb 18 13:35:58 2020 +0000 Remove HashFunctionIdentity comparators. The comparators are never used to perform ordering of functions. The only current use is to determine that two hash functions are functionally equivalent. A replacement utility class has been added to test for equality. --- .../bloomfilter/AbstractBloomFilter.java | 3 + .../bloomfilter/hasher/DynamicHasher.java | 9 +- .../bloomfilter/hasher/HashFunctionIdentity.java | 37 +--- .../bloomfilter/hasher/HashFunctionValidator.java | 61 +++++++ .../collections4/bloomfilter/hasher/Shape.java | 6 +- .../bloomfilter/hasher/StaticHasher.java | 7 +- .../bloomfilter/hasher/CommonComparatorTest.java | 161 ------------------ .../bloomfilter/hasher/DeepComparatorTest.java | 188 --------------------- .../hasher/HashFuctionValidatorTest.java | 120 +++++++++++++ .../bloomfilter/hasher/StaticHasherTest.java | 6 +- 10 files changed, 197 insertions(+), 401 deletions(-) diff --git a/src/main/java/org/apache/commons/collections4/bloomfilter/AbstractBloomFilter.java b/src/main/java/org/apache/commons/collections4/bloomfilter/AbstractBloomFilter.java index 992631c..1339dac 100644 --- a/src/main/java/org/apache/commons/collections4/bloomfilter/AbstractBloomFilter.java +++ b/src/main/java/org/apache/commons/collections4/bloomfilter/AbstractBloomFilter.java @@ -212,6 +212,9 @@ public abstract class AbstractBloomFilter implements BloomFilter { * @param hasher the Hasher to check */ protected void verifyHasher(final Hasher hasher) { + // It is assumed that the filter and hasher have been constructed using the + // same hash function. Use the signature for a fast check the hash function is equal. + // Collisions will occur at a rate of 1 in 2^64. if (shape.getHashFunctionIdentity().getSignature() != hasher.getHashFunctionIdentity().getSignature()) { throw new IllegalArgumentException( String.format("Hasher (%s) is not the hasher for shape (%s)", diff --git a/src/main/java/org/apache/commons/collections4/bloomfilter/hasher/DynamicHasher.java b/src/main/java/org/apache/commons/collections4/bloomfilter/hasher/DynamicHasher.java index f3d10a4..68991c5 100644 --- a/src/main/java/org/apache/commons/collections4/bloomfilter/hasher/DynamicHasher.java +++ b/src/main/java/org/apache/commons/collections4/bloomfilter/hasher/DynamicHasher.java @@ -177,13 +177,8 @@ public class DynamicHasher implements Hasher { */ @Override public PrimitiveIterator.OfInt getBits(final Shape shape) { - if (HashFunctionIdentity.COMMON_COMPARATOR.compare(getHashFunctionIdentity(), - shape.getHashFunctionIdentity()) != 0) { - throw new IllegalArgumentException( - String.format("Shape hasher %s is not %s", - HashFunctionIdentity.asCommonString(shape.getHashFunctionIdentity()), - HashFunctionIdentity.asCommonString(getHashFunctionIdentity()))); - } + HashFunctionValidator.checkAreEqual(getHashFunctionIdentity(), + shape.getHashFunctionIdentity()); // Use optimised iterator for no values return buffers.isEmpty() ? NoValuesIterator.INSTANCE : new Iterator(shape); } diff --git a/src/main/java/org/apache/commons/collections4/bloomfilter/hasher/HashFunctionIdentity.java b/src/main/java/org/apache/commons/collections4/bloomfilter/hasher/HashFunctionIdentity.java index 2b9ac52..7a58d44 100644 --- a/src/main/java/org/apache/commons/collections4/bloomfilter/hasher/HashFunctionIdentity.java +++ b/src/main/java/org/apache/commons/collections4/bloomfilter/hasher/HashFunctionIdentity.java @@ -18,7 +18,6 @@ package org.apache.commons.collections4.bloomfilter.hasher; import java.nio.charset.StandardCharsets; -import java.util.Comparator; import java.util.Locale; /** @@ -64,39 +63,6 @@ public interface HashFunctionIdentity { } /** - * A comparator implementation that performs the most common comparison using the - * HashFunctionIdentity name, signedness, and process. - */ - Comparator<HashFunctionIdentity> COMMON_COMPARATOR = new Comparator<HashFunctionIdentity>() { - @Override - public int compare(final HashFunctionIdentity identity1, final HashFunctionIdentity identity2) { - int result = identity1.getName().compareToIgnoreCase(identity2.getName()); - if (result == 0) { - result = identity1.getSignedness().compareTo(identity2.getSignedness()); - } - if (result == 0) { - result = identity1.getProcessType().compareTo(identity2.getProcessType()); - } - return result; - } - }; - - /** - * A comparator implementation that performs the comparison using all the properties of the - * HashFunctionIdentity: name, signedness, process, and provider. - */ - Comparator<HashFunctionIdentity> DEEP_COMPARATOR = new Comparator<HashFunctionIdentity>() { - @Override - public int compare(final HashFunctionIdentity identity1, final HashFunctionIdentity identity2) { - int result = COMMON_COMPARATOR.compare(identity1, identity2); - if (result == 0) { - result = identity1.getProvider().compareToIgnoreCase(identity2.getProvider()); - } - return result; - } - }; - - /** * Gets a common formatted string for general display. * * @param identity the identity to format. @@ -119,10 +85,9 @@ public interface HashFunctionIdentity { * @return the signature buffer for the identity */ static byte[] prepareSignatureBuffer(final HashFunctionIdentity identity) { - return String.format("%s-%s-%s", identity.getName().toUpperCase(Locale.ROOT), identity.getSignedness(), - identity.getProcessType() ).getBytes(StandardCharsets.UTF_8); + identity.getProcessType()).getBytes(StandardCharsets.UTF_8); } /** diff --git a/src/main/java/org/apache/commons/collections4/bloomfilter/hasher/HashFunctionValidator.java b/src/main/java/org/apache/commons/collections4/bloomfilter/hasher/HashFunctionValidator.java new file mode 100644 index 0000000..602dcde --- /dev/null +++ b/src/main/java/org/apache/commons/collections4/bloomfilter/hasher/HashFunctionValidator.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.commons.collections4.bloomfilter.hasher; + +/** + * Contains validation for hash functions. + */ +final class HashFunctionValidator { + /** Do not instantiate. */ + private HashFunctionValidator() {} + + /** + * Compares the identity of the two hash functions. The functions are considered + * equal if the signedness, process type and name are equal. The name is not + * case specific. + * + * <p>A pair of functions that are equal would be expected to produce the same + * hash output from the same input. + * + * @param a First hash function. + * @param b Second hash function. + * @return true, if successful + * @see String#equalsIgnoreCase(String) + */ + static boolean areEqual(HashFunctionIdentity a, HashFunctionIdentity b) { + return (a.getSignedness() == b.getSignedness() && + a.getProcessType() == b.getProcessType() && + a.getName().equalsIgnoreCase(b.getName())); + } + + /** + * Compares the identity of the two hash functions and throws an exception if they + * are not equal. + * + * @param a First hash function. + * @param b Second hash function. + * @see #areEqual(HashFunctionIdentity, HashFunctionIdentity) + * @throws IllegalArgumentException if the hash functions are not equal + */ + static void checkAreEqual(HashFunctionIdentity a, HashFunctionIdentity b) { + if (!areEqual(a, b)) { + throw new IllegalArgumentException(String.format("Hash functions are not equal: (%s) != (%s)", + HashFunctionIdentity.asCommonString(a), HashFunctionIdentity.asCommonString(b))); + } + } +} diff --git a/src/main/java/org/apache/commons/collections4/bloomfilter/hasher/Shape.java b/src/main/java/org/apache/commons/collections4/bloomfilter/hasher/Shape.java index b241650..956575f 100644 --- a/src/main/java/org/apache/commons/collections4/bloomfilter/hasher/Shape.java +++ b/src/main/java/org/apache/commons/collections4/bloomfilter/hasher/Shape.java @@ -232,7 +232,7 @@ public class Shape { * @param numberOfBits the number of bits in the filter. * @return the optimal number of hash functions. */ - private int calculateNumberOfHashFunctions(final int numberOfItems, final int numberOfBits) { + private static int calculateNumberOfHashFunctions(final int numberOfItems, final int numberOfBits) { /* * k = round((m / n) * log(2)) We change order so that we use real math rather * than integer math. @@ -258,8 +258,8 @@ public class Shape { return other.getNumberOfBits() == getNumberOfBits() && other.getNumberOfHashFunctions() == getNumberOfHashFunctions() && - HashFunctionIdentity.COMMON_COMPARATOR.compare(getHashFunctionIdentity(), - other.getHashFunctionIdentity()) == 0; + HashFunctionValidator.areEqual(getHashFunctionIdentity(), + other.getHashFunctionIdentity()); } return false; } diff --git a/src/main/java/org/apache/commons/collections4/bloomfilter/hasher/StaticHasher.java b/src/main/java/org/apache/commons/collections4/bloomfilter/hasher/StaticHasher.java index 9ad102c..b17bf8e 100644 --- a/src/main/java/org/apache/commons/collections4/bloomfilter/hasher/StaticHasher.java +++ b/src/main/java/org/apache/commons/collections4/bloomfilter/hasher/StaticHasher.java @@ -48,11 +48,8 @@ public final class StaticHasher implements Hasher { */ public StaticHasher(final Hasher hasher, final Shape shape) { this(hasher.getBits(shape), shape); - if (HashFunctionIdentity.COMMON_COMPARATOR.compare(hasher.getHashFunctionIdentity(), - shape.getHashFunctionIdentity()) != 0) { - throw new IllegalArgumentException(String.format("Hasher (%s) is not the same as for shape (%s)", - HashFunctionIdentity.asCommonString(hasher.getHashFunctionIdentity()), shape.toString())); - } + HashFunctionValidator.checkAreEqual(hasher.getHashFunctionIdentity(), + shape.getHashFunctionIdentity()); } /** diff --git a/src/test/java/org/apache/commons/collections4/bloomfilter/hasher/CommonComparatorTest.java b/src/test/java/org/apache/commons/collections4/bloomfilter/hasher/CommonComparatorTest.java deleted file mode 100644 index da0f1f6..0000000 --- a/src/test/java/org/apache/commons/collections4/bloomfilter/hasher/CommonComparatorTest.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.apache.commons.collections4.bloomfilter.hasher; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.TreeSet; - -import org.apache.commons.collections4.bloomfilter.hasher.HashFunctionIdentity.ProcessType; -import org.apache.commons.collections4.bloomfilter.hasher.HashFunctionIdentity.Signedness; -import org.junit.Test; - -/** - * Tests of the {@link HashFunctionIdentity#COMMON_COMPARATOR}. - */ -public class CommonComparatorTest { - - private static void assertAfter(final HashFunctionIdentity identity1, final HashFunctionIdentity identity2) { - assertTrue(0 < HashFunctionIdentity.COMMON_COMPARATOR.compare(identity1, identity2)); - } - - private static void assertBefore(final HashFunctionIdentity identity1, final HashFunctionIdentity identity2) { - assertTrue(0 > HashFunctionIdentity.COMMON_COMPARATOR.compare(identity1, identity2)); - } - - /** - * Tests the name ordering is not affected by case. - */ - @Test - public void nameOrderTestDifferentCapitalization() { - final HashFunctionIdentityImpl impl1 = new HashFunctionIdentityImpl("Testing Suite", "impl1", Signedness.SIGNED, - ProcessType.CYCLIC, 300L); - final HashFunctionIdentityImpl impl2 = new HashFunctionIdentityImpl("Testing Suite", "IMPL1", Signedness.SIGNED, - ProcessType.CYCLIC, 300L); - - assertEquals(0, HashFunctionIdentity.COMMON_COMPARATOR.compare(impl1, impl2)); - } - - /** - * Tests the name ordering. - */ - @Test - public void nameOrderTestDifferentNames() { - final HashFunctionIdentityImpl impl1 = new HashFunctionIdentityImpl("Testing Suite", "impl1", Signedness.SIGNED, - ProcessType.CYCLIC, 300L); - final HashFunctionIdentityImpl impl2 = new HashFunctionIdentityImpl("Testing Suite", "impl2", Signedness.SIGNED, - ProcessType.CYCLIC, 300L); - - assertBefore(impl1, impl2); - assertEquals(0, HashFunctionIdentity.COMMON_COMPARATOR.compare(impl1, impl1)); - assertEquals(0, HashFunctionIdentity.COMMON_COMPARATOR.compare(impl2, impl2)); - assertAfter(impl2, impl1); - } - - /** - * Tests that the process type ordering in correct. - */ - @Test - public void processTypeOrder() { - final HashFunctionIdentityImpl impl1 = new HashFunctionIdentityImpl("Testing Suite", "impl1", Signedness.SIGNED, - ProcessType.CYCLIC, 300L); - final HashFunctionIdentityImpl impl2 = new HashFunctionIdentityImpl("Testing Suite", "impl1", Signedness.SIGNED, - ProcessType.ITERATIVE, 300L); - - assertBefore(impl1, impl2); - assertEquals(0, HashFunctionIdentity.COMMON_COMPARATOR.compare(impl1, impl1)); - assertEquals(0, HashFunctionIdentity.COMMON_COMPARATOR.compare(impl2, impl2)); - assertAfter(impl2, impl1); - } - - /** - * Tests that a change in producer does not change the order. - */ - @Test - public void producerDoesNotChangeOrder() { - final HashFunctionIdentityImpl impl1 = new HashFunctionIdentityImpl("Testing Suite", "impl1", Signedness.SIGNED, - ProcessType.CYCLIC, 300L); - final HashFunctionIdentityImpl impl2 = new HashFunctionIdentityImpl("Testing Suite2", "impl1", Signedness.SIGNED, - ProcessType.CYCLIC, 300L); - - assertEquals(0, HashFunctionIdentity.COMMON_COMPARATOR.compare(impl1, impl2)); - } - - /** - * Tests that signedness ordering is correct. - */ - @Test - public void signednessOrder() { - final HashFunctionIdentityImpl impl1 = new HashFunctionIdentityImpl("Testing Suite", "impl1", Signedness.SIGNED, - ProcessType.CYCLIC, 300L); - final HashFunctionIdentityImpl impl2 = new HashFunctionIdentityImpl("Testing Suite", "impl1", Signedness.UNSIGNED, - ProcessType.CYCLIC, 300L); - - assertBefore(impl1, impl2); - assertEquals(0, HashFunctionIdentity.COMMON_COMPARATOR.compare(impl1, impl1)); - assertEquals(0, HashFunctionIdentity.COMMON_COMPARATOR.compare(impl2, impl2)); - assertAfter(impl2, impl1); - } - - /** - * Tests that the ordering is correct when applied ot a collection. - */ - @Test - public void testSortOrder() { - // in this test the signature is the position in the final collection for the ID - final TreeSet<HashFunctionIdentity> result = new TreeSet<>( - HashFunctionIdentity.COMMON_COMPARATOR); - final List<HashFunctionIdentity> collection = new ArrayList<>(); - - collection - .add(new HashFunctionIdentityImpl("Testing Suite", "impl1", Signedness.SIGNED, ProcessType.CYCLIC, 0)); - - collection - .add(new HashFunctionIdentityImpl("Testing Suite", "impl1", Signedness.SIGNED, ProcessType.ITERATIVE, 1)); - - collection - .add(new HashFunctionIdentityImpl("Testing Suite", "impl1", Signedness.UNSIGNED, ProcessType.CYCLIC, 2)); - - collection - .add(new HashFunctionIdentityImpl("Testing Suite", "impl1", Signedness.UNSIGNED, ProcessType.ITERATIVE, 3)); - - collection - .add(new HashFunctionIdentityImpl("Testing Suite", "impl2", Signedness.SIGNED, ProcessType.CYCLIC, 4)); - - collection - .add(new HashFunctionIdentityImpl("Testing Suite", "impl2", Signedness.SIGNED, ProcessType.ITERATIVE, 5)); - - collection - .add(new HashFunctionIdentityImpl("Testing Suite", "impl2", Signedness.UNSIGNED, ProcessType.CYCLIC, 6)); - - collection - .add(new HashFunctionIdentityImpl("Testing Suite", "impl2", Signedness.UNSIGNED, ProcessType.ITERATIVE, 7)); - - Collections.shuffle(collection); - - result.addAll(collection); - long idx = 0; - for (final HashFunctionIdentity id : result) { - assertEquals("Unexpected order for " + HashFunctionIdentity.asCommonString(id), idx++, id.getSignature()); - } - } -} diff --git a/src/test/java/org/apache/commons/collections4/bloomfilter/hasher/DeepComparatorTest.java b/src/test/java/org/apache/commons/collections4/bloomfilter/hasher/DeepComparatorTest.java deleted file mode 100644 index c4f8d46..0000000 --- a/src/test/java/org/apache/commons/collections4/bloomfilter/hasher/DeepComparatorTest.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.apache.commons.collections4.bloomfilter.hasher; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.TreeSet; - -import org.apache.commons.collections4.bloomfilter.hasher.HashFunctionIdentity.ProcessType; -import org.apache.commons.collections4.bloomfilter.hasher.HashFunctionIdentity.Signedness; -import org.junit.Test; - -/** - * Tests of the {@link HashFunctionIdentity#DEEP_COMPARATOR}. - */ -public class DeepComparatorTest { - - private static void assertAfter(final HashFunctionIdentity identity1, final HashFunctionIdentity identity2) { - assertTrue(0 < HashFunctionIdentity.DEEP_COMPARATOR.compare(identity1, identity2)); - } - - private static void assertBefore(final HashFunctionIdentity identity1, final HashFunctionIdentity identity2) { - assertTrue(0 > HashFunctionIdentity.DEEP_COMPARATOR.compare(identity1, identity2)); - } - - /** - * Tests that name order is not affected by case. - */ - @Test - public void nameOrderTestDifferentCapitalization() { - final HashFunctionIdentityImpl impl1 = new HashFunctionIdentityImpl("Testing Suite", "impl1", Signedness.SIGNED, - ProcessType.CYCLIC, 300L); - final HashFunctionIdentityImpl impl2 = new HashFunctionIdentityImpl("Testing Suite", "IMPL1", Signedness.SIGNED, - ProcessType.CYCLIC, 300L); - - assertEquals(0, HashFunctionIdentity.DEEP_COMPARATOR.compare(impl1, impl2)); - } - - /** - * Tests that name order is correct. - */ - @Test - public void nameOrderTestDifferentNames() { - final HashFunctionIdentityImpl impl1 = new HashFunctionIdentityImpl("Testing Suite", "impl1", Signedness.SIGNED, - ProcessType.CYCLIC, 300L); - final HashFunctionIdentityImpl impl2 = new HashFunctionIdentityImpl("Testing Suite", "impl2", Signedness.SIGNED, - ProcessType.CYCLIC, 300L); - - assertBefore(impl1, impl2); - assertEquals(0, HashFunctionIdentity.DEEP_COMPARATOR.compare(impl1, impl1)); - assertEquals(0, HashFunctionIdentity.DEEP_COMPARATOR.compare(impl2, impl2)); - assertAfter(impl2, impl1); - } - - /** - * Tests that process type order is correct. - */ - @Test - public void processTypeOrder() { - final HashFunctionIdentityImpl impl1 = new HashFunctionIdentityImpl("Testing Suite", "impl1", Signedness.SIGNED, - ProcessType.CYCLIC, 300L); - final HashFunctionIdentityImpl impl2 = new HashFunctionIdentityImpl("Testing Suite", "impl1", Signedness.SIGNED, - ProcessType.ITERATIVE, 300L); - - assertBefore(impl1, impl2); - assertEquals(0, HashFunctionIdentity.DEEP_COMPARATOR.compare(impl1, impl1)); - assertEquals(0, HashFunctionIdentity.DEEP_COMPARATOR.compare(impl2, impl2)); - assertAfter(impl2, impl1); - } - - /** - * Tests that producer order is correct. - */ - @Test - public void producerOrder() { - final HashFunctionIdentityImpl impl1 = new HashFunctionIdentityImpl("Testing Suite", "impl1", Signedness.SIGNED, - ProcessType.CYCLIC, 300L); - final HashFunctionIdentityImpl impl2 = new HashFunctionIdentityImpl("Testing Suite2", "impl1", Signedness.SIGNED, - ProcessType.CYCLIC, 300L); - - assertBefore(impl1, impl2); - assertEquals(0, HashFunctionIdentity.DEEP_COMPARATOR.compare(impl1, impl1)); - assertEquals(0, HashFunctionIdentity.DEEP_COMPARATOR.compare(impl2, impl2)); - assertAfter(impl2, impl1); - } - - /** - * Tests that signedness order is correct. - */ - @Test - public void signednessOrder() { - final HashFunctionIdentityImpl impl1 = new HashFunctionIdentityImpl("Testing Suite", "impl1", Signedness.SIGNED, - ProcessType.CYCLIC, 300L); - final HashFunctionIdentityImpl impl2 = new HashFunctionIdentityImpl("Testing Suite", "impl1", Signedness.UNSIGNED, - ProcessType.CYCLIC, 300L); - - assertBefore(impl1, impl2); - assertEquals(0, HashFunctionIdentity.DEEP_COMPARATOR.compare(impl1, impl1)); - assertEquals(0, HashFunctionIdentity.DEEP_COMPARATOR.compare(impl2, impl2)); - assertAfter(impl2, impl1); - } - - /** - * Tests that the ordering is correct when applied ot a collection. - */ - @Test - public void testSortOrder() { - // in this test the signature is the position in the final collection for the ID - final TreeSet<HashFunctionIdentity> result = new TreeSet<>(HashFunctionIdentity.DEEP_COMPARATOR); - final List<HashFunctionIdentity> collection = new ArrayList<>(); - - collection - .add(new HashFunctionIdentityImpl("Testing Suite", "impl1", Signedness.SIGNED, ProcessType.CYCLIC, 0)); - - collection - .add(new HashFunctionIdentityImpl("Testing Suite", "impl1", Signedness.SIGNED, ProcessType.ITERATIVE, 2)); - - collection - .add(new HashFunctionIdentityImpl("Testing Suite", "impl1", Signedness.UNSIGNED, ProcessType.CYCLIC, 4)); - - collection - .add(new HashFunctionIdentityImpl("Testing Suite", "impl1", Signedness.UNSIGNED, ProcessType.ITERATIVE, 6)); - - collection - .add(new HashFunctionIdentityImpl("Testing Suite", "impl2", Signedness.SIGNED, ProcessType.CYCLIC, 8)); - - collection - .add(new HashFunctionIdentityImpl("Testing Suite", "impl2", Signedness.SIGNED, ProcessType.ITERATIVE, 10)); - - collection - .add(new HashFunctionIdentityImpl("Testing Suite", "impl2", Signedness.UNSIGNED, ProcessType.CYCLIC, 12)); - - collection.add( - new HashFunctionIdentityImpl("Testing Suite", "impl2", Signedness.UNSIGNED, ProcessType.ITERATIVE, 14)); - - collection - .add(new HashFunctionIdentityImpl("Testing Suite2", "impl1", Signedness.SIGNED, ProcessType.CYCLIC, 1)); - - collection - .add(new HashFunctionIdentityImpl("Testing Suite2", "impl1", Signedness.SIGNED, ProcessType.ITERATIVE, 3)); - - collection - .add(new HashFunctionIdentityImpl("Testing Suite2", "impl1", Signedness.UNSIGNED, ProcessType.CYCLIC, 5)); - - collection.add( - new HashFunctionIdentityImpl("Testing Suite2", "impl1", Signedness.UNSIGNED, ProcessType.ITERATIVE, 7)); - - collection - .add(new HashFunctionIdentityImpl("Testing Suite2", "impl2", Signedness.SIGNED, ProcessType.CYCLIC, 9)); - - collection - .add(new HashFunctionIdentityImpl("Testing Suite2", "impl2", Signedness.SIGNED, ProcessType.ITERATIVE, 11)); - - collection - .add(new HashFunctionIdentityImpl("Testing Suite2", "impl2", Signedness.UNSIGNED, ProcessType.CYCLIC, 13)); - - collection.add( - new HashFunctionIdentityImpl("Testing Suite2", "impl2", Signedness.UNSIGNED, ProcessType.ITERATIVE, 15)); - - Collections.shuffle(collection); - - result.addAll(collection); - long idx = 0; - for (final HashFunctionIdentity id : result) { - assertEquals("Unexpected order for " + id.getProvider() + ":" + HashFunctionIdentity.asCommonString(id), - idx++, id.getSignature()); - } - } -} diff --git a/src/test/java/org/apache/commons/collections4/bloomfilter/hasher/HashFuctionValidatorTest.java b/src/test/java/org/apache/commons/collections4/bloomfilter/hasher/HashFuctionValidatorTest.java new file mode 100644 index 0000000..9aedb14 --- /dev/null +++ b/src/test/java/org/apache/commons/collections4/bloomfilter/hasher/HashFuctionValidatorTest.java @@ -0,0 +1,120 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.commons.collections4.bloomfilter.hasher; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.apache.commons.collections4.bloomfilter.hasher.HashFunctionIdentity.ProcessType; +import org.apache.commons.collections4.bloomfilter.hasher.HashFunctionIdentity.Signedness; +import org.junit.Test; + +/** + * Tests of the {@link HashFunctionValidator}. + */ +public class HashFuctionValidatorTest { + + /** + * Tests that name is used in the equality check. + */ + @Test + public void testName() { + final HashFunctionIdentityImpl impl1 = new HashFunctionIdentityImpl("Testing Suite", "impl1", Signedness.SIGNED, + ProcessType.CYCLIC, 300L); + final HashFunctionIdentityImpl impl2 = new HashFunctionIdentityImpl("Testing Suite", "impl2", Signedness.SIGNED, + ProcessType.CYCLIC, 300L); + + assertTrue(HashFunctionValidator.areEqual(impl1, impl1)); + assertTrue(HashFunctionValidator.areEqual(impl2, impl2)); + assertFalse(HashFunctionValidator.areEqual(impl1, impl2)); + assertFalse(HashFunctionValidator.areEqual(impl2, impl1)); + } + + /** + * Tests that name is not affected by case. + */ + @Test + public void testNameIsCaseInsensitive() { + final HashFunctionIdentityImpl impl1 = new HashFunctionIdentityImpl("Testing Suite", "impl1", Signedness.SIGNED, + ProcessType.CYCLIC, 300L); + final HashFunctionIdentityImpl impl2 = new HashFunctionIdentityImpl("Testing Suite", "IMPL1", Signedness.SIGNED, + ProcessType.CYCLIC, 300L); + + assertTrue(HashFunctionValidator.areEqual(impl1, impl2)); + } + + /** + * Tests that process type is used in the equality check. + */ + @Test + public void testProcessType() { + final HashFunctionIdentityImpl impl1 = new HashFunctionIdentityImpl("Testing Suite", "impl1", Signedness.SIGNED, + ProcessType.CYCLIC, 300L); + final HashFunctionIdentityImpl impl2 = new HashFunctionIdentityImpl("Testing Suite", "impl1", Signedness.SIGNED, + ProcessType.ITERATIVE, 300L); + + assertTrue(HashFunctionValidator.areEqual(impl1, impl1)); + assertTrue(HashFunctionValidator.areEqual(impl2, impl2)); + assertFalse(HashFunctionValidator.areEqual(impl1, impl2)); + assertFalse(HashFunctionValidator.areEqual(impl2, impl1)); + } + + /** + * Tests that provider is <strong>not</strong> used in the equality check. + */ + @Test + public void testProviderIsNotUsedInEqualityCheck() { + final HashFunctionIdentityImpl impl1 = new HashFunctionIdentityImpl("Testing Suite", "impl1", Signedness.SIGNED, + ProcessType.CYCLIC, 300L); + final HashFunctionIdentityImpl impl2 = new HashFunctionIdentityImpl("Testing Suite2", "impl1", Signedness.SIGNED, + ProcessType.CYCLIC, 300L); + + assertTrue(HashFunctionValidator.areEqual(impl1, impl1)); + assertTrue(HashFunctionValidator.areEqual(impl2, impl2)); + assertTrue(HashFunctionValidator.areEqual(impl1, impl2)); + assertTrue(HashFunctionValidator.areEqual(impl2, impl1)); + } + + /** + * Tests that signedness is used in the equality check. + */ + @Test + public void testSignedness() { + final HashFunctionIdentityImpl impl1 = new HashFunctionIdentityImpl("Testing Suite", "impl1", Signedness.SIGNED, + ProcessType.CYCLIC, 300L); + final HashFunctionIdentityImpl impl2 = new HashFunctionIdentityImpl("Testing Suite", "impl1", Signedness.UNSIGNED, + ProcessType.CYCLIC, 300L); + + assertTrue(HashFunctionValidator.areEqual(impl1, impl1)); + assertTrue(HashFunctionValidator.areEqual(impl2, impl2)); + assertFalse(HashFunctionValidator.areEqual(impl1, impl2)); + assertFalse(HashFunctionValidator.areEqual(impl2, impl1)); + } + + /** + * Test the check method throws when the two hash functions are not equal. + */ + @Test(expected=IllegalArgumentException.class) + public void testCheckThrows() { + final HashFunctionIdentityImpl impl1 = new HashFunctionIdentityImpl("Testing Suite", "impl1", Signedness.SIGNED, + ProcessType.CYCLIC, 300L); + final HashFunctionIdentityImpl impl2 = new HashFunctionIdentityImpl("Testing Suite", "impl1", Signedness.UNSIGNED, + ProcessType.CYCLIC, 300L); + HashFunctionValidator.checkAreEqual(impl1, impl2); + } +} diff --git a/src/test/java/org/apache/commons/collections4/bloomfilter/hasher/StaticHasherTest.java b/src/test/java/org/apache/commons/collections4/bloomfilter/hasher/StaticHasherTest.java index dc9ce4f..13a644a 100644 --- a/src/test/java/org/apache/commons/collections4/bloomfilter/hasher/StaticHasherTest.java +++ b/src/test/java/org/apache/commons/collections4/bloomfilter/hasher/StaticHasherTest.java @@ -187,7 +187,11 @@ public class StaticHasherTest { assertEquals(5, hasher.size()); assertEquals(shape, hasher.getShape()); - assertEquals(0, HashFunctionIdentity.DEEP_COMPARATOR.compare(testFunction, hasher.getHashFunctionIdentity())); + // All function properties are equal + assertEquals(testFunction.getName(), hasher.getHashFunctionIdentity().getName()); + assertEquals(testFunction.getProcessType(), hasher.getHashFunctionIdentity().getProcessType()); + assertEquals(testFunction.getProvider(), hasher.getHashFunctionIdentity().getProvider()); + assertEquals(testFunction.getSignedness(), hasher.getHashFunctionIdentity().getSignedness()); iter = hasher.getBits(shape); int idx = 0;