All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.openhft.collect.impl.hash.QHashCapacities Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2014 the original author or authors.
 *
 * 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 net.openhft.collect.impl.hash;

import net.openhft.collect.hash.HashOverflowException;

import java.math.BigInteger;
import java.util.ArrayList;

import static java.lang.Math.abs;
import static java.util.Arrays.binarySearch;
import static net.openhft.collect.impl.hash.Capacities.chooseBetter;


public final class QHashCapacities {

    public static int capacity(HashConfigWrapper conf, int size) {
        return capacity(conf, size, false);
    }

    /** For initial hash table construction and rehash to target load (shrink, tombstones purge). */
    public static int capacity(HashConfigWrapper conf, int size, boolean doubleSizedArrays) {
        assert size >= 0 : "size must be non-negative";
        return capacity(conf, size, conf.targetCapacity(size), doubleSizedArrays);
    }

    private static int capacity(HashConfigWrapper conf, int size, int desiredCapacity,
            boolean doubleSizedArrays) {
        int lesserCapacity, greaterCapacity;
        boolean simpleArrays;
        if (desiredCapacity <= MAX_LOOKUP_CAPACITY) {
            int smallTableIndex = SMALL_LOOKUP_TABLE_INDICES[desiredCapacity];
            greaterCapacity = SMALL_LOOKUP_TABLE_CAPACITIES[smallTableIndex];
            if (greaterCapacity == desiredCapacity || smallTableIndex == 0)
                return greaterCapacity;
            lesserCapacity = SMALL_LOOKUP_TABLE_CAPACITIES[smallTableIndex - 1];
        }
        else if (desiredCapacity <= MAX_REGULAR_CHAR_CAPACITY) {
            int capIndex = binarySearch(REGULAR_CHAR_CAPACITIES, (char) desiredCapacity);
            if (capIndex >= 0) // desiredCapacity is found in REGULAR_CHAR_CAPACITIES
                return desiredCapacity;
            capIndex = ~capIndex;
            lesserCapacity = capIndex > 0 ?
                    (int) REGULAR_CHAR_CAPACITIES[capIndex - 1] : MAX_LOOKUP_CAPACITY;
            greaterCapacity = REGULAR_CHAR_CAPACITIES[capIndex];
        }
        else if (desiredCapacity <= ((simpleArrays = !doubleSizedArrays) ?
                MAX_REGULAR_INT_CAPACITY : MAX_REGULAR_CAPACITY_FOR_DOUBLED_ARRAY)) {
            int capIndex = binarySearch(REGULAR_INT_CAPACITIES, desiredCapacity);
            if (capIndex >= 0) // desiredCapacity is found in REGULAR_INT_CAPACITIES
                return desiredCapacity;
            capIndex = ~capIndex;
            lesserCapacity = capIndex > 0 ?
                    REGULAR_INT_CAPACITIES[capIndex - 1] : MAX_REGULAR_CHAR_CAPACITY;
            greaterCapacity = REGULAR_INT_CAPACITIES[capIndex];
        }
        else {
            // Since size could be virtual (expected), don't prematurely throw
            // HashOverflowException. If sizes near to Integer.MAX_VALUE is the case,
            // version accepting long size should be used.
            return simpleArrays ? MAX_INT_CAPACITY : MAX_CAPACITY_FOR_DOUBLED_ARRAY;
        }
        return chooseBetter(conf, size, desiredCapacity, lesserCapacity, greaterCapacity,
                greaterCapacity);
    }

    public static long capacity(HashConfigWrapper conf, long size) {
        assert size >= 0L : "size must be non-negative";
        long desiredCapacity = conf.targetCapacity(size);
        if (desiredCapacity <= (long) MAX_REGULAR_INT_CAPACITY)
            return (long) capacity(conf, (int) size, (int) desiredCapacity, false);
        if (desiredCapacity <= MAX_REGULAR_LONG_CAPACITY) {
            int capIndex = binarySearch(REGULAR_LONG_CAPACITIES, desiredCapacity);
            if (capIndex >= 0)
                return desiredCapacity;
            long lesserCapacity = capIndex > 0 ?
                    REGULAR_LONG_CAPACITIES[capIndex - 1] : (long) MAX_REGULAR_INT_CAPACITY;
            long greaterCapacity = REGULAR_CHAR_CAPACITIES[capIndex];
            return chooseBetter(conf, size, desiredCapacity, lesserCapacity, greaterCapacity,
                    greaterCapacity);
        }
        return extraLargeCapacity(desiredCapacity);
    }

    public static int nearestGreaterCapacity(int desiredCapacity, int currentSize) {
        return nearestGreaterCapacity(desiredCapacity, currentSize, false);
    }

    /** For grow rehash. */
    public static int nearestGreaterCapacity(int desiredCapacity, int currentSize,
            boolean doubleSizedArrays) {
        assert currentSize >= 0 : "currentSize must be non-negative";
        if (desiredCapacity <= MAX_LOOKUP_CAPACITY)
            return SMALL_LOOKUP_TABLE_CAPACITIES[SMALL_LOOKUP_TABLE_INDICES[desiredCapacity]];
        if (desiredCapacity <= MAX_REGULAR_CHAR_CAPACITY) {
            int capIndex = binarySearch(REGULAR_CHAR_CAPACITIES, (char) desiredCapacity);
            // if capIndex >= 0 desiredCapacity IS a regular capacity
            return capIndex < 0 ? REGULAR_CHAR_CAPACITIES[~capIndex] : desiredCapacity;
        }
        boolean simpleArrays = !doubleSizedArrays;
        if (desiredCapacity <= (simpleArrays ? MAX_REGULAR_INT_CAPACITY :
                MAX_REGULAR_CAPACITY_FOR_DOUBLED_ARRAY)) {
            int capIndex = binarySearch(REGULAR_INT_CAPACITIES, desiredCapacity);
            return capIndex < 0 ? REGULAR_INT_CAPACITIES[~capIndex] : desiredCapacity;
        }
        int maxCapacity = simpleArrays ? MAX_INT_CAPACITY : MAX_CAPACITY_FOR_DOUBLED_ARRAY;
        // overflow-aware
        if (currentSize - maxCapacity < 0)
            return maxCapacity;
        if (simpleArrays && currentSize - Integer.MAX_VALUE < 0) {
            // Integer.MAX_VALUE is also a qHash prime, but likely will cause OutOfMemoryError
            return Integer.MAX_VALUE;
        } else {
            // QHash must have at least 1 free slot
            throw new HashOverflowException();
        }
    }

    public static long nearestGreaterCapacity(long desiredCapacity, long currentSize) {
        assert desiredCapacity >= 0L : "desiredCapacity must be non-negative";
        if (desiredCapacity <= (long) MAX_REGULAR_INT_CAPACITY)
            return (long) nearestGreaterCapacity((int) desiredCapacity, (int) currentSize, false);
        if (desiredCapacity <= MAX_REGULAR_LONG_CAPACITY) {
            int capIndex = binarySearch(REGULAR_LONG_CAPACITIES, desiredCapacity);
            return capIndex < 0 ? REGULAR_LONG_CAPACITIES[~capIndex] : desiredCapacity;
        }
        return extraLargeCapacity(desiredCapacity);
    }

    private static long extraLargeCapacity(long desiredCapacity) {
        for (long c = desiredCapacity; c < Long.MAX_VALUE; c++) {
            if (isQHashPrime(c))
                return c;
        }
        throw new IllegalArgumentException(
                "There isn't long qHash capacities higher than " + desiredCapacity);
    }

    private static final char[] SMALL_LOOKUP_TABLE_CAPACITIES = new char[] {
            7, 11, 19, 23, 31, 43, 47, 59, 67, 71,
            79, 83, 103, 107, 127, 131, 139, 151, 163, 167,
            179, 191, 199, 211, 223, 227, 239, 251, 263, 271,
            283, 307, 311, 331, 347, 359, 367, 379, 383, 419,
            431, 439, 443, 463, 467, 479, 487, 491, 499, 503,
            523, 547, 563, 571, 587, 599, 607, 619, 631, 643,
            647, 659, 683, 691, 719, 727, 739, 743, 751, 787,
            811, 823, 827, 839, 859, 863, 883, 887, 907, 911,
            919, 947, 967, 971, 983, 991, 1019
    };

    private static final byte[] SMALL_LOOKUP_TABLE_INDICES = new byte[] {
            0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
            1, 1, 2, 2, 2, 2, 2, 2, 2, 2,
            3, 3, 3, 3, 4, 4, 4, 4, 4, 4,
            4, 4, 5, 5, 5, 5, 5, 5, 5, 5,
            5, 5, 5, 5, 6, 6, 6, 6, 7, 7,
            7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
            8, 8, 8, 8, 8, 8, 8, 8, 9, 9,
            9, 9, 10, 10, 10, 10, 10, 10, 10, 10,
            11, 11, 11, 11, 12, 12, 12, 12, 12, 12,
            12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
            12, 12, 12, 12, 13, 13, 13, 13, 14, 14,
            14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
            14, 14, 14, 14, 14, 14, 14, 14, 15, 15,
            15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
            17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
            17, 17, 18, 18, 18, 18, 18, 18, 18, 18,
            18, 18, 18, 18, 19, 19, 19, 19, 20, 20,
            20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
            21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
            21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
            23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
            23, 23, 24, 24, 24, 24, 24, 24, 24, 24,
            24, 24, 24, 24, 25, 25, 25, 25, 26, 26,
            26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
            27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
            27, 27, 28, 28, 28, 28, 28, 28, 28, 28,
            28, 28, 28, 28, 29, 29, 29, 29, 29, 29,
            29, 29, 30, 30, 30, 30, 30, 30, 30, 30,
            30, 30, 30, 30, 31, 31, 31, 31, 31, 31,
            31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
            31, 31, 31, 31, 31, 31, 31, 31, 32, 32,
            32, 32, 33, 33, 33, 33, 33, 33, 33, 33,
            33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
            33, 33, 34, 34, 34, 34, 34, 34, 34, 34,
            34, 34, 34, 34, 34, 34, 34, 34, 35, 35,
            35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
            36, 36, 36, 36, 36, 36, 36, 36, 37, 37,
            37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
            38, 38, 38, 38, 39, 39, 39, 39, 39, 39,
            39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
            39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
            39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
            40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
            40, 40, 41, 41, 41, 41, 41, 41, 41, 41,
            42, 42, 42, 42, 43, 43, 43, 43, 43, 43,
            43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
            43, 43, 43, 43, 44, 44, 44, 44, 45, 45,
            45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
            46, 46, 46, 46, 46, 46, 46, 46, 47, 47,
            47, 47, 48, 48, 48, 48, 48, 48, 48, 48,
            49, 49, 49, 49, 50, 50, 50, 50, 50, 50,
            50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
            50, 50, 50, 50, 51, 51, 51, 51, 51, 51,
            51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
            51, 51, 51, 51, 51, 51, 51, 51, 52, 52,
            52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
            52, 52, 52, 52, 53, 53, 53, 53, 53, 53,
            53, 53, 54, 54, 54, 54, 54, 54, 54, 54,
            54, 54, 54, 54, 54, 54, 54, 54, 55, 55,
            55, 55, 55, 55, 55, 55, 55, 55, 55, 55,
            56, 56, 56, 56, 56, 56, 56, 56, 57, 57,
            57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
            58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
            58, 58, 59, 59, 59, 59, 59, 59, 59, 59,
            59, 59, 59, 59, 60, 60, 60, 60, 61, 61,
            61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
            62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
            62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
            62, 62, 62, 62, 63, 63, 63, 63, 63, 63,
            63, 63, 64, 64, 64, 64, 64, 64, 64, 64,
            64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
            64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
            65, 65, 65, 65, 65, 65, 65, 65, 66, 66,
            66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
            67, 67, 67, 67, 68, 68, 68, 68, 68, 68,
            68, 68, 69, 69, 69, 69, 69, 69, 69, 69,
            69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
            69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
            69, 69, 69, 69, 69, 69, 69, 69, 70, 70,
            70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
            70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
            70, 70, 71, 71, 71, 71, 71, 71, 71, 71,
            71, 71, 71, 71, 72, 72, 72, 72, 73, 73,
            73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
            74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
            74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
            75, 75, 75, 75, 76, 76, 76, 76, 76, 76,
            76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
            76, 76, 76, 76, 77, 77, 77, 77, 78, 78,
            78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
            78, 78, 78, 78, 78, 78, 78, 78, 79, 79,
            79, 79, 80, 80, 80, 80, 80, 80, 80, 80,
            81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
            81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
            81, 81, 81, 81, 81, 81, 81, 81, 82, 82,
            82, 82, 82, 82, 82, 82, 82, 82, 82, 82,
            82, 82, 82, 82, 82, 82, 82, 82, 83, 83,
            83, 83, 84, 84, 84, 84, 84, 84, 84, 84,
            84, 84, 84, 84, 85, 85, 85, 85, 85, 85,
            85, 85, 86, 86, 86, 86, 86, 86, 86, 86,
            86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
            86, 86, 86, 86, 86, 86, 86, 86, 86, 86
    };

    /** Compile-time constant expression */
    private static final int MAX_LOOKUP_CAPACITY = 1019;
    static {
        if (MAX_LOOKUP_CAPACITY !=
                SMALL_LOOKUP_TABLE_CAPACITIES[SMALL_LOOKUP_TABLE_CAPACITIES.length - 1]) {
            throw new AssertionError();
        }
    }

    /**
     * These capacities and other regular capacities from {@link #REGULAR_INT_CAPACITIES}
     * and {@link #REGULAR_LONG_CAPACITIES} arrays are generated using a single command
     * {@code $ java QHashCapacities 40 0.005}, i. e. trying to keep 0.5% max difference between
     * neighbouring capacities.
     *
     * @see {@link #main(String[])}
     * @see {@link #generateRegularCapacities(long, double)}
     */
    private static final char[] REGULAR_CHAR_CAPACITIES = new char[] {
            1031, 1039,
            1051, 1063, 1087, 1091, 1103, 1123, 1151, 1163, 1171, 1187,
            1223, 1231, 1259, 1279, 1283, 1291, 1303, 1307, 1319, 1327,
            1367, 1399, 1423, 1427, 1439, 1447, 1451, 1459, 1471, 1483,
            1487, 1499, 1511, 1523, 1531, 1543, 1559, 1567, 1571, 1579,
            1583, 1607, 1619, 1627, 1663, 1667, 1699, 1723, 1747, 1759,
            1783, 1787, 1811, 1823, 1831, 1847, 1867, 1871, 1879, 1907,
            1931, 1951, 1979, 1987, 1999, 2003, 2011, 2027, 2039, 2063,
            2083, 2087, 2099, 2111, 2131, 2143, 2179, 2203, 2207, 2239,
            2243, 2251, 2267, 2287, 2311, 2339, 2347, 2351, 2371, 2383,
            2399, 2411, 2423, 2447, 2459, 2467, 2503, 2531, 2539, 2543,
            2551, 2579, 2591, 2647, 2659, 2663, 2671, 2683, 2687, 2699,
            2707, 2711, 2719, 2731, 2767, 2791, 2803, 2819, 2843, 2851,
            2879, 2887, 2903, 2927, 2939, 2963, 2971, 2999, 3011, 3019,
            3023, 3067, 3079, 3083, 3119, 3163, 3167, 3187, 3191, 3203,
            3251, 3259, 3271, 3299, 3307, 3319, 3323, 3331, 3343, 3347,
            3359, 3371, 3391, 3407, 3463, 3467, 3491, 3499, 3511, 3527,
            3539, 3547, 3559, 3571, 3583, 3607, 3623, 3631, 3643, 3659,
            3671, 3691, 3719, 3727, 3739, 3767, 3779, 3803, 3823, 3847,
            3851, 3863, 3907, 3911, 3919, 3923, 3931, 3943, 3947, 3967,
            4003, 4007, 4019, 4027, 4051, 4079, 4091, 4099, 4111, 4127,
            4139, 4159, 4211, 4219, 4231, 4243, 4259, 4271, 4283, 4327,
            4339, 4363, 4391, 4423, 4447, 4451, 4463, 4483, 4507, 4519,
            4523, 4547, 4567, 4583, 4591, 4603, 4639, 4643, 4651, 4663,
            4679, 4691, 4703, 4723, 4751, 4759, 4783, 4787, 4799, 4831,
            4871, 4903, 4919, 4931, 4943, 4951, 4967, 4987, 4999, 5003,
            5011, 5023, 5039, 5051, 5059, 5087, 5099, 5107, 5119, 5147,
            5167, 5171, 5179, 5227, 5231, 5279, 5303, 5323, 5347, 5351,
            5387, 5399, 5407, 5419, 5431, 5443, 5471, 5479, 5483, 5503,
            5507, 5519, 5527, 5531, 5563, 5591, 5623, 5639, 5647, 5651,
            5659, 5683, 5711, 5743, 5779, 5783, 5791, 5807, 5827, 5839,
            5843, 5851, 5867, 5879, 5903, 5923, 5927, 5939, 5987, 6007,
            6011, 6043, 6047, 6067, 6079, 6091, 6131, 6143, 6151, 6163,
            6199, 6203, 6211, 6247, 6263, 6271, 6287, 6299, 6311, 6323,
            6343, 6359, 6367, 6379, 6427, 6451, 6491, 6547, 6551, 6563,
            6571, 6599, 6607, 6619, 6659, 6679, 6691, 6703, 6719, 6763,
            6779, 6791, 6803, 6823, 6827, 6863, 6871, 6883, 6899, 6907,
            6911, 6947, 6959, 6967, 6971, 6983, 6991, 7019, 7027, 7039,
            7043, 7079, 7103, 7127, 7151, 7159, 7187, 7207, 7211, 7219,
            7243, 7247, 7283, 7307, 7331, 7351, 7411, 7451, 7459, 7487,
            7499, 7507, 7523, 7547, 7559, 7583, 7591, 7603, 7607, 7639,
            7643, 7687, 7691, 7699, 7703, 7723, 7727, 7759, 7823, 7867,
            7879, 7883, 7907, 7919, 7927, 7951, 7963, 8011, 8039, 8059,
            8087, 8111, 8123, 8147, 8167, 8171, 8179, 8191, 8219, 8231,
            8243, 8263, 8287, 8291, 8311, 8363, 8387, 8419, 8423, 8431,
            8443, 8447, 8467, 8527, 8539, 8543, 8563, 8599, 8623, 8627,
            8647, 8663, 8699, 8707, 8719, 8731, 8747, 8779, 8783, 8803,
            8807, 8819, 8831, 8839, 8863, 8867, 8887, 8923, 8951, 8963,
            8971, 8999, 9007, 9011, 9043, 9059, 9067, 9091, 9103, 9127,
            9151, 9187, 9199, 9203, 9227, 9239, 9283, 9311, 9319, 9323,
            9343, 9371, 9391, 9403, 9419, 9431, 9439, 9463, 9467, 9479,
            9491, 9511, 9539, 9547, 9551, 9587, 9619, 9623, 9631, 9643,
            9679, 9719, 9739, 9743, 9767, 9787, 9791, 9803, 9811, 9839,
            9851, 9859, 9871, 9883, 9887, 9907, 9923, 9931, 9967, 10007,
            10039, 10067, 10079, 10091, 10099, 10103, 10111, 10139, 10151, 10159,
            10163, 10211, 10223, 10243, 10247, 10259, 10267, 10271, 10303, 10331,
            10343, 10391, 10399, 10427, 10459, 10463, 10487, 10499, 10531, 10559,
            10567, 10607, 10627, 10631, 10639, 10651, 10663, 10667, 10687, 10691,
            10711, 10723, 10739, 10771, 10799, 10831, 10847, 10859, 10867, 10883,
            10891, 10903, 10939, 10979, 10987, 11003, 11027, 11047, 11059, 11071,
            11083, 11087, 11119, 11131, 11159, 11171, 11239, 11243, 11251, 11279,
            11287, 11299, 11311, 11351, 11383, 11399, 11411, 11423, 11443, 11447,
            11467, 11471, 11483, 11491, 11503, 11519, 11527, 11551, 11579, 11587,
            11699, 11719, 11731, 11743, 11779, 11783, 11807, 11827, 11831, 11839,
            11863, 11867, 11887, 11903, 11923, 11927, 11939, 11959, 11971, 11987,
            12007, 12011, 12043, 12071, 12107, 12119, 12143, 12163, 12203, 12211,
            12227, 12239, 12251, 12263, 12323, 12343, 12347, 12379, 12391, 12451,
            12479, 12487, 12491, 12503, 12511, 12527, 12539, 12547, 12583, 12611,
            12619, 12647, 12659, 12671, 12703, 12739, 12743, 12763, 12791, 12799,
            12823, 12899, 12919, 12979, 13043, 13099, 13159, 13219, 13259, 13291,
            13339, 13399, 13463, 13523, 13567, 13619, 13679, 13711, 13763, 13831,
            13879, 13931, 13999, 14051, 14083, 14143, 14207, 14243, 14303, 14323,
            14387, 14431, 14503, 14563, 14627, 14683, 14723, 14779, 14851, 14923,
            14983, 15031, 15083, 15131, 15187, 15259, 15307, 15383, 15439, 15511,
            15551, 15607, 15667, 15727, 15787, 15859, 15919, 15991, 16063, 16111,
            16187, 16267, 16339, 16411, 16427, 16487, 16547, 16619, 16691, 16747,
            16811, 16879, 16963, 17047, 17123, 17207, 17291, 17359, 17443, 17519,
            17579, 17659, 17747, 17807, 17891, 17959, 18043, 18119, 18199, 18287,
            18367, 18427, 18503, 18583, 18671, 18719, 18787, 18839, 18899, 18959,
            19051, 19139, 19231, 19319, 19379, 19423, 19507, 19603, 19687, 19751,
            19843, 19927, 20023, 20123, 20219, 20287, 20347, 20443, 20543, 20611,
            20707, 20807, 20879, 20939, 21011, 21107, 21179, 21283, 21379, 21467,
            21559, 21647, 21739, 21839, 21943, 22039, 22147, 22247, 22343, 22447,
            22531, 22639, 22751, 22859, 22943, 23027, 23131, 23227, 23339, 23447,
            23563, 23663, 23767, 23879, 23971, 24043, 24151, 24239, 24359, 24379,
            24499, 24571, 24683, 24799, 24907, 25031, 25111, 25219, 25339, 25463,
            25579, 25679, 25799, 25903, 25999, 26099, 26227, 26339, 26407, 26539,
            26627, 26759, 26879, 27011, 27143, 27271, 27407, 27527, 27631, 27751,
            27883, 28019, 28151, 28279, 28387, 28499, 28619, 28751, 28879, 29023,
            29167, 29303, 29443, 29587, 29723, 29851, 29983, 30119, 30259, 30391,
            30539, 30671, 30803, 30931, 31079, 31231, 31387, 31543, 31699, 31847,
            31963, 32099, 32251, 32371, 32531, 32687, 32839, 32887, 33023, 33179,
            33331, 33479, 33647, 33811, 33967, 34123, 34231, 34403, 34543, 34703,
            34871, 35023, 35171, 35339, 35507, 35671, 35803, 35951, 36131, 36299,
            36451, 36587, 36767, 36943, 37123, 37307, 37447, 37619, 37799, 37987,
            38167, 38351, 38543, 38671, 38851, 39043, 39227, 39419, 39607, 39779,
            39971, 40151, 40343, 40499, 40699, 40847, 41039, 41243, 41443, 41647,
            41843, 41983, 42179, 42359, 42571, 42743, 42943, 43151, 43331, 43543,
            43759, 43943, 44131, 44351, 44563, 44771, 44959, 45179, 45403, 45599,
            45823, 46051, 46271, 46471, 46687, 46919, 47111, 47339, 47563, 47791,
            48023, 48259, 48491, 48731, 48947, 49171, 49391, 49627, 49871, 50111,
            50359, 50587, 50839, 51031, 51263, 51511, 51767, 52027, 52259, 52511,
            52747, 53003, 53267, 53527, 53791, 54059, 54311, 54583, 54851, 55079,
            55331, 55579, 55843, 56123, 56383, 56659, 56911, 57191, 57467, 57719,
            57991, 58271, 58543, 58831, 59107, 59387, 59659, 59951, 60251, 60527,
            60811, 61091, 61379, 61687, 61991, 62299, 62591, 62903, 63179, 63487,
            63803, 64123, 64439, 64747, 65063, 65371
    };

