Skip to content

Commit c6d15c4

Browse files
committed
[moveonly] Move MapIntoRange() to separate util/fastrange.h
1 parent e941507 commit c6d15c4

File tree

3 files changed

+44
-31
lines changed

3 files changed

+44
-31
lines changed

src/Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ BITCOIN_CORE_H = \
240240
util/check.h \
241241
util/epochguard.h \
242242
util/error.h \
243+
util/fastrange.h \
243244
util/fees.h \
244245
util/getuniquepath.h \
245246
util/golombrice.h \

src/util/fastrange.h

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Copyright (c) 2018-2020 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#ifndef BITCOIN_UTIL_FASTRANGE_H
6+
#define BITCOIN_UTIL_FASTRANGE_H
7+
8+
#include <cstdint>
9+
10+
// Map a value x that is uniformly distributed in the range [0, 2^64) to a
11+
// value uniformly distributed in [0, n) by returning the upper 64 bits of
12+
// x * n.
13+
//
14+
// See: https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/
15+
static inline uint64_t MapIntoRange(uint64_t x, uint64_t n)
16+
{
17+
#ifdef __SIZEOF_INT128__
18+
return (static_cast<unsigned __int128>(x) * static_cast<unsigned __int128>(n)) >> 64;
19+
#else
20+
// To perform the calculation on 64-bit numbers without losing the
21+
// result to overflow, split the numbers into the most significant and
22+
// least significant 32 bits and perform multiplication piece-wise.
23+
//
24+
// See: https://stackoverflow.com/a/26855440
25+
const uint64_t x_hi = x >> 32;
26+
const uint64_t x_lo = x & 0xFFFFFFFF;
27+
const uint64_t n_hi = n >> 32;
28+
const uint64_t n_lo = n & 0xFFFFFFFF;
29+
30+
const uint64_t ac = x_hi * n_hi;
31+
const uint64_t ad = x_hi * n_lo;
32+
const uint64_t bc = x_lo * n_hi;
33+
const uint64_t bd = x_lo * n_lo;
34+
35+
const uint64_t mid34 = (bd >> 32) + (bc & 0xFFFFFFFF) + (ad & 0xFFFFFFFF);
36+
const uint64_t upper64 = ac + (bc >> 32) + (ad >> 32) + (mid34 >> 32);
37+
return upper64;
38+
#endif
39+
}
40+
41+
#endif // BITCOIN_UTIL_FASTRANGE_H

src/util/golombrice.h

Lines changed: 2 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
#ifndef BITCOIN_UTIL_GOLOMBRICE_H
66
#define BITCOIN_UTIL_GOLOMBRICE_H
77

8+
#include <util/fastrange.h>
9+
810
#include <streams.h>
911

1012
#include <cstdint>
@@ -40,35 +42,4 @@ uint64_t GolombRiceDecode(BitStreamReader<IStream>& bitreader, uint8_t P)
4042
return (q << P) + r;
4143
}
4244

43-
// Map a value x that is uniformly distributed in the range [0, 2^64) to a
44-
// value uniformly distributed in [0, n) by returning the upper 64 bits of
45-
// x * n.
46-
//
47-
// See: https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/
48-
static inline uint64_t MapIntoRange(uint64_t x, uint64_t n)
49-
{
50-
#ifdef __SIZEOF_INT128__
51-
return (static_cast<unsigned __int128>(x) * static_cast<unsigned __int128>(n)) >> 64;
52-
#else
53-
// To perform the calculation on 64-bit numbers without losing the
54-
// result to overflow, split the numbers into the most significant and
55-
// least significant 32 bits and perform multiplication piece-wise.
56-
//
57-
// See: https://stackoverflow.com/a/26855440
58-
const uint64_t x_hi = x >> 32;
59-
const uint64_t x_lo = x & 0xFFFFFFFF;
60-
const uint64_t n_hi = n >> 32;
61-
const uint64_t n_lo = n & 0xFFFFFFFF;
62-
63-
const uint64_t ac = x_hi * n_hi;
64-
const uint64_t ad = x_hi * n_lo;
65-
const uint64_t bc = x_lo * n_hi;
66-
const uint64_t bd = x_lo * n_lo;
67-
68-
const uint64_t mid34 = (bd >> 32) + (bc & 0xFFFFFFFF) + (ad & 0xFFFFFFFF);
69-
const uint64_t upper64 = ac + (bc >> 32) + (ad >> 32) + (mid34 >> 32);
70-
return upper64;
71-
#endif
72-
}
73-
7445
#endif // BITCOIN_UTIL_GOLOMBRICE_H

0 commit comments

Comments
 (0)