/*
 * 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 java.util.PrimitiveIterator;

/**
 * The class that performs hashing.
 * <p>
 * Hashers have a Unique name based on the hashing algorithm used.
 * </p>
 * <p>
 * Implementations of {@code iterator()} may return duplicate values and may return
 * values in a random order.  See implementation javadoc notes as to the guarantees
 * provided by the specific implementation.
 * </p>
 * @since 4.5
 */
public interface Hasher {

    /**
     * A builder to build a hasher.
     * @since 4.5
     */
    interface Builder {

        /**
         * Builds the hasher.
         * @return the fully constructed hasher
         */
        Hasher build();

        /**
         * Adds a byte to the hasher.
         *
         * @param property the byte to add
         * @return a reference to this object
         * @throws IllegalStateException if the Hasher is locked
         * @see #iterator(Shape)
         */
        Builder with(byte property);

        /**
         * Adds an array of bytes to the hasher.
         *
         * @param property the array of bytes to add
         * @return a reference to this object
         * @throws IllegalStateException if the Hasher is locked
         * @see #iterator(Shape)
         */
        Builder with(byte[] property);

        /**
         * Adds a string to the hasher.
         *
         * @param property the string to add
         * @return a reference to this object
         * @throws IllegalStateException if the Hasher is locked
         * @see #iterator(Shape)
         */
        Builder with(String property);
    }

    /**
     * Gets an iterator of integers that are the bits to enable in the Bloom
     * filter based on the shape. No guarantee is made as to order
     * or duplication of values.
     *
     * @param shape the shape of the desired Bloom filter
     * @return the iterator of integers
     * @throws IllegalArgumentException if the hasher cannot generate indexes for
     * the specified @{@code shape}
     */
    PrimitiveIterator.OfInt iterator(Shape shape);

    /**
     * Gets the identify of the hash function used by the the hasher.
     *
     * @return the identity of the hash function
     */
    HashFunctionIdentity getHashFunctionIdentity();
}

@@ -905,132 +905,919 @@
 %0A * 
-The class that performs hashing.%0A * %3Cp%3E%0A * Hashers have a Unique name based on t
+A Hasher represents items of arbitrary byte size as a byte representation of%0A * fixed size (a hash). The hash representations can be used to create indexes%0A * for a Bloom filter.%0A *%0A * %3Cp%3EThe hash for each item is created using a hash function; use of different%0A * seeds allows generation of different hashes for the same item. The hashes can%0A * be dynamically converted into the bit index representation used by a Bloom%0A * filter. T
 he 
+s
 ha
-shing algorithm used
+pe of the Bloom filter defines the number of indexes per item%0A * and the range of the indexes. The hasher can generate the correct number of%0A * indexes in the range required by the Bloom filter for each item it%0A * represents
 .%0A
+ *%0A
  * %3C
-/
 p%3E
-%0A * %3Cp%3E%0A *
+Note that the process of generating hashes and mapping them to a Bloom%0A * filter shape may create duplicate indexes. The hasher may generate fewer than%0A * the required number of hash functions per item if duplicates have been%0A * removed.
  Imp
@@ -1878,16 +1878,19 @@
 e values
+%0A *
  and may
@@ -1896,19 +1896,16 @@
 y return
-%0A *
  values 
@@ -1922,17 +1922,16 @@
 m order.
- 
  See imp
@@ -1958,16 +1958,19 @@
 notes as
+%0A *
  to the 
@@ -1979,19 +1979,16 @@
 arantees
-%0A *
  provide
@@ -2025,15 +2025,81 @@
 on.%0A
+ *%0A
  * %3C
-/
 p%3E
+Hashers have an identity based on the hashing algorithm used.%0A *
 %0A * 
@@ -2516,106 +2516,8 @@
 ect%0A
-         * @throws IllegalStateException if the Hasher is locked%0A         * @see #iterator(Shape)%0A
     
@@ -2737,106 +2737,8 @@
 ect%0A
-         * @throws IllegalStateException if the Hasher is locked%0A         * @see #iterator(Shape)%0A
     
@@ -2943,106 +2943,8 @@
 ect%0A
-         * @throws IllegalStateException if the Hasher is locked%0A         * @see #iterator(Shape)%0A
     
@@ -3119,63 +3119,420 @@
 ape.
- No guarantee is made as to order%0A     * or duplication
+%0A     *%0A     * %3Cp%3EThe iterator will create indexes within the range defined by the number of bits in%0A     * the shape. The total number of indexes will respect the number of hash functions per item%0A     * defined by the shape. However the count of indexes may not be a multiple of the number of%0A     * hash functions if the implementation has removed duplicates.%0A     *%0A     * %3Cp%3ENo guarantee is made as to order
  of 

Improve documentation of Hasher.