Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
18 changes: 18 additions & 0 deletions hazelcast/include/hazelcast/client/query/predicates.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,15 @@ namespace hazelcast {
out_stream.write<int32_t>(static_cast<int32_t>(sizeof...(values)));
out_stream.write_objects(values...);
}

template<typename T>
multi_predicate(const std::string attribute_name, hazelcast_client &client, const std::vector<T> &values) : base_predicate(client) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Why is the hazelcast_client needed to create a predicate? IMO it would be great to get rid of it if possible.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

unfortunately, we need it to access the serialization service. I also do not like it but i had to do it due to the fact that i needed to prepare the binary during construction.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I see. I wish we could defer binary construction. Taking a client as a parameter has more problems, like would passing a different to multi_predicate than the one calling the actual query cause problems? But I guess this is not something that can be changed in this PR.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Passing a different client, yes, that may cause a problem if serialization configs are different. Alternative was to use the client as the factory method to create the in_predicate but it again has the same problem if the user would use a client predicate with the other client. I am open to any better solution but could not find one as of yet. Yes, we can open another issue to discuss this topic.

out_stream.write(attribute_name);
out_stream.write<int32_t>(static_cast<int32_t>(values.size()));
for (const T &value : values) {
Comment thread
yemreinci marked this conversation as resolved.
out_stream.write_object(value);
}
}
};

enum struct predicate_data_serializer_hook {
Expand Down Expand Up @@ -230,6 +239,15 @@ namespace hazelcast {
template<typename ...Args>
in_predicate(hazelcast_client &client, const std::string &attribute_name, const Args &...values)
: multi_predicate(attribute_name, client, values...) {}

/**
* The type of Args should be able to be serialized.
* @param attributeName The attribute whose value shall be compared to.
* @tparam value The values to search for
*/
template<typename T>
in_predicate(hazelcast_client &client, const std::string &attribute_name, const std::vector<T> &values)
: multi_predicate(attribute_name, client, values) {}
};

class and_predicate : public multi_predicate {
Expand Down
2 changes: 1 addition & 1 deletion hazelcast/test/src/HazelcastTests5.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1341,7 +1341,7 @@ namespace hazelcast {

// value in {4, 10, 19}
values = int_map_->values<int>(
query::in_predicate(client_, query::query_constants::THIS_ATTRIBUTE_NAME, 4, 10, 19)).get();
query::in_predicate(client_, query::query_constants::THIS_ATTRIBUTE_NAME, std::vector<int>({4, 10, 19}))).get();
ASSERT_EQ(2, (int) values.size());
std::sort(values.begin(), values.end());
ASSERT_EQ(4, values[0]);
Expand Down
25 changes: 23 additions & 2 deletions hazelcast/test/src/HazelcastTests8.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1438,6 +1438,27 @@ namespace hazelcast {
ASSERT_THROW((map->get<int, int>(1).get()), exception::hazelcast_client_not_active);
}

TEST_F(IssueTest, issue_888) {
// start a server
HazelcastServer server(*g_srvFactory);

auto hz = hazelcast::new_client().get();
auto map = hz.get_map("testmap").get();
map->put<std::string, std::string>("12", "hello").get();
map->put<std::string, std::string>("23", "world").get();
map->put<std::string, std::string>("34", "!!!!").get();

std::vector<std::string> myKeys{"12", "34"};

auto v = map->entry_set<std::string, std::string>(
query::in_predicate(hz, query::query_constants::KEY_ATTRIBUTE_NAME, myKeys)).get();

ASSERT_EQ(2, v.size());

ASSERT_NO_THROW(map->remove_all(
query::in_predicate(hz, query::query_constants::KEY_ATTRIBUTE_NAME, myKeys)).get());
}

TEST_F(IssueTest, invocation_should_not_block_indefinitely_during_client_shutdown) {
HazelcastServer server(*g_srvFactory);
auto hz = new_client().get();
Expand Down Expand Up @@ -1509,11 +1530,11 @@ namespace hazelcast {
namespace hazelcast {
namespace client {
namespace test {
HazelcastServer::HazelcastServer(HazelcastServerFactory &factory)
HazelcastServer::HazelcastServer(HazelcastServerFactory &factory)
: factory_(factory)
, is_started_(false)
, is_shutdown_(false)
, logger_(std::make_shared<logger>("HazelcastServer", "HazelcastServer",
, logger_(std::make_shared<logger>("HazelcastServer", "HazelcastServer",
logger::level::info, logger::default_handler)) {
start();
}
Expand Down