Skip to content

Add method transaction::has_key() #241

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

Closed
wants to merge 1 commit into from
Closed
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
1 change: 1 addition & 0 deletions include/wsrep/sr_key_set.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ namespace wsrep
: root_()
{ }
void insert(const wsrep::key& key);
bool contains(const wsrep::key& key) const;
const branch_type& root() const { return root_; }
void clear();
bool empty() const { return root_.empty(); }
Expand Down
2 changes: 2 additions & 0 deletions include/wsrep/transaction.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,8 @@ namespace wsrep

int append_key(const wsrep::key&);

bool has_key(const wsrep::key&) const;

int append_data(const wsrep::const_buffer&);

int after_row();
Expand Down
20 changes: 20 additions & 0 deletions src/sr_key_set.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,26 @@ void wsrep::sr_key_set::insert(const wsrep::key& key)
key.key_parts()[1].size()));
}

bool wsrep::sr_key_set::contains(const wsrep::key& key) const
{
assert(key.size() >= 2);
if (key.size() < 2)
{
throw wsrep::runtime_error("Invalid key size");
}

std::string key_part_1(static_cast<const char*>(key.key_parts()[0].data()),
key.key_parts()[0].size());
std::string key_part_2(static_cast<const char*>(key.key_parts()[1].data()),
key.key_parts()[1].size());

auto it(root_.find(key_part_1));
if (it == root_.end())
return false;
leaf_type leafs(it->second);
return (leafs.find(key_part_2) != leafs.end());
}

void wsrep::sr_key_set::clear()
{
root_.clear();
Expand Down
6 changes: 6 additions & 0 deletions src/transaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,12 @@ int wsrep::transaction::append_key(const wsrep::key& key)
}
}

bool wsrep::transaction::has_key(const wsrep::key& key) const
{
assert(active());
return sr_keys_.contains(key);
}

int wsrep::transaction::append_data(const wsrep::const_buffer& data)
{
assert(active());
Expand Down
1 change: 1 addition & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ set(TEST_SOURCES
nbo_test.cpp
rsu_test.cpp
server_context_test.cpp
sr_key_set_test.cpp
toi_test.cpp
transaction_test.cpp
transaction_test_2pc.cpp
Expand Down
73 changes: 73 additions & 0 deletions test/sr_key_set_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* Copyright (C) 2024 Codership Oy <[email protected]>
*
* This file is part of wsrep-lib.
*
* Wsrep-lib is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Wsrep-lib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with wsrep-lib. If not, see <https://www.gnu.org/licenses/>.
*/

#include "wsrep/key.hpp"
#include "wsrep/sr_key_set.hpp"
#include <boost/test/unit_test.hpp>

static void append_key_parts(wsrep::key& key,
const std::vector<std::string>& parts)
{
for (const std::string& part : parts)
{
key.append_key_part(part.c_str(), part.length());
}
}

BOOST_AUTO_TEST_CASE(sr_key_set_test_contains)
{
wsrep::sr_key_set key_set;

{ // contains same key
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be better to have separate test cases named according to what they test than having multiple blocks inside single test case. If the test fails, it it much easier to see immediately what was the testcase which failed.

If there is some common setup step for all the tests, it can be put into test fixture.

wsrep::key key(wsrep::key::exclusive);
std::vector<std::string> parts = { "1", "2" };
append_key_parts(key, parts);
BOOST_REQUIRE(!key_set.contains(key));
key_set.insert(key);
BOOST_REQUIRE(key_set.contains(key));
}

{ // contains same key with different type
wsrep::key key(wsrep::key::shared);
std::vector<std::string> parts = { "1", "2" };
append_key_parts(key, parts);
BOOST_REQUIRE(key_set.contains(key));
}

{ // contains same key with one more level
wsrep::key key(wsrep::key::shared);
std::vector<std::string> parts = { "1", "2", "3" };
append_key_parts(key, parts);
BOOST_REQUIRE(key_set.contains(key));
}

{ // does not contain different key first at first level
wsrep::key key(wsrep::key::shared);
std::vector<std::string> parts = { "different", "2" };
append_key_parts(key, parts);
BOOST_REQUIRE(!key_set.contains(key));
}

{ // does not contain different key part at second level
wsrep::key key(wsrep::key::shared);
std::vector<std::string> parts = { "1", "different" };
append_key_parts(key, parts);
BOOST_REQUIRE(!key_set.contains(key));
}
}
Loading