Hazelcast C++ Client
|
You can use native C++ Client to connect to hazelcast nodes and make almost all operations that a node does. Different from nodes, clients do not hold data.
Some of features of C++ Clients are:
Our C++ client is completely open source and the source code is freely available at https://github.com/hazelcast/hazelcast-cpp-client . Please feel free to contribute. You can join our community at https://groups.google.com/forum/#!forum/hazelcast where you can find answers to your questions.
Hazelcast C++ client is shipped with 32 & 64 bit, shared and static libraries. Compiled static libraries of dependencies are also available in the release.
The user should make sure that the libraries are in appropriate linkage path for the application.
Only dependency is shared_ptr from the boost library.
Downloaded release folder consist of
And each of the folders above (except docs folder) contains the following
C++ client is tested on Linux 32/64, Mac 64 and Windows 32/64 bit machines. For each of the headers above, it is assumed that you are in correct folder for your platform. Binaries that are distributed with enterprise zip are for following platforms: Windows_32 (Visual Studio 2012), Windows_64 (Visual Studio 2012), Linux_32(gcc 3.4+ , libc 2.5+) or Linux_64(gcc 3.4+ , libc 2.5+) For other platforms are specific compiler versions, please contact suppo rt@h azelc ast. com
For linux, there are two distributions one is 32bit the other is 64bit.
Sample script to build with static library:
Sample script to build with shared library:
For Mac binaries, please contact suppo rt@h azelc ast. com
Sample script to build with static library:
Sample script to build with shared library:
For Windows, there are two distributions one is 32bit the other is 64bit. Currently, the release is built with Visual Studio 2012 . For other builds, please contact with suppo rt@h azelc ast. com
When compiling for Windows environment the user should specify one of the following flags:
Note that these codes to work, there should be a Hazelcast node is running.
The binaries for the examples are located at examples folder. The sources for the binaries are located at examples/src folder.
You can also browse all the examples at https://github.com/hazelcast/hazelcast-cpp-client/tree/master/examples.
Furthermore, you can access a large set of tests that we use for testing the API, these will also give you a better idea about how we are using the API. You can find these tests at https://github.com/hazelcast/hazelcast-cpp-client/tree/master/hazelcast/test/src
The CommandLineTool example gives you a way to play with the data in the cluster from the command line terminal.
#include "(.*)" #include <iostream> using namespace hazelcast::client; int main(){ ClientConfig clientConfig; Address address("localhost", 5701); clientConfig.addAddress(address); HazelcastClient hazelcastClient(clientConfig); IMap<int,int> myMap = hazelcastClient.getMap<int ,int>("myIntMap"); myMap.put(1,3); boost::shared_ptr<int> v = myMap.get(1); if(v.get() != NULL){ //process the item } // You can work with raw pointer maps if you want to get memory ownership of returned objects hazelcast::client::adaptor::RawPointerMap<int, int> rawMap(myMap); myMap.put(2, 6); std::auto_ptr<int> value = myMap.get(1); if (NULL != value.get()) { // do something with the value } // query values with predicate // EqualPredicate // key == 5 std::vector<int> values = myMap.values(query::EqualPredicate<int>(query::QueryConstants::getKeyAttributeName(), 5)); // Same query with raw Map std::auto_ptr<DataArray<int> > valuesArray = rawMap.values(query::EqualPredicate<int>(query::QueryConstants::getKeyAttributeName(), 5)); size_t numberOfValues = valuesArray->size(); if (numberOfValues > 0) { const int *firstValue = valuesArray->get(0); firstValue = (*valuesArray)[0]; std::auto_ptr<int> firstValueWithMemoryOwnership = valuesArray->release(0); } // add listener with predicate // Only listen events for entries with key >= 7 MyEntryListener listener; std::string listenerId = map.addEntryListener(listener, hazelcast::client::query::GreaterLessPredicate<int>( hazelcast::client::query::QueryConstants::getKeyAttributeName(), 7, true, false), true); // same listener using the raw map std::string secondListener = rawMap.addEntryListener(listener, hazelcast::client::query::GreaterLessPredicate<int>( hazelcast::client::query::QueryConstants::getKeyAttributeName(), 7, true, false), true); // listen for entries sleep(10); return 0; }
#include "(.*)" #include <iostream> #include <string> using namespace hazelcast::client; int main(){ ClientConfig clientConfig; Address address("localhost", 5701); clientConfig.addAddress(address); HazelcastClient hazelcastClient(clientConfig); IQueue<std::string> q = hazelcastClient.getQueue<std::string>("q"); q.offer("sample"); boost::shared_ptr<std::string> v = q.poll(); if(v.get() != NULL){ //process the item } return 0; }
#include "(.*)" #include <iostream> #include <string> using namespace hazelcast::client; class SampleEntryListener { public: void entryAdded(EntryEvent<std::string, std::string> &event) { std::cout << "entry added " << event.getKey() << " " << event.getValue() << std::endl; }; void entryRemoved(EntryEvent<std::string, std::string> &event) { std::cout << "entry added " << event.getKey() << " " << event.getValue() << std::endl; } void entryUpdated(EntryEvent<std::string, std::string> &event) { std::cout << "entry added " << event.getKey() << " " << event.getValue() << std::endl; } void entryEvicted(EntryEvent<std::string, std::string> &event) { std::cout << "entry added " << event.getKey() << " " << event.getValue() << std::endl; } }; int main(int argc, char **argv) { ClientConfig clientConfig; Address address("localhost", 5701); clientConfig.addAddress(address); HazelcastClient hazelcastClient(clientConfig); IMap<std::string,std::string> myMap = hazelcastClient.getMap<std::string ,std::string>("myIntMap"); SampleEntryListener * listener = new SampleEntryListener(); std::string id = myMap.addEntryListener(*listener, true); myMap.put("key1", "value1"); //prints entryAdded myMap.put("key1", "value2"); //prints updated myMap.remove("key1"); //prints entryRemoved myMap.put("key2", "value2",1000); //prints entryEvicted after 1 second myMap.removeEntryListener(id); //WARNING: deleting listener before removing it from hazelcast leads to crashes. delete listener; //delete listener after remove it from hazelcast. return 0; };
Suppose you have the following two classes in Java and you want to use it with C++ client.
class Foo implements Serializable{ private int age; private String name; } class Bar implements Serializable{ private float x; private float y; }
First make them implement Portable or IdentifiedDataSerializable.
class Foo implements Portable { private int age; private String name; public int getFactoryId() { return 666; // a positive id that you choose } public int getClassId() { return 2; // a positive id that you choose } public void writePortable(PortableWriter writer) throws IOException { writer.writeUTF("n", &name); writer.writeInt("a", age); } public void readPortable(PortableReader reader) throws IOException { name = reader.readUTF("n"); age = reader.readInt("a"); } } class Bar implements IdentifiedDataSerializable { private float x; private float y; public int getFactoryId() { return 4; // a positive id that you choose } public int getId() { return 5; // a positive id that you choose } public void writeData(ObjectDataOutput out) throws IOException { out.writeFloat(x); out.writeFloat(y); } public void readData(ObjectDataInput in) throws IOException { x = in.readFloat(); y = in.readFloat(); } }
Then, implement the corresponding classes in C++ with same factory and class Id as follows:
class Foo : public serialization::Portable { public: int getFactoryId() const{ return 666; }; int getClassId() const{ return 2; }; void writePortable(serialization::PortableWriter &writer) const{ writer.writeUTF("n", &name); writer.writeInt("a", age); }; void readPortable(serialization::PortableReader &reader){ name = reader.readUTF("n"); age = reader.readInt("a"); }; private: int age; std::string name; }; class Bar : public serialization::IdentifiedDataSerializable { public: int getFactoryId() const{ return 4; }; int getClassId() const{ return 2; }; void writeData(serialization::ObjectDataOutput& out) const{ out.writeFloat(x); out.writeFloat(y); }; void readData(serialization::ObjectDataInput& in){ x = in.readFloat(); y = in.readFloat(); }; private: float x; float y; };
Now, you can use class Foo and Bar in distributed structures. For example as Key or Value of IMap, or as an Item in IQueue.