blob: dd4e8e3e1acf70b079a2a9338336ecce0af6b253 [file] [log] [blame]
Howard Hinnant3e519522010-05-11 19:42:16 +00001//===-------------------------- hash.cpp ----------------------------------===//
2//
Howard Hinnant5b08a8a2010-05-11 21:36:01 +00003// The LLVM Compiler Infrastructure
Howard Hinnant3e519522010-05-11 19:42:16 +00004//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "__hash_table"
11#include "algorithm"
12
13_LIBCPP_BEGIN_NAMESPACE_STD
14
15namespace {
16
17// handle all next_prime(i) for i in [1, 210), special case 0
18const unsigned small_primes[] =
19{
20 0,
21 2,
22 3,
23 5,
24 7,
25 11,
26 13,
27 17,
28 19,
29 23,
30 29,
31 31,
32 37,
33 41,
34 43,
35 47,
36 53,
37 59,
38 61,
39 67,
40 71,
41 73,
42 79,
43 83,
44 89,
45 97,
46 101,
47 103,
48 107,
49 109,
50 113,
51 127,
52 131,
53 137,
54 139,
55 149,
56 151,
57 157,
58 163,
59 167,
60 173,
61 179,
62 181,
63 191,
64 193,
65 197,
66 199,
67 211
68};
69
70// potential primes = 210*k + indices[i], k >= 1
71// these numbers are not divisible by 2, 3, 5 or 7
72// (or any integer 2 <= j <= 10 for that matter).
73const unsigned indices[] =
74{
75 1,
76 11,
77 13,
78 17,
79 19,
80 23,
81 29,
82 31,
83 37,
84 41,
85 43,
86 47,
87 53,
88 59,
89 61,
90 67,
91 71,
92 73,
93 79,
94 83,
95 89,
96 97,
97 101,
98 103,
99 107,
100 109,
101 113,
102 121,
103 127,
104 131,
105 137,
106 139,
107 143,
108 149,
109 151,
110 157,
111 163,
112 167,
113 169,
114 173,
115 179,
116 181,
117 187,
118 191,
119 193,
120 197,
121 199,
122 209
123};
124
125}
126
127// Returns: If n == 0, returns 0. Else returns the lowest prime number that
128// is greater than or equal to n.
Howard Hinnant940e2112010-08-22 00:03:27 +0000129//
Howard Hinnant3e519522010-05-11 19:42:16 +0000130// The algorithm creates a list of small primes, plus an open-ended list of
131// potential primes. All prime numbers are potential prime numbers. However
132// some potential prime numbers are not prime. In an ideal world, all potential
133// prime numbers would be prime. Candiate prime numbers are chosen as the next
134// highest potential prime. Then this number is tested for prime by dividing it
135// by all potential prime numbers less than the sqrt of the candidate.
Howard Hinnant940e2112010-08-22 00:03:27 +0000136//
Howard Hinnant3e519522010-05-11 19:42:16 +0000137// This implementation defines potential primes as those numbers not divisible
138// by 2, 3, 5, and 7. Other (common) implementations define potential primes
139// as those not divisible by 2. A few other implementations define potential
140// primes as those not divisible by 2 or 3. By raising the number of small
141// primes which the potential prime is not divisible by, the set of potential
142// primes more closely approximates the set of prime numbers. And thus there
143// are fewer potential primes to search, and fewer potential primes to divide
144// against.
145
146size_t
147__next_prime(size_t n)
148{
149 const size_t L = 210;
150 const size_t N = sizeof(small_primes) / sizeof(small_primes[0]);
151 // If n is small enough, search in small_primes
152 if (n <= small_primes[N-1])
153 return *std::lower_bound(small_primes, small_primes + N, n);
154 // Else n > largest small_primes
155 // Start searching list of potential primes: L * k0 + indices[in]
156 const size_t M = sizeof(indices) / sizeof(indices[0]);
157 // Select first potential prime >= n
158 // Known a-priori n >= L
159 size_t k0 = n / L;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000160 size_t in = std::lower_bound(indices, indices + M, n - k0 * L) - indices;
Howard Hinnant3e519522010-05-11 19:42:16 +0000161 n = L * k0 + indices[in];
162 while (true)
163 {
164 // Divide n by all primes or potential primes (i) until:
165 // 1. The division is even, so try next potential prime.
166 // 2. The i > sqrt(n), in which case n is prime.
167 // It is known a-priori that n is not divisible by 2, 3, 5 or 7,
168 // so don't test those (j == 5 -> divide by 11 first). And the
169 // potential primes start with 211, so don't test against the last
170 // small prime.
171 for (size_t j = 5; j < N - 1; ++j)
172 {
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000173 const std::size_t p = small_primes[j];
174 const std::size_t q = n / p;
175 if (q < p)
Howard Hinnant3e519522010-05-11 19:42:16 +0000176 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000177 if (n == q * p)
178 goto next;
Howard Hinnant3e519522010-05-11 19:42:16 +0000179 }
180 // n wasn't divisible by small primes, try potential primes
181 {
182 size_t i = 211;
183 while (true)
184 {
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000185 std::size_t q = n / i;
186 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000187 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000188 if (n == q * i)
189 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000190
191 i += 10;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000192 q = n / i;
193 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000194 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000195 if (n == q * i)
196 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000197
198 i += 2;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000199 q = n / i;
200 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000201 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000202 if (n == q * i)
203 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000204
205 i += 4;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000206 q = n / i;
207 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000208 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000209 if (n == q * i)
210 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000211
212 i += 2;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000213 q = n / i;
214 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000215 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000216 if (n == q * i)
217 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000218
219 i += 4;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000220 q = n / i;
221 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000222 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000223 if (n == q * i)
224 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000225
226 i += 6;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000227 q = n / i;
228 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000229 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000230 if (n == q * i)
231 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000232
233 i += 2;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000234 q = n / i;
235 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000236 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000237 if (n == q * i)
238 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000239
240 i += 6;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000241 q = n / i;
242 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000243 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000244 if (n == q * i)
245 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000246
247 i += 4;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000248 q = n / i;
249 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000250 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000251 if (n == q * i)
252 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000253
254 i += 2;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000255 q = n / i;
256 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000257 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000258 if (n == q * i)
259 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000260
261 i += 4;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000262 q = n / i;
263 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000264 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000265 if (n == q * i)
266 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000267
268 i += 6;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000269 q = n / i;
270 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000271 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000272 if (n == q * i)
273 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000274
275 i += 6;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000276 q = n / i;
277 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000278 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000279 if (n == q * i)
280 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000281
282 i += 2;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000283 q = n / i;
284 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000285 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000286 if (n == q * i)
287 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000288
289 i += 6;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000290 q = n / i;
291 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000292 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000293 if (n == q * i)
294 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000295
296 i += 4;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000297 q = n / i;
298 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000299 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000300 if (n == q * i)
301 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000302
303 i += 2;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000304 q = n / i;
305 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000306 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000307 if (n == q * i)
308 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000309
310 i += 6;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000311 q = n / i;
312 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000313 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000314 if (n == q * i)
315 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000316
317 i += 4;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000318 q = n / i;
319 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000320 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000321 if (n == q * i)
322 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000323
324 i += 6;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000325 q = n / i;
326 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000327 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000328 if (n == q * i)
329 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000330
331 i += 8;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000332 q = n / i;
333 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000334 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000335 if (n == q * i)
336 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000337
338 i += 4;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000339 q = n / i;
340 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000341 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000342 if (n == q * i)
343 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000344
345 i += 2;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000346 q = n / i;
347 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000348 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000349 if (n == q * i)
350 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000351
352 i += 4;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000353 q = n / i;
354 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000355 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000356 if (n == q * i)
357 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000358
359 i += 2;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000360 q = n / i;
361 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000362 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000363 if (n == q * i)
364 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000365
366 i += 4;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000367 q = n / i;
368 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000369 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000370 if (n == q * i)
371 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000372
373 i += 8;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000374 q = n / i;
375 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000376 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000377 if (n == q * i)
378 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000379
380 i += 6;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000381 q = n / i;
382 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000383 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000384 if (n == q * i)
385 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000386
387 i += 4;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000388 q = n / i;
389 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000390 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000391 if (n == q * i)
392 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000393
394 i += 6;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000395 q = n / i;
396 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000397 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000398 if (n == q * i)
399 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000400
401 i += 2;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000402 q = n / i;
403 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000404 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000405 if (n == q * i)
406 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000407
408 i += 4;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000409 q = n / i;
410 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000411 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000412 if (n == q * i)
413 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000414
415 i += 6;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000416 q = n / i;
417 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000418 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000419 if (n == q * i)
420 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000421
422 i += 2;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000423 q = n / i;
424 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000425 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000426 if (n == q * i)
427 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000428
429 i += 6;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000430 q = n / i;
431 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000432 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000433 if (n == q * i)
434 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000435
436 i += 6;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000437 q = n / i;
438 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000439 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000440 if (n == q * i)
441 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000442
443 i += 4;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000444 q = n / i;
445 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000446 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000447 if (n == q * i)
448 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000449
450 i += 2;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000451 q = n / i;
452 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000453 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000454 if (n == q * i)
455 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000456
457 i += 4;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000458 q = n / i;
459 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000460 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000461 if (n == q * i)
462 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000463
464 i += 6;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000465 q = n / i;
466 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000467 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000468 if (n == q * i)
469 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000470
471 i += 2;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000472 q = n / i;
473 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000474 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000475 if (n == q * i)
476 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000477
478 i += 6;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000479 q = n / i;
480 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000481 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000482 if (n == q * i)
483 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000484
485 i += 4;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000486 q = n / i;
487 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000488 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000489 if (n == q * i)
490 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000491
492 i += 2;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000493 q = n / i;
494 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000495 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000496 if (n == q * i)
497 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000498
499 i += 4;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000500 q = n / i;
501 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000502 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000503 if (n == q * i)
504 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000505
506 i += 2;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000507 q = n / i;
508 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000509 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000510 if (n == q * i)
511 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000512
513 i += 10;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000514 q = n / i;
515 if (q < i)
Howard Hinnant3e519522010-05-11 19:42:16 +0000516 return n;
Howard Hinnant8fb62e32010-09-13 01:43:27 +0000517 if (n == q * i)
518 break;
Howard Hinnant3e519522010-05-11 19:42:16 +0000519
520 // This will loop i to the next "plane" of potential primes
521 i += 2;
522 }
523 }
524next:
525 // n is not prime. Increment n to next potential prime.
526 if (++in == M)
527 {
528 ++k0;
529 in = 0;
530 }
531 n = L * k0 + indices[in];
532 }
533}
534
535_LIBCPP_END_NAMESPACE_STD