Coverage Report

Created: 2025-06-10 13:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/bitcoin/src/util/fastrange.h
Line
Count
Source
1
// Copyright (c) 2018-2022 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
/* This file offers implementations of the fast range reduction technique described
11
 * in https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/
12
 *
13
 * In short, they take an integer x and a range n, and return the upper bits of
14
 * (x * n). If x is uniformly distributed over its domain, the result is as close to
15
 * uniformly distributed over [0, n) as (x mod n) would be, but significantly faster.
16
 */
17
18
/** Fast range reduction with 32-bit input and 32-bit range. */
19
static inline uint32_t FastRange32(uint32_t x, uint32_t n)
20
124M
{
21
124M
    return (uint64_t{x} * n) >> 32;
22
124M
}
Unexecuted instantiation: init.cpp:FastRange32(unsigned int, unsigned int)
Unexecuted instantiation: net_processing.cpp:FastRange32(unsigned int, unsigned int)
Unexecuted instantiation: blockmanager_args.cpp:FastRange32(unsigned int, unsigned int)
Unexecuted instantiation: blockstorage.cpp:FastRange32(unsigned int, unsigned int)
Unexecuted instantiation: chainstate.cpp:FastRange32(unsigned int, unsigned int)
Unexecuted instantiation: chainstatemanager_args.cpp:FastRange32(unsigned int, unsigned int)
Unexecuted instantiation: context.cpp:FastRange32(unsigned int, unsigned int)
Unexecuted instantiation: interfaces.cpp:FastRange32(unsigned int, unsigned int)
Unexecuted instantiation: mempool_persist.cpp:FastRange32(unsigned int, unsigned int)
Unexecuted instantiation: mempool_persist_args.cpp:FastRange32(unsigned int, unsigned int)
Unexecuted instantiation: miner.cpp:FastRange32(unsigned int, unsigned int)
Unexecuted instantiation: transaction.cpp:FastRange32(unsigned int, unsigned int)
Unexecuted instantiation: txdownloadman_impl.cpp:FastRange32(unsigned int, unsigned int)
Unexecuted instantiation: rest.cpp:FastRange32(unsigned int, unsigned int)
Unexecuted instantiation: blockchain.cpp:FastRange32(unsigned int, unsigned int)
Unexecuted instantiation: mempool.cpp:FastRange32(unsigned int, unsigned int)
Unexecuted instantiation: mining.cpp:FastRange32(unsigned int, unsigned int)
Unexecuted instantiation: net.cpp:FastRange32(unsigned int, unsigned int)
Unexecuted instantiation: rawtransaction.cpp:FastRange32(unsigned int, unsigned int)
Unexecuted instantiation: server.cpp:FastRange32(unsigned int, unsigned int)
Unexecuted instantiation: server_util.cpp:FastRange32(unsigned int, unsigned int)
Unexecuted instantiation: txoutproof.cpp:FastRange32(unsigned int, unsigned int)
validation.cpp:FastRange32(unsigned int, unsigned int)
Line
Count
Source
20
1.25M
{
21
1.25M
    return (uint64_t{x} * n) >> 32;
22
1.25M
}
Unexecuted instantiation: blockencodings.cpp:FastRange32(unsigned int, unsigned int)
Unexecuted instantiation: blockfilter.cpp:FastRange32(unsigned int, unsigned int)
Unexecuted instantiation: base.cpp:FastRange32(unsigned int, unsigned int)
Unexecuted instantiation: blockfilterindex.cpp:FastRange32(unsigned int, unsigned int)
Unexecuted instantiation: coinstatsindex.cpp:FastRange32(unsigned int, unsigned int)
Unexecuted instantiation: txindex.cpp:FastRange32(unsigned int, unsigned int)
Unexecuted instantiation: coinstats.cpp:FastRange32(unsigned int, unsigned int)
Unexecuted instantiation: coin.cpp:FastRange32(unsigned int, unsigned int)
Unexecuted instantiation: utxo_snapshot.cpp:FastRange32(unsigned int, unsigned int)
Unexecuted instantiation: sigcache.cpp:FastRange32(unsigned int, unsigned int)
Unexecuted instantiation: transactions.cpp:FastRange32(unsigned int, unsigned int)
bloom.cpp:FastRange32(unsigned int, unsigned int)
Line
Count
Source
20
123M
{
21
123M
    return (uint64_t{x} * n) >> 32;
22
123M
}
23
24
/** Fast range reduction with 64-bit input and 64-bit range. */
25
static inline uint64_t FastRange64(uint64_t x, uint64_t n)
26
2.23M
{
27
2.23M
#ifdef __SIZEOF_INT128__
28
2.23M
    return (static_cast<unsigned __int128>(x) * static_cast<unsigned __int128>(n)) >> 64;
29
#else
30
    // To perform the calculation on 64-bit numbers without losing the
31
    // result to overflow, split the numbers into the most significant and
32
    // least significant 32 bits and perform multiplication piece-wise.
33
    //
34
    // See: https://stackoverflow.com/a/26855440
35
    const uint64_t x_hi = x >> 32;
36
    const uint64_t x_lo = x & 0xFFFFFFFF;
37
    const uint64_t n_hi = n >> 32;
38
    const uint64_t n_lo = n & 0xFFFFFFFF;
39
40
    const uint64_t ac = x_hi * n_hi;
41
    const uint64_t ad = x_hi * n_lo;
42
    const uint64_t bc = x_lo * n_hi;
43
    const uint64_t bd = x_lo * n_lo;
44
45
    const uint64_t mid34 = (bd >> 32) + (bc & 0xFFFFFFFF) + (ad & 0xFFFFFFFF);
46
    const uint64_t upper64 = ac + (bc >> 32) + (ad >> 32) + (mid34 >> 32);
47
    return upper64;
48
#endif
49
2.23M
}
Unexecuted instantiation: init.cpp:FastRange64(unsigned long, unsigned long)
Unexecuted instantiation: net_processing.cpp:FastRange64(unsigned long, unsigned long)
Unexecuted instantiation: blockmanager_args.cpp:FastRange64(unsigned long, unsigned long)
Unexecuted instantiation: blockstorage.cpp:FastRange64(unsigned long, unsigned long)
Unexecuted instantiation: chainstate.cpp:FastRange64(unsigned long, unsigned long)
Unexecuted instantiation: chainstatemanager_args.cpp:FastRange64(unsigned long, unsigned long)
Unexecuted instantiation: context.cpp:FastRange64(unsigned long, unsigned long)
Unexecuted instantiation: interfaces.cpp:FastRange64(unsigned long, unsigned long)
Unexecuted instantiation: mempool_persist.cpp:FastRange64(unsigned long, unsigned long)
Unexecuted instantiation: mempool_persist_args.cpp:FastRange64(unsigned long, unsigned long)
Unexecuted instantiation: miner.cpp:FastRange64(unsigned long, unsigned long)
Unexecuted instantiation: transaction.cpp:FastRange64(unsigned long, unsigned long)
Unexecuted instantiation: txdownloadman_impl.cpp:FastRange64(unsigned long, unsigned long)
Unexecuted instantiation: rest.cpp:FastRange64(unsigned long, unsigned long)
Unexecuted instantiation: blockchain.cpp:FastRange64(unsigned long, unsigned long)
Unexecuted instantiation: mempool.cpp:FastRange64(unsigned long, unsigned long)
Unexecuted instantiation: mining.cpp:FastRange64(unsigned long, unsigned long)
Unexecuted instantiation: net.cpp:FastRange64(unsigned long, unsigned long)
Unexecuted instantiation: rawtransaction.cpp:FastRange64(unsigned long, unsigned long)
Unexecuted instantiation: server.cpp:FastRange64(unsigned long, unsigned long)
Unexecuted instantiation: server_util.cpp:FastRange64(unsigned long, unsigned long)
Unexecuted instantiation: txoutproof.cpp:FastRange64(unsigned long, unsigned long)
Unexecuted instantiation: validation.cpp:FastRange64(unsigned long, unsigned long)
Unexecuted instantiation: blockencodings.cpp:FastRange64(unsigned long, unsigned long)
blockfilter.cpp:FastRange64(unsigned long, unsigned long)
Line
Count
Source
26
2.23M
{
27
2.23M
#ifdef __SIZEOF_INT128__
28
2.23M
    return (static_cast<unsigned __int128>(x) * static_cast<unsigned __int128>(n)) >> 64;
29
#else
30
    // To perform the calculation on 64-bit numbers without losing the
31
    // result to overflow, split the numbers into the most significant and
32
    // least significant 32 bits and perform multiplication piece-wise.
33
    //
34
    // See: https://stackoverflow.com/a/26855440
35
    const uint64_t x_hi = x >> 32;
36
    const uint64_t x_lo = x & 0xFFFFFFFF;
37
    const uint64_t n_hi = n >> 32;
38
    const uint64_t n_lo = n & 0xFFFFFFFF;
39
40
    const uint64_t ac = x_hi * n_hi;
41
    const uint64_t ad = x_hi * n_lo;
42
    const uint64_t bc = x_lo * n_hi;
43
    const uint64_t bd = x_lo * n_lo;
44
45
    const uint64_t mid34 = (bd >> 32) + (bc & 0xFFFFFFFF) + (ad & 0xFFFFFFFF);
46
    const uint64_t upper64 = ac + (bc >> 32) + (ad >> 32) + (mid34 >> 32);
47
    return upper64;
48
#endif
49
2.23M
}
Unexecuted instantiation: base.cpp:FastRange64(unsigned long, unsigned long)
Unexecuted instantiation: blockfilterindex.cpp:FastRange64(unsigned long, unsigned long)
Unexecuted instantiation: coinstatsindex.cpp:FastRange64(unsigned long, unsigned long)
Unexecuted instantiation: txindex.cpp:FastRange64(unsigned long, unsigned long)
Unexecuted instantiation: coinstats.cpp:FastRange64(unsigned long, unsigned long)
Unexecuted instantiation: coin.cpp:FastRange64(unsigned long, unsigned long)
Unexecuted instantiation: utxo_snapshot.cpp:FastRange64(unsigned long, unsigned long)
Unexecuted instantiation: sigcache.cpp:FastRange64(unsigned long, unsigned long)
Unexecuted instantiation: transactions.cpp:FastRange64(unsigned long, unsigned long)
Unexecuted instantiation: bloom.cpp:FastRange64(unsigned long, unsigned long)
50
51
#endif // BITCOIN_UTIL_FASTRANGE_H