    /** Compile-time constant expression */
    private static final int MAX_REGULAR_CHAR_CAPACITY = 65371;
    static {
        if (MAX_REGULAR_CHAR_CAPACITY !=
                REGULAR_CHAR_CAPACITIES[REGULAR_CHAR_CAPACITIES.length - 1])
            throw new AssertionError();
    }


    private static final int[] REGULAR_INT_CAPACITIES = new int[] {
            65687, 65827, 66103, 66431,
            66751, 67079, 67391, 67699, 68023, 68351, 68687, 69031, 69371, 69691,
            69991, 70327, 70627, 70979, 71327, 71647, 71947, 72271, 72623, 72931,
            73291, 73643, 73999, 74323, 74687, 75011, 75367, 75731, 76091, 76463,
            76819, 77167, 77527, 77899, 78259, 78607, 78979, 79319, 79687, 80039,
            80407, 80803, 81203, 81611, 82003, 82387, 82787, 83203, 83563, 83891,
            84299, 84691, 85103, 85523, 85931, 86351, 86783, 87211, 87643, 88079,
            88499, 88919, 89363, 89759, 90187, 90631, 91079, 91499, 91939, 92399,
            92863, 93307, 93763, 94219, 94687, 95131, 95603, 96059, 96527, 96979,
            97459, 97919, 98387, 98867, 99347, 99823, 100291, 100787, 101267, 101719,
            102191, 102667, 103171, 103687, 104207, 104707, 105227, 105751, 106279, 106787,
            107323, 107827, 108343, 108883, 109423, 109943, 110479, 111031, 111539, 112067,
            112603, 113159, 113719, 114259, 114799, 115363, 115931, 116491, 117071, 117659,
            118247, 118831, 119419, 119963, 120539, 121123, 121687, 122263, 122867, 123479,
            124067, 124643, 125243, 125863, 126443, 127031, 127607, 128239, 128879, 129499,
            130147, 130783, 131363, 131543, 132199, 132859, 133519, 134171, 134807, 135463,
            136139, 136811, 137491, 138179, 138863, 139511, 140191, 140891, 141587, 142271,
            142979, 143687, 144379, 145091, 145799, 146519, 147211, 147919, 148627, 149371,
            150107, 150847, 151603, 152363, 153107, 153871, 154619, 155371, 156119, 156887,
            157667, 158443, 159223, 160019, 160807, 161611, 162419, 163211, 164023, 164839,
            165667, 166487, 167311, 168151, 168991, 169823, 170647, 171491, 172331, 173183,
            174047, 174907, 175783, 176651, 177511, 178403, 179287, 180179, 181003, 181871,
            182779, 183691, 184607, 185519, 186451, 187367, 188291, 189199, 190147, 191047,
            192007, 192971, 193939, 194911, 195887, 196871, 197831, 198811, 199783, 200771,
            201743, 202751, 203767, 204751, 205759, 206779, 207799, 208843, 209887, 210907,
            211927, 212987, 214003, 215051, 216119, 217199, 218279, 219371, 220447, 221539,
            222587, 223667, 224683, 225751, 226819, 227947, 228983, 230123, 231271, 232391,
            233551, 234659, 235783, 236947, 238099, 239287, 240479, 241603, 242807, 244003,
            245171, 246371, 247607, 248851, 250091, 251323, 252559, 253787, 255043, 256307,
            257591, 258871, 260171, 261427, 262723, 263951, 265271, 266587, 267887, 269219,
            270563, 271919, 273271, 274579, 275911, 277223, 278591, 279967, 281363, 282767,
            284159, 285559, 286987, 288403, 289843, 291299, 292759, 294223, 295699, 297151,
            298631, 300119, 301579, 303091, 304559, 306083, 307583, 309091, 310643, 312199,
            313679, 315247, 316819, 318403, 319967, 321547, 323123, 324743, 326351, 327967,
            329587, 331231, 332887, 334547, 336199, 337859, 339467, 341171, 342871, 344587,
            346303, 348011, 349759, 351503, 353263, 355027, 356803, 358591, 360391, 362143,
            363959, 365779, 367603, 369407, 371227, 373091, 374939, 376787, 378667, 380563,
            382463, 384359, 386279, 388211, 390151, 392099, 394063, 396031, 398011, 399979,
            401939, 403951, 405947, 407923, 409967, 412019, 414083, 416147, 418199, 420263,
            422311, 424423, 426527, 428639, 430783, 432931, 435103, 437263, 439459, 441667,
            443867, 446087, 448303, 450479, 452731, 454991, 457267, 459523, 461803, 464119,
            466423, 468739, 471091, 473443, 475807, 478171, 480563, 482947, 485347, 487783,
            490207, 492647, 495119, 497587, 500083, 502543, 505067, 507599, 510127, 512663,
            515191, 517739, 520339, 522947, 525571, 528163, 530807, 533447, 536111, 538799,
            541483, 544199, 546919, 549623, 552379, 555143, 557927, 560719, 563503, 566311,
            569083, 571939, 574799, 577627, 580471, 583367, 586291, 589187, 592139, 595087,
            598051, 601031, 604031, 607043, 610063, 613099, 616171, 619247, 622331, 625451,
            628583, 631711, 634859, 638023, 641227, 644431, 647659, 650911, 654163, 657431,
            660727, 664043, 667363, 670711, 674059, 677387, 680783, 684191, 687623, 691051,
            694511, 697979, 701479, 704999, 708527, 712067, 715639, 719179, 722783, 726367,
            729991, 733651, 737327, 741007, 744727, 748463, 752183, 755959, 759719, 763523,
            767323, 771143, 775007, 778871, 782783, 786659, 790567, 794531, 798487, 802471,
            806503, 810539, 814579, 818659, 822763, 826879, 831023, 835123, 839303, 843503,
            847727, 851971, 856187, 860479, 864803, 869119, 873463, 877843, 882239, 886651,
            891103, 895571, 900019, 904531, 909071, 913639, 918199, 922807, 927403, 931999,
            936679, 941383, 946091, 950839, 955607, 960383, 965179, 970027, 974891, 979787,
            984703, 989623, 994559, 999491, 1004483, 1009483, 1014547, 1019639, 1024703, 1029823,
            1034983, 1040167, 1045391, 1050631, 1054171, 1059439, 1064743, 1070087, 1075463, 1080847,
            1086259, 1091711, 1097179, 1102691, 1108223, 1113787, 1119359, 1124983, 1130627, 1136299,
            1142003, 1147739, 1153487, 1159283, 1165103, 1170947, 1176827, 1182739, 1188667, 1194631,
            1200607, 1206619, 1212671, 1218727, 1224823, 1230967, 1237139, 1243343, 1249559, 1255811,
            1262119, 1268447, 1274803, 1281187, 1287623, 1294087, 1300571, 1307063, 1313623, 1320191,
            1326791, 1333411, 1340107, 1346827, 1353551, 1360327, 1367159, 1374007, 1380887, 1387783,
            1394747, 1401739, 1408763, 1415803, 1422899, 1430027, 1437199, 1444411, 1451603, 1458871,
            1466147, 1473503, 1480903, 1488343, 1495751, 1503247, 1510759, 1518343, 1525963, 1533583,
            1541251, 1548947, 1556719, 1564499, 1572359, 1580251, 1588159, 1596107, 1604123, 1612183,
            1620247, 1628383, 1636543, 1644691, 1652947, 1661243, 1669543, 1677899, 1686319, 1694767,
            1703267, 1711799, 1720399, 1729043, 1737691, 1746419, 1755179, 1763959, 1772819, 1781699,
            1790599, 1799591, 1808627, 1817663, 1826771, 1835923, 1845119, 1854379, 1863671, 1873019,
            1882403, 1891859, 1901359, 1910891, 1920487, 1930099, 1939787, 1949527, 1959283, 1969111,
            1978927, 1988839, 1998827, 2008807, 2018899, 2029003, 2039179, 2049419, 2059711, 2069959,
            2080339, 2090771, 2101259, 2106551, 2117119, 2127739, 2138387, 2149127, 2159923, 2170771,
            2181671, 2192623, 2203631, 2214691, 2225819, 2236987, 2248223, 2259503, 2270803, 2282207,
            2293567, 2305091, 2316667, 2328307, 2340007, 2351731, 2363507, 2375327, 2387243, 2399207,
            2411243, 2423359, 2435519, 2447743, 2460043, 2472403, 2484803, 2497259, 2509807, 2522407,
            2535059, 2547791, 2560583, 2573423, 2586343, 2599327, 2612383, 2625487, 2638651, 2651899,
            2665199, 2678551, 2692003, 2705519, 2719111, 2732759, 2746423, 2760223, 2774071, 2788007,
            2802011, 2816059, 2830151, 2844367, 2858623, 2872967, 2887363, 2901839, 2916383, 2930999,
            2945707, 2960467, 2975339, 2990279, 3005267, 3020351, 3035507, 3050759, 3066067, 3081443,
            3096911, 3112391, 3127979, 3143671, 3159439, 3175259, 3191099, 3207119, 3223223, 3239419,
            3255683, 3272039, 3288479, 3304991, 3321583, 3338263, 3355031, 3371867, 3388799, 3405791,
            3422807, 3439987, 3457271, 3474599, 3492043, 3509587, 3527219, 3544907, 3562711, 3580579,
            3598519, 3616583, 3634727, 3652991, 3671347, 3689771, 3708283, 3726911, 3745631, 3764443,
            3783343, 3802283, 3821327, 3840479, 3859759, 3879023, 3898483, 3918067, 3937751, 3957479,
            3977339, 3997307, 4017359, 4037531, 4057799, 4078187, 4098659, 4119239, 4139923, 4160711,
            4181579, 4202567, 4210807, 4231943, 4253203, 4274551, 4295999, 4317571, 4339207, 4361003,
            4382879, 4404899, 4426999, 4449227, 4471559, 4494019, 4516571, 4539247, 4562039, 4584959,
            4607987, 4631131, 4654399, 4677779, 4701239, 4724831, 4748563, 4772399, 4796371, 4820443,
            4844659, 4868999, 4893419, 4918007, 4942687, 4967491, 4992419, 5017447, 5042647, 5067967,
            5093423, 5119007, 5144707, 5170519, 5196467, 5222579, 5248787, 5275159, 5301623, 5328251,
            5355019, 5381927, 5408947, 5436127, 5463391, 5490787, 5518351, 5546071, 5573927, 5601907,
            5630039, 5658307, 5686739, 5715299, 5743987, 5772847, 5801843, 5830963, 5860243, 5889683,
            5919271, 5948939, 5978831, 6008867, 6038999, 6069311, 6099767, 6130391, 6161063, 6192023,
            6223099, 6254359, 6285787, 6317327, 6349043, 6380939, 6412999, 6445223, 6477599, 6510107,
            6542803, 6575671, 6608639, 6641839, 6675211, 6708739, 6742363, 6776207, 6810247, 6844447,
            6878803, 6913351, 6948079, 6982907, 7017979, 7053223, 7088611, 7124231, 7159987, 7195963,
            7232111, 7268423, 7304939, 7341647, 7378531, 7415599, 7452859, 7490303, 7527911, 7565627,
            7603627, 7641791, 7680191, 7718771, 7757543, 7796491, 7835647, 7874983, 7914551, 7954319,
            7994279, 8034451, 8074811, 8115383, 8156147, 8197099, 8238247, 8279627, 8321227, 8363023,
            8405003, 8419511, 8461787, 8504291, 8546999, 8589923, 8633063, 8676431, 8719987, 8763803,
            8807803, 8852059, 8896483, 8941171, 8986091, 9031207, 9076579, 9122143, 9167923, 9213979,
            9260263, 9306779, 9353483, 9400463, 9447667, 9495139, 9542843, 9590699, 9638891, 9687323,
            9735991, 9784903, 9834047, 9883463, 9933059, 9982939, 10033063, 10083443, 10134107, 10185011,
            10236179, 10287587, 10339267, 10391219, 10443431, 10495907, 10548623, 10601627, 10654871, 10708403,
            10762211, 10816271, 10870619, 10925227, 10980059, 11035223, 11090627, 11146279, 11202251, 11258483,
            11314987, 11371807, 11428931, 11486347, 11544047, 11602043, 11660339, 11718923, 11777791, 11836963,
            11896427, 11956199, 12016187, 12076567, 12137183, 12198139, 12259399, 12320983, 12382823, 12445039,
            12507559, 12570403, 12633559, 12697039, 12760843, 12824899, 12889339, 12954079, 13019143, 13084531,
            13150279, 13216331, 13282723, 13349411, 13416463, 13483751, 13551467, 13619563, 13687987, 13756739,
            13825831, 13895291, 13965103, 14035279, 14105759, 14176619, 14247847, 14319419, 14391359, 14463667,
            14536307, 14609351, 14682719, 14756491, 14830603, 14905123, 14980019, 15055259, 15130903, 15206899,
            15283291, 15360071, 15437239, 15514783, 15592739, 15671087, 15749819, 15828947, 15908423, 15988363,
            16068691, 16149431, 16230491, 16312039, 16394003, 16476371, 16559159, 16642343, 16725971, 16810007,
            16836587, 16921183, 17006167, 17091623, 17177507, 17263783, 17350519, 17437691, 17525243, 17613307,
            17701807, 17790739, 17880067, 17969911, 18060187, 18150911, 18242083, 18333703, 18425819, 18518363,
            18611419, 18704927, 18798907, 18893351, 18988267, 19083679, 19179551, 19275847, 19372699, 19470019,
            19567811, 19666123, 19764947, 19864267, 19964059, 20064371, 20165143, 20266391, 20368211, 20470547,
            20573411, 20676791, 20780659, 20885071, 20989967, 21095423, 21201347, 21307859, 21414923, 21522511,
            21630659, 21739351, 21848579, 21958367, 22068647, 22179511, 22290943, 22402951, 22515511, 22628651,
            22742303, 22856527, 22971259, 23086667, 23202643, 23319227, 23436407, 23554099, 23672459, 23791399,
            23910947, 24031087, 24151807, 24273163, 24395023, 24517607, 24640799, 24764611, 24889043, 25014071,
            25139767, 25266071, 25393031, 25520623, 25648867, 25777639, 25907143, 26037299, 26168099, 26299571,
            26431723, 26564507, 26697991, 26832139, 26966963, 27102419, 27238559, 27375419, 27512951, 27651191,
            27790127, 27929723, 28070071, 28211123, 28352887, 28495351, 28638539, 28782419, 28927039, 29072399,
            29218403, 29365207, 29512739, 29661043, 29810023, 29959819, 30110347, 30261643, 30413707, 30566519,
            30720119, 30874483, 31029587, 31185443, 31342139, 31499599, 31657783, 31816847, 31976723, 32137403,
            32298863, 32461159, 32624239, 32788099, 32952839, 33118391, 33284803, 33452047, 33619979, 33670103,
            33839243, 34009279, 34180163, 34351879, 34524491, 34697951, 34872283, 35047483, 35223599, 35400583,
            35578471, 35757247, 35936903, 36117467, 36298943, 36481343, 36664651, 36848891, 37033987, 37220047,
            37407059, 37595027, 37783927, 37973783, 38164571, 38356327, 38548999, 38742707, 38937319, 39132979,
            39329627, 39527123, 39725723, 39925339, 40125947, 40327571, 40530199, 40733867, 40938523, 41144203,
            41350943, 41558687, 41767483, 41977367, 42188287, 42400243, 42613303, 42827431, 43042631, 43258907,
            43476287, 43694747, 43914307, 44134931, 44356639, 44579503, 44803511, 45028639, 45254899, 45482291,
            45710831, 45940523, 46171351, 46403347, 46636519, 46870867, 47106379, 47343083, 47580983, 47820079,
            48060359, 48301867, 48544583, 48788503, 49033651, 49280003, 49527619, 49776479, 50026607, 50277979,
            50530619, 50784523, 51039683, 51296159, 51553903, 51812927, 52073279, 52334951, 52597891, 52862143,
            53127779, 53394727, 53663039, 53932651, 54203659, 54476027, 54749771, 55024859, 55301359, 55579243,
            55858459, 56139079, 56421151, 56704667, 56989571, 57275927, 57563699, 57852943, 58143583, 58435703,
            58729331, 59024443, 59321039, 59619127, 59918687, 60219779, 60522379, 60826511, 61132163, 61439239,
            61747963, 62058247, 62370079, 62683463, 62998451, 63314959, 63633079, 63952799, 64274159, 64597111,
            64921699, 65247907, 65575747, 65905267, 66236431, 66569267, 66903779, 67239967, 67338643, 67677007,
            68017067, 68358739, 68702143, 69047299, 69394219, 69742919, 70093327, 70445519, 70799507, 71155267,
            71512787, 71872127, 72233279, 72596243, 72961039, 73327651, 73696111, 74066411, 74438591, 74812651,
            75188591, 75566347, 75946067, 76327703, 76711231, 77096707, 77484083, 77873431, 78264727, 78657983,
            79053187, 79450363, 79849543, 80250763, 80654027, 81059287, 81466579, 81875951, 82287379, 82700791,
            83116367, 83534023, 83953763, 84375623, 84799619, 85225739, 85653947, 86084287, 86516863, 86951603,
            87388531, 87827647, 88268987, 88712527, 89158283, 89606287, 90056467, 90508987, 90963799, 91420867,
            91880263, 92341967, 92805983, 93272327, 93741019, 94212031, 94685419, 95161219, 95639387, 96119927,
            96602903, 97088339, 97576163, 98066491, 98559259, 99054523, 99552227, 100052467, 100555243, 101060539,
            101568287, 102078679, 102591631, 103107119, 103625239, 104145887, 104669179, 105195127, 105723743, 106254899,
            106788827, 107325451, 107864747, 108406763, 108951503, 109498943, 110049059, 110602031, 111157807, 111716383,
            112277699, 112841863, 113408767, 113978507, 114551263, 115126883, 115705351, 116286743, 116871091, 117458347,
            118048547, 118641739, 119237927, 119837059, 120439243, 121044431, 121652599, 122263903, 122878211, 123495683,
            124116191, 124739887, 125366567, 125996539, 126629663, 127265951, 127905443, 128548139, 129194083, 129843299,
            130495763, 131151491, 131810491, 132472831, 133138519, 133807547, 134479879, 134673607, 135350351, 136030471,
            136714027, 137400979, 138091427, 138785203, 139482599, 140183503, 140887919, 141595859, 142307287, 143022359,
            143741047, 144463339, 145189259, 145918711, 146651903, 147388823, 148129447, 148873787, 149621891, 150373759,
            151129399, 151888843, 152652103, 153419159, 154190087, 154964867, 155743583, 156526207, 157312763, 158103259,
            158897743, 159696211, 160498699, 161305211, 162115787, 162930419, 163749119, 164571971, 165398927, 166230007,
            167065303, 167904791, 168748499, 169596463, 170448683, 171305207, 172165991, 173031143, 173900563, 174774427,
            175652671, 176535311, 177422411, 178313951, 179209991, 180110471, 181015519, 181925111, 182839303, 183758039,
            184681411, 185609447, 186542099, 187479491, 188421539, 189368371, 190319959, 191276291, 192237431, 193203431,
            194174191, 195149939, 196130579, 197116159, 198106663, 199102151, 200102579, 201108043, 202118563, 203134123,
            204154859, 205180751, 206211799, 207248011, 208289351, 209336027, 210387907, 211445131, 212507651, 213575503,
            214648699, 215727247, 216811267, 217900763, 218995739, 220096183, 221202119, 222313643, 223430791, 224553523,
            225681923, 226815983, 227955727, 229101203, 230252411, 231409439, 232572299, 233740999, 234915539, 236095939,
            237282343, 238474711, 239672963, 240877339, 242087771, 243304219, 244526851, 245755619, 246990559, 248231707,
            249479099, 250732739, 251992667, 253258879, 254531507, 255810559, 257096039, 258387967, 259686391, 260991287,
            262302791, 263620879, 264945587, 266276947, 267614983, 268959767, 269344759, 270698227, 272058491, 273425591,
            274799579, 276180431, 277568219, 278963011, 280364803, 281773571, 283189499, 284612527, 286042723, 287480071,
            288924599, 290376451, 291835627, 293302123, 294775991, 296257271, 297745967, 299242171, 300745843, 302257051,
            303775919, 305302427, 306836599, 308378407, 309928027, 311485423, 313050587, 314623703, 316204703, 317793559,
            319390507, 320995471, 322608491, 324229639, 325858867, 327496339, 329142019, 330795991, 332458267, 334128887,
            335807831, 337495303, 339191227, 340895683, 342608719, 344330351, 346060571, 347799511, 349547071, 351303583,
            353068907, 354843119, 356626211, 358418243, 360219283, 362029403, 363848627, 365676923, 367514491, 369361231,
            371217299, 373082707, 374957483, 376841587, 378735251, 380638387, 382551083, 384473399, 386405387, 388347103,
            390298547, 392259767, 394230899, 396211903, 398202899, 400203871, 402214927, 404236087, 406267391, 408308899,
            410360539, 412422631, 414495091, 416577947, 418671283, 420775151, 422889583, 425014571, 427150247, 429296719,
            431453983, 433622011, 435800971, 437990923, 440191879, 442403887, 444627019, 446861267, 449106787, 451363571,
            453631727, 455911259, 458202211, 460504699, 462818767, 465144487, 467481851, 469831003, 472191851, 474564667,
            476949379, 479346103, 481754807, 484175663, 486608687, 489053951, 491511491, 493981363, 496463519, 498958307,
            501465563, 503985479, 506518063, 509063299, 511621387, 514192271, 516776131, 519372859, 521982751, 524605747,
            527241899, 529891199, 532553939, 535230083, 537919639, 538685971, 541392743, 544113239, 546847447, 549595367,
            552357139, 555132803, 557922367, 560725951, 563543663, 566375527, 569221603, 572081959, 574956703, 577845787,
            580749511, 583667831, 586600783, 589548499, 592511039, 595488451, 598480807, 601488211, 604510703, 607548371,
            610601371, 613669687, 616753427, 619852679, 622967503, 626097991, 629244167, 632406163, 635584031, 638777903,
            641987839, 645213847, 648456091, 651714607, 654989519, 658280863, 661588783, 664913323, 668254571, 671612587,
            674987507, 678379379, 681788203, 685214251, 688657483, 692117983, 695595931, 699091331, 702604327, 706134991,
            709683371, 713249591, 716833727, 720435851, 724056107, 727694531, 731351279, 735026371, 738719939, 742432063,
            746162863, 749912399, 753680731, 757468067, 761274403, 765099883, 768944587, 772808551, 776691959, 780594923,
            784517507, 788459759, 792421843, 796403831, 800405831, 804427927, 808470259, 812532911, 816615971, 820719539,
            824843651, 828988331, 833154031, 837340703, 841548427, 845777279, 850027351, 854298799, 858591751, 862906279,
            867242491, 871600487, 875980379, 880382287, 884806283, 889252471, 893721071, 898212083, 902725711, 907261963,
            911821051, 916403011, 921007907, 925636079, 930287503, 934962299, 939660587, 944382499, 949128119, 953897599,
            958691051, 963508519, 968350231, 973216267, 978106799, 983021807, 987961591, 992926211, 997915771, 1002930347,
            1007970143, 1013035271, 1018125743, 1023241907, 1028383823, 1033551523, 1038745151, 1043964947, 1049210831, 1054483151,
            1059782051, 1065107587, 1070459851, 1075839019, 1077368339, 1082782187, 1088223299, 1093691743, 1099187591, 1104711019,
            1110262327, 1115841499, 1121448739, 1127084059, 1132747771, 1138439959, 1144160711, 1149910183, 1155688603, 1161496079,
            1167332711, 1173198647, 1179094079, 1185019067, 1190973899, 1196958667, 1202973511, 1209018599, 1215094019, 1221199951,
            1227336631, 1233504079, 1239702463, 1245932059, 1252193003, 1258485419, 1264809463, 1271165167, 1277552923, 1283972759,
            1290424799, 1296909343, 1303426459, 1309976287, 1316559071, 1323174883, 1329823987, 1336506463, 1343222567, 1349972251,
            1356756031, 1363573879, 1370425967, 1377312463, 1384233491, 1391189419, 1398180307, 1405206307, 1412267611, 1419364259,
            1426496711, 1433664959, 1440869279, 1448109779, 1455386671, 1462700131, 1470050363, 1477437523, 1484861771, 1492323307,
            1499822383, 1507359151, 1514933747, 1522546447, 1530197423, 1537886851, 1545614899, 1553381771, 1561187699, 1569032827,
            1576917379, 1584841567, 1592805583, 1600809611, 1608853859, 1616938507, 1625063819, 1633229951, 1641437099, 1649685467,
            1657975307, 1666306819, 1674680207, 1683095671, 1691553427, 1700053627, 1708596587, 1717182347, 1725811267, 1734483643,
            1743199571, 1751959367, 1760763107, 1769611087, 1778503583, 1787440747, 1796422847, 1805449999, 1814522603, 1823640799,
            1832804767, 1842014791, 1851271043, 1860573907, 1869923411, 1879319999, 1888763743, 1898254999, 1907793931, 1917380807,
            1927015879, 1936699351, 1946431363, 1956212243, 1966042451, 1975922059, 1985851247, 1995830323, 2005859543, 2015939239,
            2026069559, 2036250751, 2046483151, 2056766983, 2067102431, 2077489807, 2087929451, 2098421519, 2108966287, 2119564099,
            2130215159, 2140919723,
    };


