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

Add move argument override to hasmap.it(). #558

Merged
merged 3 commits into from
Feb 5, 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
7 changes: 7 additions & 0 deletions include/bitcoin/database/impl/primitives/hashmap.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,13 @@ inline Link CLASS::first(const Key& key) const NOEXCEPT
return first(get_memory(), head_.top(key), key);
}

TEMPLATE
inline typename CLASS::iterator CLASS::it(Key&& key) const NOEXCEPT
{
const auto top = head_.top(key);
return { get_memory(), top, std::forward<Key>(key) };
}

TEMPLATE
inline typename CLASS::iterator CLASS::it(const Key& key) const NOEXCEPT
{
Expand Down
10 changes: 5 additions & 5 deletions include/bitcoin/database/impl/primitives/iterator.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,15 @@ namespace libbitcoin {
namespace database {

TEMPLATE
CLASS::iterator(const memory_ptr& data, const Link& start, Key&& key) NOEXCEPT
: memory_(data), key_(std::forward<Key>(key)), link_(to_match(start))
CLASS::iterator(memory_ptr&& data, const Link& start, Key&& key) NOEXCEPT
: memory_(std::move(data)), key_(std::forward<Key>(key)),
link_(to_match(start))
{
}

TEMPLATE
CLASS::iterator(const memory_ptr& data, const Link& start,
const Key& key) NOEXCEPT
: memory_(data), key_(key), link_(to_match(start))
CLASS::iterator(memory_ptr&& data, const Link& start, const Key& key) NOEXCEPT
: memory_(std::move(data)), key_(key), link_(to_match(start))
{
}

Expand Down
20 changes: 0 additions & 20 deletions include/bitcoin/database/impl/query/confirm.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -247,30 +247,10 @@ TEMPLATE
error::error_t CLASS::spent_prevout(const hash_digest& point_hash,
index point_index, const tx_link& self) const NOEXCEPT
{
////if (table::spend::null_point(point_hash))
//// return error::integrity6;
////
////if (table::spend::null_point(point_index))
//// return error::integrity7;

// TODO: pass comparitor to iterator construct to preclude composition copy.
auto it = store_.spend.it(table::spend::compose(point_hash, point_index));
if (!it)
{
if (self.is_terminal())
return error::success;

if (!it.get())
return error::integrity8;

if (it.self().is_terminal())
return error::integrity9;

if (!store_.spend.exists(it.key()))
return error::integrity10;

return error::integrity3;
}

// Get all txs that spend the point (non-terminal self must be a spender).
tx_links spenders{};
Expand Down
1 change: 1 addition & 0 deletions include/bitcoin/database/primitives/hashmap.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ class hashmap
inline Link first(const Key& key) const NOEXCEPT;

/// Iterator holds shared lock on storage remap.
inline iterator it(Key&& key) const NOEXCEPT;
inline iterator it(const Key& key) const NOEXCEPT;

/// Allocate count or slab size at returned link (follow with set|put).
Expand Down
7 changes: 5 additions & 2 deletions include/bitcoin/database/primitives/iterator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ namespace database {
/// THE hashmap.get(const iterator& it, ...) METHOD EXISTS TO PREVENT A CALL TO
/// manager.get(), WHICH DESPITE BEING A READ WOULD CAUSE A DEADLOCK. THIS IS
/// BECAUSE IT CANNOT COMPLETE ITS READ WHILE REMAP IS WAITING ON ACCESS.
/// A SIMILAR RISK ARISES FROM HOLDING iterator WHILE READING/WRITING ANY OTHER
/// TABLE AS A CYCLE CAUSING THE ABOVE WILL OCCUR. USE THE ITERATOR TO COLLECT
/// A SET FROM ITS TABLE AND THEN CALL iterator.release() TO FREE THE POINTER.

/// This class is not thread safe.
/// Size non-max implies record manager (ordinal record links).
Expand All @@ -44,8 +47,8 @@ class iterator
DEFAULT_COPY_MOVE_DESTRUCT(iterator);

/// This advances to first match (or terminal).
iterator(const memory_ptr& data, const Link& start, Key&& key) NOEXCEPT;
iterator(const memory_ptr& data, const Link& start, const Key& key) NOEXCEPT;
iterator(memory_ptr&& data, const Link& start, Key&& key) NOEXCEPT;
iterator(memory_ptr&& data, const Link& start, const Key& key) NOEXCEPT;

/// Advance to and return next iterator.
inline bool advance() NOEXCEPT;
Expand Down
19 changes: 18 additions & 1 deletion test/primitives/hashmap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -627,7 +627,7 @@ BOOST_AUTO_TEST_CASE(hashmap__slab_first__exists__true)
BOOST_REQUIRE(!instance.get_fault());
}

BOOST_AUTO_TEST_CASE(hashmap__record_it__exists__non_terminal)
BOOST_AUTO_TEST_CASE(hashmap__record_it__exists_copy__non_terminal)
{
test::chunk_storage head_store{};
test::chunk_storage body_store{};
Expand All @@ -644,6 +644,23 @@ BOOST_AUTO_TEST_CASE(hashmap__record_it__exists__non_terminal)
BOOST_REQUIRE(!instance.get_fault());
}

BOOST_AUTO_TEST_CASE(hashmap__record_it__exists_move__non_terminal)
{
test::chunk_storage head_store{};
test::chunk_storage body_store{};
hashmap<link5, key1, big_record::size, true> instance{ head_store, body_store, buckets };
BOOST_REQUIRE(instance.create());

constexpr key1 key{ 0x41 };
BOOST_REQUIRE(instance.it(key1{ 0x41 }).self().is_terminal());
BOOST_REQUIRE(!instance.put_link(key, big_record{ 0xa1b2c3d4_u32 }).is_terminal());
BOOST_REQUIRE(!instance.it(key1{ 0x41 }).self().is_terminal());

big_record record{};
BOOST_REQUIRE(instance.get(instance.it(key1{ 0x41 }).self(), record));
BOOST_REQUIRE(!instance.get_fault());
}

BOOST_AUTO_TEST_CASE(hashmap__record_it__multiple__iterated)
{
test::chunk_storage head_store{};
Expand Down
Loading