Skip to content

Commit

Permalink
Merge pull request #1582 from evoskuil/master
Browse files Browse the repository at this point in the history
Optimize populate by avoiding hash copies, normalize ref optimizations.
  • Loading branch information
evoskuil authored Jan 13, 2025
2 parents cd5ec49 + f8da59c commit f5d4c65
Show file tree
Hide file tree
Showing 14 changed files with 218 additions and 158 deletions.
12 changes: 1 addition & 11 deletions include/bitcoin/system/chain/block.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
#define LIBBITCOIN_SYSTEM_CHAIN_BLOCK_HPP

#include <memory>
#include <unordered_set>
#include <vector>
#include <bitcoin/system/chain/context.hpp>
#include <bitcoin/system/chain/header.hpp>
Expand Down Expand Up @@ -188,15 +187,6 @@ class BC_API block

private:
typedef struct { size_t nominal; size_t witnessed; } sizes;
using point_cref = std::reference_wrapper<const point>;
using point_hash = std::hash<std::reference_wrapper<const point>>;
using hash_cref = std::reference_wrapper<const hash_digest>;
using hash_hash = unique_hash_t<>;

using unordered_set_of_constant_referenced_points =
std::unordered_set<point_cref, point_hash>;
using unordered_set_of_constant_referenced_hashes =
std::unordered_set<hash_cref, hash_hash>;

void assign_data(reader& source, bool witness) NOEXCEPT;
static block from_data(reader& source, bool witness) NOEXCEPT;
Expand Down Expand Up @@ -243,7 +233,7 @@ struct hash<bc::system::chain::block>
{
size_t operator()(const bc::system::chain::block& value) const NOEXCEPT
{
return bc::system::unique_hash_t<>{}(value.hash());
return bc::system::unique_hash(value.hash());
}
};
} // namespace std
Expand Down
2 changes: 1 addition & 1 deletion include/bitcoin/system/chain/checkpoint.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ struct hash<bc::system::chain::checkpoint>
size_t operator()(const bc::system::chain::checkpoint& value) const NOEXCEPT
{
return bc::system::hash_combine(value.height(),
bc::system::unique_hash_t<>{}(value.hash()));
bc::system::unique_hash(value.hash()));
}
};
} // namespace std
Expand Down
2 changes: 1 addition & 1 deletion include/bitcoin/system/chain/header.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ struct hash<bc::system::chain::header>
{
size_t operator()(const bc::system::chain::header& value) const NOEXCEPT
{
return bc::system::unique_hash_t<>{}(value.hash());
return bc::system::unique_hash(value.hash());
}
};
} // namespace std
Expand Down
19 changes: 19 additions & 0 deletions include/bitcoin/system/chain/input.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,14 @@ typedef std_vector<input::cptr> input_cptrs;
typedef std::shared_ptr<input_cptrs> inputs_ptr;
typedef std::shared_ptr<const input_cptrs> inputs_cptr;

/// Constant reference optimizers.
struct cref_point { hash_cref hash; uint32_t index; };
using unordered_map_of_cref_point_to_output_cptr_cref =
std::unordered_map<cref_point, output_cptr_cref>;
BC_API bool operator<(const cref_point& left, const cref_point& right) NOEXCEPT;
BC_API bool operator==(const cref_point& left, const cref_point& right) NOEXCEPT;
BC_API bool operator!=(const cref_point& left, const cref_point& right) NOEXCEPT;

DECLARE_JSON_VALUE_CONVERTORS(input);
DECLARE_JSON_VALUE_CONVERTORS(input::cptr);

Expand All @@ -188,6 +196,17 @@ struct hash<bc::system::chain::input>
return std::hash<bc::system::data_chunk>{}(value.to_data());
}
};

template<>
struct hash<bc::system::chain::cref_point>
{
std::size_t operator()(
const bc::system::chain::cref_point& value) const NOEXCEPT
{
return bc::system::hash_combine(value.index,
bc::system::unique_hash(value.hash.get()));
}
};
} // namespace std

#endif
3 changes: 3 additions & 0 deletions include/bitcoin/system/chain/output.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@ typedef std_vector<output::cptr> output_cptrs;
typedef std::shared_ptr<output_cptrs> outputs_ptr;
typedef std::shared_ptr<const output_cptrs> outputs_cptr;

/// Constant reference optimizers.
using output_cptr_cref = std::reference_wrapper<const output::cptr>;

DECLARE_JSON_VALUE_CONVERTORS(output);
DECLARE_JSON_VALUE_CONVERTORS(output::cptr);

