/**
   * Core impl.
   *
   * @param n The expected #of index entries (this value is ignored for {@link IndexSegment}s).
   * @param p The desired error rate for the bloom filter at that #of index entries (or at the
   *     actual #of index entries for an {@link IndexSegment}).
   * @param maxP The maximum error rate for the bloom filter for a {@link BTree} (it will be
   *     disabled for a {@link BTree} once the bloom filter can be expected to realize this error
   *     rate).
   * @throws IllegalArgumentException if <i>n</i> is non-positive.
   * @throws IllegalArgumentException unless <i>p</i> lies in (0:1].
   * @throws IllegalArgumentException
   * @throws IllegalArgumentException unless <i>maxP</i> lies in (<i>p</i>:1].
   */
  public BloomFilterFactory(final int n, final double p, final double maxP) {

    if (n <= 0) throw new IllegalArgumentException();
    if (p <= 0d || p > 1d) throw new IllegalArgumentException();
    if (maxP <= p || maxP > 1d) throw new IllegalArgumentException();

    this.n = n;

    this.p = p;

    this.maxP = maxP;

    // #of hash functions.
    final int k = BloomFilter.getHashFunctionCount(p);

    // bit length of the filter.
    final long m = BloomFilter.getBitLength(k, n);

    /*
     * The maximum #of index entries before we disable the filter because
     * the expected performance will be worse than the specified maximum
     * error rate.
     */
    this.maxN = BloomFilter.getEntryCountForErrorRate(k, m, maxP);
  }