    // Compile-time constant expressions
    private static final int MAX_REGULAR_CAPACITY_FOR_DOUBLED_ARRAY = 107325451;
    private static final int MAX_REGULAR_INT_CAPACITY = 2140919723;
    static {
        if (MAX_REGULAR_INT_CAPACITY != REGULAR_INT_CAPACITIES[REGULAR_INT_CAPACITIES.length - 1] ||
                binarySearch(REGULAR_INT_CAPACITIES, MAX_REGULAR_CAPACITY_FOR_DOUBLED_ARRAY) < 0)
            throw new AssertionError();
    }

    /** == 2^30 - 41 */
    private static final int MAX_CAPACITY_FOR_DOUBLED_ARRAY = 1073741783;

    /** The highest qHash prime below Integer.MAX_VALUE (which is a qHash prime too). */
    private static final int MAX_INT_CAPACITY = 2147483587;

    public static boolean isMaxCapacity(int capacity) {
        // MAX_INT_CAPACITY or Integer.MAX_VALUE
        return capacity >= MAX_INT_CAPACITY;
    }

    public static boolean isMaxCapacity(int capacity, boolean doubleSizedArrays) {
        return capacity >= (!doubleSizedArrays ? MAX_INT_CAPACITY : MAX_CAPACITY_FOR_DOUBLED_ARRAY);
    }