Expand Down
26 changes: 13 additions & 13 deletions include/bitcoin/system/chain/point.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#include <istream>
#include <memory>
#include <unordered_set>
#include <vector>
#include <bitcoin/system/data/data.hpp>
#include <bitcoin/system/define.hpp>
Expand Down Expand Up @@ -112,6 +113,13 @@ bool operator<(const point& left, const point& right) NOEXCEPT;

typedef std_vector<point> points;

/// Constant reference optimizers.
using point_cref = std::reference_wrapper<const point>;
using unordered_set_of_point_cref = std::unordered_set<point_cref>;
BC_API bool operator<(const point_cref& left, const point_cref& right) NOEXCEPT;
BC_API bool operator==(const point_cref& left, const point_cref& right) NOEXCEPT;
BC_API bool operator!=(const point_cref& left, const point_cref& right) NOEXCEPT;

DECLARE_JSON_VALUE_CONVERTORS(point);
DECLARE_JSON_VALUE_CONVERTORS(point::cptr);

Expand All @@ -127,27 +135,19 @@ struct hash<bc::system::chain::point>
size_t operator()(const bc::system::chain::point& value) const NOEXCEPT
{
return bc::system::hash_combine(value.index(),
bc::system::unique_hash_t<>{}(value.hash()));
bc::system::unique_hash(value.hash()));
}
};

template<>
struct hash<std::reference_wrapper<const bc::system::chain::point>>
struct hash<bc::system::chain::point_cref>
{
using wrapped = std::reference_wrapper<const bc::system::chain::point>;
std::size_t operator()(const wrapped& point) const NOEXCEPT
std::size_t operator()(
const bc::system::chain::point_cref& value) const NOEXCEPT
{
return std::hash<bc::system::chain::point>{}(point.get());
return std::hash<bc::system::chain::point>{}(value.get());
}
};

inline bool operator==(
const std::reference_wrapper<const bc::system::chain::point>& left,
const std::reference_wrapper<const bc::system::chain::point>& right) NOEXCEPT
{
return left.get() == right.get();
}

} // namespace std

#endif
9 changes: 1 addition & 8 deletions include/bitcoin/system/chain/transaction.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -300,16 +300,9 @@ struct hash<bc::system::chain::transaction>
size_t operator()(const bc::system::chain::transaction& value) const NOEXCEPT
{
// Witness coinbases will collide (null_hash).
return bc::system::unique_hash_t<>{}(value.hash(true));
return bc::system::unique_hash(value.hash(true));
}
};

inline bool operator==(
const std::reference_wrapper<const bc::system::hash_digest>& left,
const std::reference_wrapper<const bc::system::hash_digest>& right) NOEXCEPT
{
return left.get() == right.get();
}
} // namespace std

#endif
36 changes: 36 additions & 0 deletions include/bitcoin/system/hash/functions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#include <algorithm>
#include <memory>
#include <unordered_set>
#include <bitcoin/system/data/data.hpp>
#include <bitcoin/system/define.hpp>
#include <bitcoin/system/endian/endian.hpp>
Expand Down Expand Up @@ -156,9 +157,35 @@ INLINE constexpr size_t djb2_hash(const data_slice& data) NOEXCEPT;
/// Combine hash values, such as a pair of djb2_hash outputs [hash tables].
INLINE constexpr size_t hash_combine(size_t left, size_t right) NOEXCEPT;

/// Constant reference optimizers.
using hash_cref = std::reference_wrapper<const hash_digest>;
using unordered_set_of_hash_cref = std::unordered_set<hash_cref>;

} // namespace system
} // namespace libbitcoin

/// Comparison operators for constant reference optimizers.
namespace std
{
inline bool operator<(const bc::system::hash_cref& left,
const bc::system::hash_cref& right) NOEXCEPT
{
return left.get() < right.get();
}

inline bool operator==(const bc::system::hash_cref& left,
const bc::system::hash_cref& right) NOEXCEPT
{
return left.get() == right.get();
}

inline bool operator!=(const bc::system::hash_cref& left,
const bc::system::hash_cref& right) NOEXCEPT
{
return !(left == right);
}
} // namespace std

/// Extend std and boost namespaces with djb2_hash.
/// ---------------------------------------------------------------------------
/// This allows data_array/chunk to be incorporated into std/boost hash tables.
Expand All @@ -182,6 +209,15 @@ struct hash<bc::system::data_array<Size>>
return bc::system::djb2_hash(data);
}
};

template <>
struct hash<bc::system::hash_cref>
{
size_t operator()(const bc::system::hash_cref& hash) const NOEXCEPT
{
return bc::system::unique_hash(hash.get());
}
};
} // namespace std

namespace boost
Expand Down
Loading

0 comments on commit f5d4c65

Please sign in to comment.