Skip to content

Commit

Permalink
Improve dstore performance (#88)
Browse files Browse the repository at this point in the history
enable configuring multiple hive ipfs nodes through dstore_create(), and randomly select one as working node. working node is re-selected if the current one stops working.
  • Loading branch information
jiiq authored and stiartsly committed Aug 5, 2019
1 parent 58b76d9 commit 943094b
Show file tree
Hide file tree
Showing 10 changed files with 138 additions and 24 deletions.
6 changes: 3 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ matrix:
- BUILD_DIR="${TRAVIS_BUILD_DIR}/../build"
- mkdir -p "${BUILD_DIR}"
- cd "${BUILD_DIR}"
- CCC_CXX=clang++-3.8 scan-build-3.8 --status-bugs cmake -DJSON_FOR_MODERN_CXX_INCLUDE_DIR:PATH="${TRAVIS_BUILD_DIR}/../include" -DBUILD_SHARED_LIBS:BOOL=ON "${SOURCE_DIR}"
- CCC_CXX=clang++-3.8 scan-build-3.8 --status-bugs cmake -DBUILD_TESTING=FALSE -DJSON_FOR_MODERN_CXX_INCLUDE_DIR:PATH="${TRAVIS_BUILD_DIR}/../include" -DBUILD_SHARED_LIBS:BOOL=ON "${SOURCE_DIR}"
- CCC_CXX=clang++-3.8 scan-build-3.8 --status-bugs make VERBOSE=1
- os: linux
before_install:
Expand Down Expand Up @@ -171,7 +171,7 @@ matrix:
- mkdir -p "${BUILD_DIR}"
- cd "${BUILD_DIR}"
- echo "CXXFLAGS='${CXXFLAGS}' LDFLAGS='${LDFLAGS}'"
- cmake -DJSON_FOR_MODERN_CXX_INCLUDE_DIR:PATH="${TRAVIS_BUILD_DIR}/../include" -DBUILD_SHARED_LIBS:BOOL=ON -DCMAKE_BUILD_TYPE=Debug "${SOURCE_DIR}"
- cmake -DBUILD_TESTING=FALSE -DJSON_FOR_MODERN_CXX_INCLUDE_DIR:PATH="${TRAVIS_BUILD_DIR}/../include" -DBUILD_SHARED_LIBS:BOOL=ON -DCMAKE_BUILD_TYPE=Debug "${SOURCE_DIR}"
- make VERBOSE=1
- "${TRAVIS_BUILD_DIR}/.travis/ipfs_daemon_start.sh"
- OK="no"
Expand Down Expand Up @@ -199,5 +199,5 @@ script:
- mkdir -p "${BUILD_DIR}"
- cd "${BUILD_DIR}"
- echo "CXXFLAGS='${CXXFLAGS}' LDFLAGS='${LDFLAGS}'"
- cmake -DJSON_FOR_MODERN_CXX_INCLUDE_DIR:PATH="${TRAVIS_BUILD_DIR}/../include" -DBUILD_SHARED_LIBS:BOOL=ON "${CMAKE_EXTRA_ARGS_}" "${SOURCE_DIR}"
- cmake -DBUILD_TESTING=FALSE -DJSON_FOR_MODERN_CXX_INCLUDE_DIR:PATH="${TRAVIS_BUILD_DIR}/../include" -DBUILD_SHARED_LIBS:BOOL=ON "${CMAKE_EXTRA_ARGS_}" "${SOURCE_DIR}"
- make VERBOSE=1
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ add_definitions(-DCURL_STATICLIB)
# Find "JSON for Modern C++" (nlohmann/json.hpp)
include_directories("include/hive")

include_directories("include")
include_directories(BEFORE "include")

# Targets
# cpp-hive-api
Expand Down
6 changes: 6 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
2019/08/05 Li Fenxiang [email protected]

**Version 0.1.2**, main feature list:

- Improve DStore performance

2019/05/05 Li Fenxiang [email protected]

**Version 0.1.1**, main feature list:
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,14 @@ $ cd build
Generate the Makefile in the current directory:

```shell
$ cmake ..
$ cmake -DBUILD_TESTING=FALSE ..
$ make
```

To be able to build a distribution and install it to the customized location, run the following commands:

```shell
$ cmake -DCMAKE_INSTALL_PREFIX=YOUR-INSTALL-PATH ..
$ cmake -DBUILD_TESTING=FALSE -DCMAKE_INSTALL_PREFIX=YOUR-INSTALL-PATH ..
$ make install
```
# Run Tests
Expand Down
8 changes: 7 additions & 1 deletion include/hive/c-api.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,15 @@ const char* hive_generate_conf(const char* host, int port);
const char* hive_refresh_conf(const char* defaultConf);
const char* hive_random_host(const char* volatileConf);

typedef struct dstorec_node {
char *ipv4;
char *ipv6;
uint16_t port;
} dstorec_node;

typedef void DStoreC;

DStoreC *dstore_create(const char *hive_conf);
DStoreC *dstore_create(dstorec_node *bootstraps, size_t sz);
void dstore_destroy(DStoreC *dstore);
int dstore_get_values(DStoreC *dstore, const char *key,
bool (*cb)(const char *key, const uint8_t *value,
Expand Down
24 changes: 21 additions & 3 deletions include/hive/message.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#if !defined(__DMMESSAGE_H_)
#define __DMMESSAGE_H_

#include <vector>

#include <hive/node.h>
#include <string>

Expand All @@ -21,9 +23,15 @@ class DMessage {
std::string content;
};

typedef struct dstore_node {
std::string ipv4;
std::string ipv6;
uint16_t port;
} dstore_node;

class DStore {
public:
DStore(const std::string host, int port, bool log = false);
explicit DStore(std::vector<dstore_node> &&nodes, bool log = false);

std::string get_peerId();

Expand All @@ -42,11 +50,20 @@ class DStore {

bool remove_values(const std::string& key);

bool set_sender_UID(std::string& uid);

void enable_log(bool enable);

private:
bool set_sender_UID(std::string& uid);

std::shared_ptr<std::vector<std::shared_ptr<DMessage>>> get_values_internal(
const std::string& key);

bool add_value_internal(const std::string& key, std::shared_ptr<DMessage> message);

bool remove_values_internal(const std::string& key);

bool select_node();

bool publish();

bool resolve();
Expand All @@ -60,6 +77,7 @@ class DStore {
bool needPublish;
bool needResolve;
bool debugLog;
std::vector<dstore_node> candidate_nodes;
};

#endif // __DMMESSAGE_H_
8 changes: 5 additions & 3 deletions include/hive/node.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,18 @@ class Node {
* @snippet generic.cc ipfs::Node::Node
*
* @since version 0.1.0 */
Node(
explicit Node(
/** [in] Hostname or IP address of the server to connect to. */
const std::string& host,
const std::string& host = "localhost",
/** [in] Port to connect to. */
long port);
long port = 9095);

/** Destructor.
* @since version 0.1.0 */
~Node();

void set_addr(const std::string& host, long port);

/** Return the identity of the peer.
*
* Implements
Expand Down
24 changes: 16 additions & 8 deletions src/c-api/dstorec.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,26 @@
#include <fstream>
#include <memory>
#include <string>
#include <vector>
#include <utility>

#include <hive/c-api.h>
#include <hive/message.h>

DStoreC *dstore_create(const char *hive_conf) {
DStoreC *dstore_create(dstorec_node *bootstraps, size_t sz) {
try {
auto host_rand = hive_random_host(hive_conf);
if (!host_rand) return nullptr;
std::vector<dstore_node> ds_bootstraps;

auto ds = new DStore{host_rand, 9095};
if (!bootstraps || !sz)
return nullptr;

// Please replace this line
std::string uid = "uid-2041b18e-ca86-4962-9a21-d477f7f627ce";
ds->set_sender_UID(uid);
for (size_t i = 0; i < sz; ++i) {
ds_bootstraps.push_back(dstore_node {bootstraps[i].ipv4,
bootstraps[i].ipv6,
bootstraps[i].port});
}

auto ds = new DStore{std::move(ds_bootstraps)};

return reinterpret_cast<DStoreC *>(ds);
} catch (...) {
Expand All @@ -39,7 +45,9 @@ int dstore_get_values(DStoreC *dstore, const char *key,
if (!dstore || !key || !*key || !callback) return -1;

try {
const auto &dmsgs = ds->get_values(key);
const auto dmsgs = ds->get_values(key);
if (!dmsgs)
return -1;
for (auto &dmsg : *dmsgs) {
auto value = dmsg->value();
bool cont = callback(key, reinterpret_cast<const uint8_t *>(value.data()),
Expand Down
76 changes: 73 additions & 3 deletions src/message.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,52 @@
#include <iostream>
#include <stdexcept>
#include <string>
#include <algorithm>
#include <random>

#include <hive/cluster.h>
#include <hive/node.h>
#include <hive/test/utils.h>
#include "hive/message.h"

DStore::DStore(const std::string host, int port, bool log) : node(host, port) {
bool DStore::select_node() {
std::random_device rd;
std::mt19937 g(rd());
// Please replace this line
std::string uid = "uid-2041b18e-ca86-4962-9a21-d477f7f627ce";

std::shuffle(candidate_nodes.begin(), candidate_nodes.end(), g);

for (auto &nd : candidate_nodes) {
if (!nd.ipv4.empty()) {
node.set_addr(nd.ipv4, nd.port);
try {
ipfs::Json json;
node.Version(&json);
return set_sender_UID(uid);
} catch (...) {}
}

if (!nd.ipv6.empty()) {
node.set_addr(nd.ipv6, nd.port);
try {
ipfs::Json json;
node.Version(&json);
return set_sender_UID(uid);
} catch (...) {}
}
}

return false;
}

DStore::DStore(std::vector<dstore_node> &&nodes, bool log): candidate_nodes {nodes} {
debugLog = log;
needPublish = true;
needResolve = true;

if (!select_node())
throw std::runtime_error("no IPFS node is reachable");
}

std::string DStore::get_peerId() { return peerId; }
Expand Down Expand Up @@ -90,6 +126,19 @@ std::shared_ptr<std::vector<std::string>> DStore::get_remote_keys(

std::shared_ptr<std::vector<std::shared_ptr<DMessage>>> DStore::get_values(
const std::string& key) {
auto dmsg = get_values_internal(key);

if (dmsg)
return dmsg;

if (!select_node())
return nullptr;

return get_values_internal(key);
}

std::shared_ptr<std::vector<std::shared_ptr<DMessage>>> DStore::get_values_internal(
const std::string &key) {
// ipfs files ls /nodes/peerId/
// ipfs files read /nodes/peerId/messages/key/001
// ipfs files read /nodes/peerId/messages/key/002
Expand Down Expand Up @@ -136,7 +185,7 @@ std::shared_ptr<std::vector<std::shared_ptr<DMessage>>> DStore::get_values(
<< " failed" << std::endl;
std::cerr << e.what() << std::endl;
}
return vm;
return nullptr;
}

if (debugLog) {
Expand Down Expand Up @@ -204,6 +253,17 @@ DStore::get_remote_values(const std::string& peerId, const std::string& key) {

bool DStore::add_value(const std::string& key,
std::shared_ptr<DMessage> message) {
if (add_value_internal(key, message))
return true;

if (!select_node())
return false;

return add_value_internal(key, message);
}

bool DStore::add_value_internal(const std::string &key,
std::shared_ptr<DMessage> message) {
// > ipfs files write /nodes/peerId/messages/key/timestamp-xxxx

// > ipfs files stat /nodes/peerId
Expand Down Expand Up @@ -265,6 +325,16 @@ bool DStore::add_value(const std::string& key,
}

bool DStore::remove_values(const std::string& key) {
if (remove_values_internal(key))
return true;

if (!select_node())
return false;

return remove_values_internal(key);
}

bool DStore::remove_values_internal(const std::string& key) {
// > ipfs files rm /nodes/peerId/messages/key/xxxxxxxx

// > ipfs files stat /nodes/peerId
Expand Down Expand Up @@ -293,7 +363,7 @@ bool DStore::remove_values(const std::string& key) {
return publish();
}

bool DStore::set_sender_UID(std::string& uid) {
bool DStore::set_sender_UID(std::string &uid){
ipfs::Json uidInfo;

node.UidInfo(uid, &uidInfo);
Expand Down
4 changes: 4 additions & 0 deletions src/node.cc
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ Node::~Node() { delete http_; }

void Node::Id(Json* id) { FetchAndParseJson(MakeUrl("id"), id); }

void Node::set_addr(const std::string& host, long port) {
url_prefix_ = "http://" + host + ":" + std::to_string(port) + "/api/v0";
}

void Node::Version(Json* version) {
FetchAndParseJson(MakeUrl("version"), version);
}
Expand Down

0 comments on commit 943094b

Please sign in to comment.