l2j_mobius/L2J_Mobius_HighFive/java/com/l2jmobius/util/PrimeFinder.java
MobiusDev 34fc592ced
2016-10-21 21:26:21 +00:00

353 lines
6.6 KiB
Java

/*
* Copyright (c) 1999 CERN - European Organization for Nuclear Research.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear in
* supporting documentation. CERN makes no representations about the
* suitability of this software for any purpose. It is provided "as is"
* without expressed or implied warranty.
*/
package com.l2jmobius.util;
import java.util.Arrays;
/**
* <b>Modified for Trove to use the java.util.Arrays sort/search<br>
* algorithms instead of those provided with colt.</b><br>
* Used to keep hash table capacities prime numbers.<br>
* Not of interest for users; only for implementors of hashtables.<br>
* <p>
* Choosing prime numbers as hash table capacities is a good idea<br>
* to keep them working fast, particularly under hash table expansions.<br>
* <p>
* However, JDK 1.2, JGL 3.1 and many other toolkits do nothing to keep capacities prime.<br>
* This class provides efficient means to choose prime capacities.
* <p>
* Choosing a prime is <tt>O(log 300)</tt> (binary search in a list of 300 ints).<br>
* Memory requirements: 1 KB static memory.<br>
* @author wolfgang.hoschek@cern.ch
* @version 1.0, 09/24/99
*/
public final class PrimeFinder
{
/**
* The largest prime this class can generate; currently equal to <tt>Integer.MAX_VALUE</tt>.
*/
public static final int LARGEST_PRIME = Integer.MAX_VALUE; // yes, it is prime.
/**
* The prime number list consists of 11 chunks.<br>
* Each chunk contains prime numbers.<br>
* A chunk starts with a prime P1.<br>
* The next element is a prime P2.<br>
* P2 is the smallest prime for which holds: P2 >= 2*P1.<br>
* The next element is P3, for which the same holds with respect to P2, and so on. Chunks are chosen such that for any desired capacity >= 1000<br>
* the list includes a prime number <= desired capacity * 1.11.<br>
* Therefore, primes can be retrieved which are quite close to any<br>
* desired capacity, which in turn avoids wasting memory.<br>
* For example, the list includes<br>
* 1039,1117,1201,1277,1361,1439,1523,1597,1759,1907,2081.<br>
* So if you need a prime >= 1040, you will find a prime <= 1040*1.11=1154.<br> Chunks are chosen such that they are optimized for a hashtable growthfactor of 2.0;<br>
* If your hashtable has such a growthfactor then, after initially<br>
* "rounding to a prime" upon hashtable construction, it will<br>
* later expand to prime capacities such that there exist no better primes.<br>
* In total these are about 32*10=320 numbers -> 1 KB of static memory needed.<br>
* If you are stingy, then delete every second or fourth chunk.
*/
private static final int[] PRIME_CAPACITIES =
{
// chunk #0
LARGEST_PRIME,
// chunk #1
5,
11,
23,
47,
97,
197,
397,
797,
1597,
3203,
6421,
12853,
25717,
51437,
102877,
205759,
411527,
823117,
1646237,
3292489,
6584983,
13169977,
26339969,
52679969,
105359939,
210719881,
421439783,
842879579,
1685759167,
// chunk #2
433,
877,
1759,
3527,
7057,
14143,
28289,
56591,
113189,
226379,
452759,
905551,
1811107,
3622219,
7244441,
14488931,
28977863,
57955739,
115911563,
231823147,
463646329,
927292699,
1854585413,
// chunk #3
953,
1907,
3821,
7643,
15287,
30577,
61169,
122347,
244703,
489407,
978821,
1957651,
3915341,
7830701,
15661423,
31322867,
62645741,
125291483,
250582987,
501165979,
1002331963,
2004663929,
// chunk #4
1039,
2081,
4177,
8363,
16729,
33461,
66923,
133853,
267713,
535481,
1070981,
2141977,
4283963,
8567929,
17135863,
34271747,
68543509,
137087021,
274174111,
548348231,
1096696463,
// chunk #5
31,
67,
137,
277,
557,
1117,
2237,
4481,
8963,
17929,
35863,
71741,
143483,
286973,
573953,
1147921,
2295859,
4591721,
9183457,
18366923,
36733847,
73467739,
146935499,
293871013,
587742049,
1175484103,
// chunk #6
599,
1201,
2411,
4831,
9677,
19373,
38747,
77509,
155027,
310081,
620171,
1240361,
2480729,
4961459,
9922933,
19845871,
39691759,
79383533,
158767069,
317534141,
635068283,
1270136683,
// chunk #7
311,
631,
1277,
2557,
5119,
10243,
20507,
41017,
82037,
164089,
328213,
656429,
1312867,
2625761,
5251529,
10503061,
21006137,
42012281,
84024581,
168049163,
336098327,
672196673,
1344393353,
// chunk #8
3,
7,
17,
37,
79,
163,
331,
673,
1361,
2729,
5471,
10949,
21911,
43853,
87719,
175447,
350899,
701819,
1403641,
2807303,
5614657,
11229331,
22458671,
44917381,
89834777,
179669557,
359339171,
718678369,
1437356741,
// chunk #9
43,
89,
179,
359,
719,
1439,
2879,
5779,
11579,
23159,
46327,
92657,
185323,
370661,
741337,
1482707,
2965421,
5930887,
11861791,
23723597,
47447201,
94894427,
189788857,
379577741,
759155483,
1518310967,
// chunk #10
379,
761,
1523,
3049,
6101,
12203,
24407,
48817,
97649,
195311,
390647,
781301,
1562611,
3125257,
6250537,
12501169,
25002389,
50004791,
100009607,
200019221,
400038451,
800076929,
1600153859
};
static
{ // initializer
// The above prime numbers are formatted for human readability.
// To find numbers fast, we sort them once and for all.
Arrays.sort(PRIME_CAPACITIES);
}
/**
* Returns a prime number which is <code>&gt;= desiredCapacity</code> and very close to <code>desiredCapacity</code> (within 11% if <code>desiredCapacity &gt;= 1000</code>).
* @param desiredCapacity the capacity desired by the user.
* @return the capacity which should be used for a hashtable.
*/
public static int nextPrime(int desiredCapacity)
{
int i = Arrays.binarySearch(PRIME_CAPACITIES, desiredCapacity);
if (i < 0)
{
// desired capacity not found, choose next prime greater
// than desired capacity
i = -i - 1; // remember the semantics of binarySearch...
}
return PRIME_CAPACITIES[i];
}
}