std::pair<std::string, int> cht::find_predecessor(const std::string& key) { std::vector<std::string> hlist; get_hashlist_(key, hlist); std::string hash = make_hash(key); std::string path; build_actor_path(path, type_, name_); path += "/cht"; std::vector<std::string>::iterator node0 = std::lower_bound(hlist.begin(), hlist.end(), hash); size_t idx = (static_cast<int>(node0 - hlist.begin()) + hlist.size() - 1) % hlist.size(); std::string ip; int port; std::string loc; if (lock_service_->read(path + "/" + hlist[idx], loc)) { revert(loc, ip, port); return make_pair(ip, port); } else { throw JUBATUS_EXCEPTION(core::common::not_found(path)); // TODO(kuenishi): output log and throw exception } }
// return at most n nodes, if theres nodes less than n, return size is also less // than n. // find(hash) :: lock_service -> key -> [node] // where hash(node0) <= hash(key) < hash(node1) bool cht::find( const std::string& key, std::vector<std::pair<std::string, int> >& out, size_t n) { out.clear(); std::vector<std::string> hlist; if (!get_hashlist_(key, hlist)) { throw JUBATUS_EXCEPTION(core::common::not_found(key)); } std::string hash = make_hash(key); std::string path; build_actor_path(path, type_, name_); path += "/cht"; std::vector<std::string>::iterator node0 = std::lower_bound(hlist.begin(), hlist.end(), hash); size_t idx = static_cast<int>(node0 - hlist.begin()) % hlist.size(); std::string loc; for (size_t i = 0; i < n; ++i) { std::string ip; int port; if (lock_service_->read(path + "/" + hlist[idx], loc)) { revert(loc, ip, port); out.push_back(make_pair(ip, port)); } else { // TODO(kuenishi): output log throw JUBATUS_EXCEPTION(core::common::not_found(path)); } idx++; idx %= hlist.size(); } return !hlist.size(); }
czk_test() { zk_ = pfi::lang::shared_ptr<jubatus::server::common::lock_service>( common::create_lock_service("zk", "localhost:2181", 1024, "test.log")); std::string engine_name, engine_root; engine_name = "test"; engine_root = ACTOR_BASE_PATH + "/" + engine_name; name_ = build_loc_str("localhost", 10000); build_actor_path(path, engine_name, name_); name1_ = build_loc_str("localhost", 10001); build_actor_path(path1, engine_name, name1_); zk_->create(JUBATUS_BASE_PATH, ""); zk_->create(ACTOR_BASE_PATH, ""); zk_->create(engine_root, ""); zk_->create(path, "hoge0", true); zk_->create(path1, "hoge1", true); }
bool cht::get_hashlist_( const std::string& key, std::vector<std::string>& hlist) { hlist.clear(); std::string path; build_actor_path(path, type_, name_); path += "/cht"; if (!lock_service_->list(path, hlist) || hlist.empty()) { return false; } std::sort(hlist.begin(), hlist.end()); return true; }
// register_node :: node -> bool; // creates /jubatus/actors/<name>/cht/<hash(ip_port)> with contents ip_port void cht::register_node(const std::string& ip, int port) { std::string path; build_actor_path(path, type_, name_); path += "/cht"; for (unsigned int i = 0; i < NUM_VSERV; ++i) { std::string hashpath = path + "/" + make_hash(build_loc_str(ip, port, i)); if (!lock_service_->create(hashpath, build_loc_str(ip, port), true)) { throw JUBATUS_EXCEPTION( core::common::exception::runtime_error("Failed to register cht node") << core::common::exception::error_api_func("lock_service::create") << core::common::exception::error_message("cht hashpash: " + hashpath)); } DLOG(INFO) << "cht node created: " << hashpath; } }
void cht::setup_cht_dir( lock_service& ls, const std::string& type, const std::string& name) { bool success = true; std::string path; build_actor_path(path, type, name); success = ls.create(path) && success; path += "/cht"; success = ls.create(path) && success; if (!success) { throw JUBATUS_EXCEPTION( core::common::exception::runtime_error("Failed to create cht directory") << core::common::exception::error_api_func("lock_service::create") << core::common::exception::error_message("cht path: " + path)); } }