    private static final long[] REGULAR_LONG_CAPACITIES = new long[] {
            2151678103L, 2154731503L, 2165559283L, 2176441471L, 2187378343L, 2198370191L, 2209417163L, 2220519727L,
            2231677999L, 2242892447L, 2254163239L, 2265490691L, 2276875039L, 2288316587L, 2299815659L, 2311372423L, 2322987283L, 2334660571L,
            2346392527L, 2358183439L, 2370033559L, 2381943251L, 2393912767L, 2405942467L, 2418032623L, 2430183479L, 2442395407L, 2454668687L,
            2467003699L, 2479400587L, 2491859879L, 2504381683L, 2516966443L, 2529614491L, 2542326079L, 2555101583L, 2567941267L, 2580845419L,
            2593814459L, 2606848691L, 2619948427L, 2633113927L, 2646345643L, 2659643839L, 2673008867L, 2686441063L, 2699940743L, 2713508251L,
            2727143827L, 2740848023L, 2754621091L, 2768463407L, 2782375279L, 2796356947L, 2810408971L, 2824531627L, 2838725243L, 2852990131L,
            2867326747L, 2881735387L, 2896216363L, 2910770167L, 2925397151L, 2940097627L, 2954871967L, 2969720491L, 2984643703L, 2999641903L,
            3014715439L, 3029864707L, 3045090127L, 3060392059L, 3075770899L, 3091227019L, 3106760779L, 3122372611L, 3138062887L, 3153832007L,
            3169680359L, 3185608379L, 3201616459L, 3217704979L, 3233874331L, 3250124947L, 3266457211L, 3282871499L, 3299368327L, 3315947951L,
            3332611003L, 3349357747L, 3366188671L, 3383104171L, 3400104667L, 3417190591L, 3434362391L, 3451620439L, 3468965231L, 3486397171L,
            3503916751L, 3521524339L, 3539220439L, 3557005327L, 3574879603L, 3592843799L, 3610898227L, 3629043419L, 3647279771L, 3665607739L,
            3684027871L, 3702540559L, 3721146283L, 3739845451L, 3758638603L, 3777526147L, 3796508687L, 3815586611L, 3834760387L, 3854030459L,
            3873397427L, 3892861699L, 3912423751L, 3932084159L, 3951843367L, 3971701871L, 3991660063L, 4011718591L, 4031877959L, 4052138539L,
            4072501007L, 4092965791L, 4113533387L, 4134204383L, 4154979247L, 4175858471L, 4196842679L, 4217932319L, 4239127931L, 4260430051L,
            4281839203L, 4303355939L, 4309459963L, 4331115539L, 4352879899L, 4374753659L, 4396737311L, 4418831467L, 4441036631L, 4463353351L,
            4485782239L, 4508323811L, 4530978559L, 4553747267L, 4576630379L, 4599628519L, 4622742127L, 4645971931L, 4669318471L, 4692782359L,
            4716364019L, 4740064327L, 4763883703L, 4787822783L, 4811882143L, 4836062323L, 4860364139L, 4884788039L, 4909334671L, 4934004667L,
            4958798651L, 4983717103L, 5008760879L, 5033930479L, 5059226563L, 5084649707L, 5110200691L, 5135879971L, 5161688383L, 5187626491L,
            5213694911L, 5239894367L, 5266225423L, 5292688799L, 5319285211L, 5346015251L, 5372879639L, 5399878987L, 5427014011L, 5454285379L,
            5481693827L, 5509240027L, 5536924643L, 5564748359L, 5592711907L, 5620815979L, 5649061279L, 5677448471L, 5705978287L, 5734651523L,
            5763468827L, 5792430979L, 5821538651L, 5850792611L, 5880193531L, 5909742211L, 5939439343L, 5969285747L, 5999282143L, 6029429243L,
            6059727823L, 6090178711L, 6120782579L, 6151540231L, 6182452483L, 6213520063L, 6244743683L, 6276124187L, 6307662451L, 6339359219L,
            6371215267L, 6403231423L, 6435408443L, 6467747023L, 6500248211L, 6532912667L, 6565741339L, 6598734971L, 6631894391L, 6665220271L,
            6698713807L, 6732375667L, 6766206683L, 6800207699L, 6834379523L, 6868723087L, 6903239171L, 6937928779L, 6972792719L, 7007831827L,
            7043046931L, 7078439059L, 7114008983L, 7149757763L, 7185686143L, 7221795103L, 7258085491L, 7294558259L, 7331214307L, 7368054559L,
            7405079939L, 7442291371L, 7479689803L, 7517276167L, 7555051363L, 7593016439L, 7631172239L, 7669519811L, 7708060111L, 7746793991L,
            7785722599L, 7824846791L, 7864167559L, 7903685947L, 7943402923L, 7983319507L, 8023436683L, 8063755451L, 8104276811L, 8145001807L,
            8185931363L, 8227066583L, 8268408559L, 8309958263L, 8351716771L, 8393685127L, 8435864447L, 8478255659L, 8520859931L, 8563678307L,
            8606711851L, 8618915047L, 8662225991L, 8705754763L, 8749502263L, 8793469603L, 8837657887L, 8882068159L, 8926701431L, 8971559143L,
            9016642339L, 9061952099L, 9107489539L, 9153255791L, 9199252019L, 9245479379L, 9291939071L, 9338632207L, 9385559779L, 9432723323L,
            9480123907L, 9527762707L, 9575640863L, 9623759603L, 9672120191L, 9720723751L, 9769571599L, 9818664811L, 9868004791L, 9917592743L,
            9967429867L, 10017517283L, 10067856563L, 10118448787L, 10169295203L, 10220397163L, 10271755919L, 10323372779L, 10375248979L, 10427385847L,
            10479784739L, 10532446907L, 10585373707L, 10638566479L, 10692026599L, 10745755343L, 10799754083L, 10854024191L, 10908567023L, 10963383911L,
            11018476247L, 11073845459L, 11129492923L, 11185419991L, 11241628087L, 11298118651L, 11354893091L, 11411952791L, 11469299243L, 11526933823L,
            11584858091L, 11643073367L, 11701581247L, 11760383123L, 11819480507L, 11878874863L, 11938567699L, 11998560419L, 12058854671L, 12119451907L,
            12180353659L, 12241561439L, 12303076811L, 12364901299L, 12427036463L, 12489483863L, 12552245051L, 12615321647L, 12678715139L, 12742427263L,
            12806459543L, 12870813607L, 12935491043L, 13000493507L, 13065822599L, 13131479947L, 13197467243L, 13263786167L, 13330438339L, 13397425451L,
            13464749183L, 13532411147L, 13600413139L, 13668756887L, 13737444107L, 13806476443L, 13875855703L, 13945583579L, 14015661887L, 14086092283L,
            14156876647L, 14228016707L, 14299514263L, 14371371059L, 14443589003L, 14516169847L, 14589115423L, 14662427543L, 14736107987L, 14810158739L,
            14884581631L, 14959378519L, 15034551263L, 15110101759L, 15186031787L, 15262343443L, 15339038623L, 15416119123L, 15493587019L, 15571444211L,
            15649692659L, 15728334319L, 15807371143L, 15886805131L, 15966638279L, 16046872603L, 16127510083L, 16208552791L, 16290002683L, 16371861971L,
            16454132599L, 16536816643L, 16619916191L, 16703433347L, 16787370191L, 16871728763L, 16956511267L, 17041719859L, 17127356539L, 17213423639L,
            17237825987L, 17324448199L, 17411505719L, 17499000707L, 17586935383L, 17675311879L, 17764132511L, 17853399451L, 17943114947L, 18033281327L,
            18123900811L, 18214975679L, 18306508183L, 18398500643L, 18490955419L, 18583874731L, 18677261023L, 18771116587L, 18865443719L, 18960244943L,
            19055522539L, 19151278919L, 19247516419L, 19344237587L, 19441444787L, 19539140459L, 19637327063L, 19736007079L, 19835182951L, 19934857207L,
            20035032299L, 20135710787L, 20236895191L, 20338588087L, 20440792003L, 20543509499L, 20646743179L, 20750495639L, 20854769459L, 20959567247L,
            21064891699L, 21170745319L, 21277130879L, 21384051083L, 21491508611L, 21599506139L, 21708046331L, 21817131967L, 21926765747L, 22036950487L,
            22147688923L, 22258983811L, 22370837987L, 22483254247L, 22596235411L, 22709784311L, 22823903779L, 22938596731L, 23053865951L, 23169714487L,
            23286145087L, 23403160843L, 23520764651L, 23638959419L, 23757748159L, 23877133823L, 23997119347L, 24117707851L, 24238902307L, 24360705791L,
            24483121363L, 24606152107L, 24729801023L, 24854071367L, 24978966191L, 25104488531L, 25230641699L, 25357428743L, 25484852927L, 25612917511L,
            25741625603L, 25870980503L, 26000985343L, 26131643543L, 26262958307L, 26394932939L, 26527570687L, 26660875019L, 26794849243L, 26929496723L,
            27064820819L, 27200824939L, 27337512427L, 27474886771L, 27612951479L, 27751710011L, 27891165803L, 28031322391L, 28172183251L, 28313751919L,
            28456032067L, 28599027199L, 28742740891L, 28887176743L, 29032338427L, 29178229543L, 29324853763L, 29472214799L, 29620316371L, 29769162167L,
            29918755907L, 30069101383L, 30220202359L, 30372062579L, 30524685967L, 30678076339L, 30832237399L, 30987173263L, 31142887663L, 31299384583L,
            31456667831L, 31614741451L, 31773609431L, 31933275767L, 32093744467L, 32255019527L, 32417104991L, 32580004991L, 32743723591L, 32908264867L,
            33073632947L, 33239832107L, 33406866359L, 33574740047L, 33743457287L, 33913022383L, 34083439531L, 34254713071L, 34426847267L, 34475648759L,
            34648893199L, 34823008079L, 34997997959L, 35173867279L, 35350620323L, 35528261611L, 35706795559L, 35886226667L, 36066559447L, 36247798387L,
            36429948059L, 36613013119L, 36796998059L, 36981907583L, 37167746159L, 37354518703L, 37542229847L, 37730884183L, 37920486599L, 38111041807L,
            38302554551L, 38495029691L, 38688471959L, 38882886323L, 39078277663L, 39274650763L, 39472010783L, 39670362539L, 39869711071L, 40070061371L,
            40271418443L, 40473787363L, 40677173219L, 40881581047L, 41087016079L, 41293483447L, 41500988383L, 41709536059L, 41919131659L, 42129780551L,
            42341487983L, 42554259263L, 42768099727L, 42983014783L, 43199009831L, 43416090227L, 43634261519L, 43853529143L, 44073898619L, 44295375479L,
            44517965299L, 44741673659L, 44966506187L, 45192468523L, 45419566243L, 45647805251L, 45877191179L, 46107729823L, 46339426951L, 46572288379L,
            46806319891L, 47041527371L, 47277916919L, 47515494379L, 47754265703L, 47994236887L, 48235413871L, 48477802823L, 48721409831L, 48966240859L,
            49212302327L, 49459600219L, 49708140791L, 49957930411L, 50208975239L, 50461281643L, 50714855903L, 50969704343L, 51225833419L, 51483249607L,
            51741959351L, 52001969143L, 52263285551L, 52525915103L, 52789864343L, 53055139931L, 53321748643L, 53589697079L, 53858991943L, 54129640091L,
            54401648299L, 54675023311L, 54949772159L, 55225901551L, 55503418639L, 55782330259L, 56062643419L, 56344365127L, 56627502619L, 56912062903L,
            57198053167L, 57485480551L, 57774352291L, 58064675579L, 58356457867L, 58649706347L, 58944428483L, 59240631623L, 59538323167L, 59837510699L,
            60138201611L, 60440403619L, 60744124223L, 61049371051L, 61356151807L, 61664474171L, 61974345887L, 62285774731L, 62598768499L, 62913335143L,
            63229482527L, 63547218563L, 63866551291L, 64187488679L, 64510038847L, 64834209883L, 65160009923L, 65487447119L, 65816529731L, 66147266023L,
            66479664283L, 66813732847L, 67149480179L, 67486914707L, 67826044807L, 68166879019L, 68509426103L, 68853694499L, 68951293447L, 69297782299L,
            69646012279L, 69995992211L, 70347730823L, 70701236999L, 71056519591L, 71413587491L, 71772449699L, 72133115227L, 72495592927L, 72859892383L,
            73226022383L, 73593992267L, 73963811323L, 74335488691L, 74709033811L, 75084456071L, 75461764879L, 75840969707L, 76222080083L, 76605105607L,
            76990055867L, 77376940439L, 77765769259L, 78156551999L, 78549298423L, 78944018459L, 79340721991L, 79739419063L, 80140119643L, 80542833731L,
            80947571587L, 81354343267L, 81763159043L, 82174029071L, 82586963843L, 83001973711L, 83419069031L, 83838260327L, 84259558067L, 84682972931L,
            85108515407L, 85536196379L, 85966026511L, 86398016587L, 86832177451L, 87268519979L, 87707055223L, 88147794179L, 88590747899L, 89035927363L,
            89483344031L, 89933009071L, 90384933703L, 90839129291L, 91295607307L, 91754379007L, 92215456283L, 92678850403L, 93144573199L, 93612636331L,
            94083051563L, 94555830683L, 95030985571L, 95508528187L, 95988470531L, 96470824631L, 96955602643L, 97442816687L, 97932479011L, 98424601999L,
            98919197959L, 99416279351L, 99915858563L, 100417948187L, 100922560987L, 101429709499L, 101939406479L, 102451664759L, 102966497219L, 103483916747L,
            104003936423L, 104526569219L, 105051828359L, 105579726799L, 106110278179L, 106643495363L, 107179392259L, 107717982143L, 108259278499L, 108803294911L,
            109350045019L, 109899542719L, 110451801659L, 111006835811L, 111564659071L, 112125285479L, 112688729119L, 113255004103L, 113824124671L, 114396104971L,
            114970959683L, 115548703187L, 116129349823L, 116712914323L, 117299411347L, 117888855523L, 118481261827L, 119076645047L, 119675020039L, 120276402011L,
            120880805959L, 121488247151L, 122098740851L, 122712302347L, 123328947023L, 123948690451L, 124571548151L, 125197535747L, 125826669047L, 126458963863L,
            127094435899L, 127733101267L, 128374976087L, 129020076431L, 129668418491L, 130320018551L, 130974893011L, 131633058299L, 132294530899L, 132959327531L,
            133627464847L, 134298959563L, 134973828679L, 135652089119L, 136333757863L, 137018852107L, 137707388983L, 137902581967L, 138595559647L, 139292019683L,
            139991979551L, 140695456711L, 141402469031L, 142113034031L, 142827169879L, 143544894323L, 144266225447L, 144991181327L, 145719780119L, 146452040291L,
            147187980151L, 147927618227L, 148670973079L, 149418063239L, 150168907711L, 150923525323L, 151681934983L, 152444155663L, 153210206627L, 153980107123L,
            154753876427L, 155531534071L, 156313099511L, 157098592463L, 157888032611L, 158681439767L, 159478833931L, 160280235103L, 161085663359L, 161895139051L,
            162708682379L, 163526313947L, 164348054203L, 165173923807L, 166003943519L, 166838134087L, 167676516607L, 168519112159L, 169365941867L, 170217026939L,
            171072388759L, 171932048983L, 172796029103L, 173664350851L, 174537035983L, 175414106339L, 176295584207L, 177181491623L, 178071850783L, 178966684063L,
            179866014127L, 180769863431L, 181678254679L, 182591210723L, 183508754483L, 184430909011L, 185357697487L, 186289143151L, 187225269479L, 188166099851L,
            189111658123L, 190061967919L, 191017053167L, 191976937847L, 192941646059L, 193911202027L, 194885630171L, 195864954931L, 196849200763L, 197838392711L,
            198832555447L, 199831714003L, 200835893347L, 201845118863L, 202859415911L, 203878809931L, 204903326431L, 205932991343L, 206967830479L, 208007869787L,
            209053135463L, 210103653731L, 211159450979L, 212220553739L, 213286988587L, 214358782487L, 215435962139L, 216518554871L, 217606587799L, 218700088231L,
            219799083643L, 220903601647L, 222013669907L, 223129316471L, 224250569159L, 225377456431L, 226510006363L, 227648247551L, 228792208543L, 229941918131L,
            231097405139L, 232258698523L, 233425827451L, 234598821547L, 235777709807L, 236962522331L, 238153288691L, 239350038803L, 240552802759L, 241761610787L,
            242976493219L, 244197480587L, 245424603491L, 246657892919L, 247897379783L, 249143095163L, 250395070483L, 251653337147L, 252917926759L, 254188871087L,
            255466202027L, 256749951751L, 258040152467L, 259336836643L, 260640036827L, 261949785731L, 263266116307L, 264589061587L, 265918654819L, 267254929367L,
            268597918891L, 269947657123L, 271304177971L, 272667515539L, 274037704051L, 275414777927L, 275805159103L, 277191114623L, 278584034711L, 279983954399L,
            281390908879L, 282804933503L, 284226063739L, 285654335347L, 287089784183L, 288532446403L, 289982358131L, 291439555711L, 292904076083L, 294375955843L,
            295855232003L, 297341941643L, 298836122251L, 300337811303L, 301847046439L, 303363865631L, 304888307147L, 306420409151L, 307960210183L, 309507748919L,
            311063064223L, 312626195159L, 314197181027L, 315776061311L, 317362875611L, 318957663847L, 320560466111L, 322171322723L, 323790273959L, 325417360643L,
            327052623743L, 328696104179L, 330347843327L, 332007882683L, 333676263931L, 335353029071L, 337038220147L, 338731879463L, 340434049679L, 342144773479L,
            343864093891L, 345592054099L, 347328697559L, 349074067891L, 350828208859L, 352591164671L, 354362979559L, 356143697999L, 357933364739L, 359732024767L,
            361539723331L, 363356505847L, 365182417891L, 367017505411L, 368861814463L, 370715391407L, 372578282819L, 374450535331L, 376332196291L, 378223312811L,
            380123932451L, 382034102803L, 383953872151L, 385883288491L, 387822400451L, 389771256703L, 391729906163L, 393698398103L, 395676781999L, 397665107471L,
            399663424547L, 401671783463L, 403690234543L, 405718828631L, 407757616663L, 409806649907L, 411865979747L, 413935658011L, 416015736671L, 418106267987L,
            420207304507L, 422318898971L, 424441104463L, 426573974327L, 428717562083L, 430871921687L, 433037107219L, 435213172967L, 437400173759L, 439598164531L,
            441807200503L, 444027337139L, 446258630267L, 448501135939L, 450754910479L, 453020010467L, 455296492883L, 457584414923L, 459883834043L, 462194808043L,
            464517394987L, 466851653231L, 469197641387L, 471555418463L, 473925043619L, 476306576467L, 478700076851L, 481105604807L, 483523220863L, 485952985783L,
            488394960511L, 490849206467L, 493315785311L, 495794758967L, 498286189871L, 500790140563L, 503306673899L, 505835853119L, 508377741743L, 510932403703L,
            513499903171L, 516080304659L, 518673673019L, 521280073351L, 523899571123L, 526532232263L, 529178122843L, 531837309379L, 534509858591L, 537195837743L,
            539895314227L, 542608355999L, 545335031147L, 548075408107L, 550829555791L, 553301556503L, 556081966303L, 558876348011L, 561684771863L, 564507308311L,
            567344028451L, 570195003419L, 573060304891L, 575940004883L, 578834175671L, 581742890107L, 584666221199L, 587604242399L, 590557027507L, 593524650751L,
            596507186647L, 599504710159L, 602517296543L, 605545021567L, 608587961231L, 611646192187L, 614719791131L, 617808835279L, 620913402283L, 624033570107L,
            627169417163L, 630321022259L, 633488464579L, 636671823679L, 639871179539L, 643086612559L, 646318203523L, 649566033691L, 652830184607L, 656110738279L,
            659407777163L, 662721383959L, 666051642043L, 669398635207L, 672762447443L, 676143163039L, 679540867307L, 682955645503L, 686387583391L, 689836767227L,
            693303283627L, 696787219699L, 700288662991L, 703807701427L, 707344423543L, 710898918091L, 714471274427L, 718061582327L, 721669931923L, 725296413983L,
            728941119551L, 732604140211L, 736285568003L, 739985495471L, 743704015543L, 747441221623L, 751197207647L, 754972067851L, 758765897327L, 762578791279L,
            766410845443L, 770262156211L, 774132820247L, 778022934907L, 781932597871L, 785861907359L, 789810962111L, 793779861403L, 797768704751L, 801777592667L,
            805806625739L, 809855905207L, 813925532831L, 818015610803L, 822126241931L, 826257529567L, 830409577379L, 834582489791L, 838776371647L, 842991328271L,
            847227465547L, 851484889891L, 855763708399L, 860064028511L, 864385958291L, 868729606243L, 873095081591L, 877482493967L, 881891953711L, 886323571487L,
            890777458751L, 895253727331L, 899752489751L, 904273859011L, 908817948743L, 913384873039L, 917974746727L, 922587685099L, 927223804079L, 931883220083L,
            936566050331L, 941272412303L, 946002424351L, 950756205359L, 955533874663L, 960335552411L, 965161359179L, 970011416251L, 974885845303L, 979784768983L,
            984708310511L, 989656593439L, 994629742091L, 999627881387L, 1004651137067L, 1009699635227L, 1014773502719L, 1019872867043L, 1024997856319L, 1030148599303L,
            1035325225387L, 1040527864631L, 1045756647671L, 1051011706183L, 1056293172019L, 1061601177907L, 1066935857179L, 1072297343879L, 1077685772719L, 1083101279107L,
            1088543999083L, 1094014069427L, 1099511627563L
    };

