Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize populate by avoiding hash copies, normalize ref optimizations. #1582

Merged
merged 4 commits into from
Jan 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading