blob: dd4e8e3e1acf70b079a2a9338336ecce0af6b253 [file] [log] [blame]
Howard Hinnantc51e1022010-05-11 19:42:16 +00001//===-------------------------- hash.cpp ----------------------------------===//
2//
Howard Hinnantc566dc32010-05-11 21:36:01 +00003// The LLVM Compiler Infrastructure
Howard Hinnantc51e1022010-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 Hinnantffb308e2010-08-22 00:03:27 +0000129//
Howard Hinnantc51e1022010-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 Hinnantffb308e2010-08-22 00:03:27 +0000136//
Howard Hinnantc51e1022010-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 Hinnant7bf565c2010-09-13 01:43:27 +0000160 size_t in = std::lower_bound(indices, indices + M, n - k0 * L) - indices;
Howard Hinnantc51e1022010-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 Hinnant7bf565c2010-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 Hinnantc51e1022010-05-11 19:42:16 +0000176 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000177 if (n == q * p)
178 goto next;
Howard Hinnantc51e1022010-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 Hinnant7bf565c2010-09-13 01:43:27 +0000185 std::size_t q = n / i;
186 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000187 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000188 if (n == q * i)
189 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000190
191 i += 10;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000192 q = n / i;
193 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000194 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000195 if (n == q * i)
196 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000197
198 i += 2;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000199 q = n / i;
200 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000201 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000202 if (n == q * i)
203 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000204
205 i += 4;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000206 q = n / i;
207 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000208 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000209 if (n == q * i)
210 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000211
212 i += 2;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000213 q = n / i;
214 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000215 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000216 if (n == q * i)
217 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000218
219 i += 4;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000220 q = n / i;
221 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000222 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000223 if (n == q * i)
224 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000225
226 i += 6;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000227 q = n / i;
228 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000229 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000230 if (n == q * i)
231 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000232
233 i += 2;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000234 q = n / i;
235 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000236 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000237 if (n == q * i)
238 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000239
240 i += 6;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000241 q = n / i;
242 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000243 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000244 if (n == q * i)
245 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000246
247 i += 4;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000248 q = n / i;
249 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000250 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000251 if (n == q * i)
252 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000253
254 i += 2;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000255 q = n / i;
256 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000257 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000258 if (n == q * i)
259 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000260
261 i += 4;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000262 q = n / i;
263 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000264 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000265 if (n == q * i)
266 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000267
268 i += 6;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000269 q = n / i;
270 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000271 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000272 if (n == q * i)
273 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000274
275 i += 6;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000276 q = n / i;
277 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000278 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000279 if (n == q * i)
280 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000281
282 i += 2;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000283 q = n / i;
284 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000285 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000286 if (n == q * i)
287 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000288
289 i += 6;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000290 q = n / i;
291 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000292 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000293 if (n == q * i)
294 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000295
296 i += 4;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000297 q = n / i;
298 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000299 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000300 if (n == q * i)
301 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000302
303 i += 2;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000304 q = n / i;
305 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000306 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000307 if (n == q * i)
308 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000309
310 i += 6;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000311 q = n / i;
312 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000313 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000314 if (n == q * i)
315 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000316
317 i += 4;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000318 q = n / i;
319 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000320 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000321 if (n == q * i)
322 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000323
324 i += 6;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000325 q = n / i;
326 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000327 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000328 if (n == q * i)
329 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000330
331 i += 8;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000332 q = n / i;
333 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000334 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000335 if (n == q * i)
336 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000337
338 i += 4;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000339 q = n / i;
340 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000341 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000342 if (n == q * i)
343 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000344
345 i += 2;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000346 q = n / i;
347 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000348 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000349 if (n == q * i)
350 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000351
352 i += 4;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000353 q = n / i;
354 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000355 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000356 if (n == q * i)
357 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000358
359 i += 2;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000360 q = n / i;
361 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000362 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000363 if (n == q * i)
364 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000365
366 i += 4;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000367 q = n / i;
368 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000369 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000370 if (n == q * i)
371 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000372
373 i += 8;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000374 q = n / i;
375 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000376 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000377 if (n == q * i)
378 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000379
380 i += 6;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000381 q = n / i;
382 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000383 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000384 if (n == q * i)
385 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000386
387 i += 4;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000388 q = n / i;
389 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000390 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000391 if (n == q * i)
392 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000393
394 i += 6;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000395 q = n / i;
396 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000397 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000398 if (n == q * i)
399 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000400
401 i += 2;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000402 q = n / i;
403 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000404 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000405 if (n == q * i)
406 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000407
408 i += 4;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000409 q = n / i;
410 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000411 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000412 if (n == q * i)
413 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000414
415 i += 6;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000416 q = n / i;
417 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000418 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000419 if (n == q * i)
420 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000421
422 i += 2;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000423 q = n / i;
424 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000425 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000426 if (n == q * i)
427 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000428
429 i += 6;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000430 q = n / i;
431 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000432 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000433 if (n == q * i)
434 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000435
436 i += 6;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000437 q = n / i;
438 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000439 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000440 if (n == q * i)
441 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000442
443 i += 4;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000444 q = n / i;
445 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000446 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000447 if (n == q * i)
448 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000449
450 i += 2;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000451 q = n / i;
452 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000453 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000454 if (n == q * i)
455 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000456
457 i += 4;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000458 q = n / i;
459 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000460 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000461 if (n == q * i)
462 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000463
464 i += 6;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000465 q = n / i;
466 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000467 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000468 if (n == q * i)
469 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000470
471 i += 2;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000472 q = n / i;
473 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000474 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000475 if (n == q * i)
476 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000477
478 i += 6;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000479 q = n / i;
480 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000481 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000482 if (n == q * i)
483 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000484
485 i += 4;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000486 q = n / i;
487 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000488 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000489 if (n == q * i)
490 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000491
492 i += 2;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000493 q = n / i;
494 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000495 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000496 if (n == q * i)
497 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000498
499 i += 4;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000500 q = n / i;
501 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000502 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000503 if (n == q * i)
504 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000505
506 i += 2;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000507 q = n / i;
508 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000509 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000510 if (n == q * i)
511 break;
Howard Hinnantc51e1022010-05-11 19:42:16 +0000512
513 i += 10;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000514 q = n / i;
515 if (q < i)
Howard Hinnantc51e1022010-05-11 19:42:16 +0000516 return n;
Howard Hinnant7bf565c2010-09-13 01:43:27 +0000517 if (n == q * i)
518 break;
Howard Hinnantc51e1022010-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