    /**
     * = 2^40 - 213 (the highest qHash prime below 2^40)
     *
     * Compile-time constant expression
     */
    private static final long MAX_REGULAR_LONG_CAPACITY = 1099511627563L;
    static {
        if (MAX_REGULAR_LONG_CAPACITY !=
                REGULAR_LONG_CAPACITIES[REGULAR_LONG_CAPACITIES.length - 1])
            throw new AssertionError();
    }

    // GENERATION

    public static void main(String[] args) {
        long power = Long.parseLong(args[0]);
        double maxDiff = Double.parseDouble(args[1]);
        long[] capacities = generateRegularCapacities(1L << power, maxDiff);
        for (int i = 0; i < capacities.length; i += 10) {
            for (int j = i; j < Math.min(i + 10, capacities.length); j++) {
                System.out.print(capacities[j] + ", ");
            }
            System.out.println();
        }
    }

    /**
     * Searches for "qHash" primes (4k + 3 primes), not very close to powers of 2.
     *
     * While possible, keeps max difference between neighbouring capacities not greater
     * than {@code maxDiff}: cap / next cap > 1 - maxDiff.
     *
     * @param maxDiff maximum difference between neighbouring capacities, keeping while possible
     * @return array containing generated capacities in ascending order
     */
    private static long[] generateRegularCapacities(long limit, double maxDiff) {
        int avoidBitsAroundPowersOf2 = 1;
        while ((1.0 / (1 << avoidBitsAroundPowersOf2)) * 2 > maxDiff) {
            avoidBitsAroundPowersOf2++;
        }

        ArrayList capacities = new ArrayList();
        long highPrime;
        for (long i = limit - 1L; ; i--) {
            if (isQHashPrime(i)) {
                highPrime = i;
                capacities.add(highPrime);
                break;
            }
        }
        int nearPowerOf2Count = 0;
        while (true) {
            long minPrevPrime = ((long) ((1 - maxDiff) * highPrime)) + 1;
            long qPrime = 0L;
            long qPrimeNearToPowerOf2 = 0L;
            for (long i = minPrevPrime; i < highPrime; i++) {
                if (isQHashPrime(i)) {
                    long lowerPowerOf2 = Long.highestOneBit(i);
                    long avoidDiffWithPowerOf2 = lowerPowerOf2 >> avoidBitsAroundPowersOf2;
                    if (abs(lowerPowerOf2 - i) < avoidDiffWithPowerOf2) {
                        qPrimeNearToPowerOf2 = i;
                        if (lowerPowerOf2 + avoidDiffWithPowerOf2 >= highPrime)
                            break;
                        for (long j = lowerPowerOf2 + avoidDiffWithPowerOf2; j > i; j--) {
                            if (isQHashPrime(j)) {
                                qPrimeNearToPowerOf2 = j;
                                break;
                            }
                        }
                        i = lowerPowerOf2 + avoidDiffWithPowerOf2;
                        continue;
                    }
                    long higherPowerOf2 = lowerPowerOf2 << 1;
                    avoidDiffWithPowerOf2 = higherPowerOf2 >> avoidBitsAroundPowersOf2;
                    if (abs(higherPowerOf2 - i) < avoidDiffWithPowerOf2) {
                        qPrimeNearToPowerOf2 = i;
                        if (higherPowerOf2 + avoidDiffWithPowerOf2 >= highPrime)
                            break;
                        for (long j = higherPowerOf2 + avoidDiffWithPowerOf2;
                             abs(higherPowerOf2 - i) < abs(higherPowerOf2 - j); j--) {
                            if (isQHashPrime(j)) {
                                qPrimeNearToPowerOf2 = j;
                                break;
                            }
                        }
                        i = higherPowerOf2 + avoidDiffWithPowerOf2;
                        continue;
                    }
                    qPrime = i;
                    break;
                }
            }
            long prevPrime = qPrime;
            if (prevPrime == 0) {
                prevPrime = qPrimeNearToPowerOf2;
                if (prevPrime != 0) {
                    nearPowerOf2Count++;
                } else {
                    break;
                }
            }
            capacities.add(prevPrime);
            System.out.println(prevPrime);
            highPrime = prevPrime;
        }
        System.out.println("nearPowerOf2Count: " + nearPowerOf2Count);
        System.out.println("Lowest diff prime: " + highPrime);
        // Differences between nearest qPrimes becomes greater than maxDiff.
        for (long i = highPrime - 1L; i > 2L; i--) {
            if (isQHashPrime(i))
                capacities.add(i);
        }

        long[] res = new long[capacities.size()];
        for (int i = capacities.size() - 1, j = 0; i >= 0; i--) {
            res[j++] = capacities.get(i);
        }
        return res;
    }

    private static boolean isQHashPrime(long i) {
        return (i % 4L == 3L) && isPrime(i);
    }

    public static boolean isPrime(long n) {
        if (!BigInteger.valueOf(n).isProbablePrime(10))
            return false;
        if (n > 2L && (n & 1L) == 0)
            return false;
        for (long i = 3L; i * i <= n; i += 2L) {
            if (n % i == 0)
                return false;
        }
        return true;
    }

    private QHashCapacities() {}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy