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.
This commit is contained in:
parent
66b418f3e9
commit
55cb720ccf
|
@ -212,6 +212,9 @@ public abstract class AbstractBloomFilter implements BloomFilter {
|
||||||
* @param hasher the Hasher to check
|
* @param hasher the Hasher to check
|
||||||
*/
|
*/
|
||||||
protected void verifyHasher(final Hasher hasher) {
|
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()) {
|
if (shape.getHashFunctionIdentity().getSignature() != hasher.getHashFunctionIdentity().getSignature()) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
String.format("Hasher (%s) is not the hasher for shape (%s)",
|
String.format("Hasher (%s) is not the hasher for shape (%s)",
|
||||||
|
|
|
@ -177,13 +177,8 @@ public class DynamicHasher implements Hasher {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public PrimitiveIterator.OfInt getBits(final Shape shape) {
|
public PrimitiveIterator.OfInt getBits(final Shape shape) {
|
||||||
if (HashFunctionIdentity.COMMON_COMPARATOR.compare(getHashFunctionIdentity(),
|
HashFunctionValidator.checkAreEqual(getHashFunctionIdentity(),
|
||||||
shape.getHashFunctionIdentity()) != 0) {
|
shape.getHashFunctionIdentity());
|
||||||
throw new IllegalArgumentException(
|
|
||||||
String.format("Shape hasher %s is not %s",
|
|
||||||
HashFunctionIdentity.asCommonString(shape.getHashFunctionIdentity()),
|
|
||||||
HashFunctionIdentity.asCommonString(getHashFunctionIdentity())));
|
|
||||||
}
|
|
||||||
// Use optimised iterator for no values
|
// Use optimised iterator for no values
|
||||||
return buffers.isEmpty() ? NoValuesIterator.INSTANCE : new Iterator(shape);
|
return buffers.isEmpty() ? NoValuesIterator.INSTANCE : new Iterator(shape);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
package org.apache.commons.collections4.bloomfilter.hasher;
|
package org.apache.commons.collections4.bloomfilter.hasher;
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -63,39 +62,6 @@ public interface HashFunctionIdentity {
|
||||||
SIGNED, UNSIGNED
|
SIGNED, UNSIGNED
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
* Gets a common formatted string for general display.
|
||||||
*
|
*
|
||||||
|
@ -119,10 +85,9 @@ public interface HashFunctionIdentity {
|
||||||
* @return the signature buffer for the identity
|
* @return the signature buffer for the identity
|
||||||
*/
|
*/
|
||||||
static byte[] prepareSignatureBuffer(final HashFunctionIdentity identity) {
|
static byte[] prepareSignatureBuffer(final HashFunctionIdentity identity) {
|
||||||
|
|
||||||
return String.format("%s-%s-%s",
|
return String.format("%s-%s-%s",
|
||||||
identity.getName().toUpperCase(Locale.ROOT), identity.getSignedness(),
|
identity.getName().toUpperCase(Locale.ROOT), identity.getSignedness(),
|
||||||
identity.getProcessType() ).getBytes(StandardCharsets.UTF_8);
|
identity.getProcessType()).getBytes(StandardCharsets.UTF_8);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -232,7 +232,7 @@ public class Shape {
|
||||||
* @param numberOfBits the number of bits in the filter.
|
* @param numberOfBits the number of bits in the filter.
|
||||||
* @return the optimal number of hash functions.
|
* @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
|
* k = round((m / n) * log(2)) We change order so that we use real math rather
|
||||||
* than integer math.
|
* than integer math.
|
||||||
|
@ -258,8 +258,8 @@ public class Shape {
|
||||||
return
|
return
|
||||||
other.getNumberOfBits() == getNumberOfBits() &&
|
other.getNumberOfBits() == getNumberOfBits() &&
|
||||||
other.getNumberOfHashFunctions() == getNumberOfHashFunctions() &&
|
other.getNumberOfHashFunctions() == getNumberOfHashFunctions() &&
|
||||||
HashFunctionIdentity.COMMON_COMPARATOR.compare(getHashFunctionIdentity(),
|
HashFunctionValidator.areEqual(getHashFunctionIdentity(),
|
||||||
other.getHashFunctionIdentity()) == 0;
|
other.getHashFunctionIdentity());
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,11 +48,8 @@ public final class StaticHasher implements Hasher {
|
||||||
*/
|
*/
|
||||||
public StaticHasher(final Hasher hasher, final Shape shape) {
|
public StaticHasher(final Hasher hasher, final Shape shape) {
|
||||||
this(hasher.getBits(shape), shape);
|
this(hasher.getBits(shape), shape);
|
||||||
if (HashFunctionIdentity.COMMON_COMPARATOR.compare(hasher.getHashFunctionIdentity(),
|
HashFunctionValidator.checkAreEqual(hasher.getHashFunctionIdentity(),
|
||||||
shape.getHashFunctionIdentity()) != 0) {
|
shape.getHashFunctionIdentity());
|
||||||
throw new IllegalArgumentException(String.format("Hasher (%s) is not the same as for shape (%s)",
|
|
||||||
HashFunctionIdentity.asCommonString(hasher.getHashFunctionIdentity()), shape.toString()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -187,7 +187,11 @@ public class StaticHasherTest {
|
||||||
|
|
||||||
assertEquals(5, hasher.size());
|
assertEquals(5, hasher.size());
|
||||||
assertEquals(shape, hasher.getShape());
|
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);
|
iter = hasher.getBits(shape);
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
|
|
Loading…
Reference in New Issue