24 #include "jubatus/util/data/unordered_set.h"
25 #include "jubatus/util/lang/cast.h"
35 using jubatus::util::lang::lexical_cast;
36 using jubatus::util::data::unordered_set;
44 bool is_empty_query(
const preset_query& query) {
45 return query.node_query.empty() && query.edge_query.empty();
48 bool is_matched_to_query(
49 const vector<pair<string, string> >& query,
51 for (
size_t i = 0; i < query.size(); ++i) {
52 property::const_iterator it = prop.find(query[i].first);
53 if (it == prop.end() || it->second != query[i].second) {
62 for (eigen_vector_diff::const_iterator it = v.begin(); it != v.end(); ++it) {
63 sum += it->second.score;
65 const double normalizer = v.size() /
sum;
66 for (eigen_vector_diff::iterator it = v.begin(); it != v.end(); ++it) {
67 it->second.score *= normalizer;
119 for (spt_query_diff::iterator it =
spts_.begin(); it !=
spts_.end(); ++it) {
128 mixed.push_back(spt);
151 it->second.property = p;
164 string(
"graph_wo_index::remove_node unknown id=")
165 + lexical_cast<string>(
id)));
175 string(
"graph_wo_index::create_edge unknown src id=")
176 + lexical_cast<string>(src)
177 +
" tgt id=" + lexical_cast<string>(tgt),
243 eigen_vector_query_diff::const_iterator model_it
248 eigen_vector_diff::const_iterator it = model_it->second.find(
id);
249 if (it == model_it->second.end()) {
252 return it->second.score;
262 std::vector<node_id_t>& ret,
270 spt_query_diff::const_iterator model_it =
spts_.find(query);
271 if (model_it ==
spts_.end()) {
274 const spt_diff& mixed = model_it->second;
276 uint64_t min_score = ~uint64_t();
277 uint64_t ind = ~uint64_t();
278 for (uint64_t i = 0; i < mixed.size(); ++i) {
280 spt_edges::const_iterator src_it = spt.
to_root.find(src);
281 spt_edges::const_iterator tgt_it = spt.
from_root.find(tgt);
285 uint64_t score = src_it->second.first + tgt_it->second.first;
286 if (score < min_score) {
296 const spt_edges& to_root = mixed[ind].to_root;
297 const spt_edges& from_root = mixed[ind].from_root;
298 uint64_t landmark = mixed[ind].landmark;
300 for (uint64_t cur = src; cur != landmark;) {
301 if (ret.size() >= max_hop) {
304 spt_edges::const_iterator it = to_root.find(cur);
305 if (it == to_root.end()) {
313 cur = it->second.second;
315 ret.push_back(landmark);
317 std::vector<node_id_t> from_root_path;
318 for (uint64_t cur = tgt; cur != landmark;) {
319 if (ret.size() + from_root_path.size() >= max_hop) {
322 spt_edges::const_iterator it = from_root.find(cur);
323 if (it == from_root.end()) {
327 from_root_path.push_back(cur);
328 cur = it->second.second;
331 for (vector<node_id_t>::const_reverse_iterator rit = from_root_path.rbegin();
332 rit != from_root_path.rend(); ++rit) {
338 node_info_map::const_iterator it =
local_nodes_.find(
id);
346 edge_info_map::const_iterator it =
local_edges_.find(eid);
354 return string(
"graph_wo_index");
375 for (eigen_vector_query_diff::const_iterator query_it
382 for (eigen_vector_diff::const_iterator it = model.begin();
383 it != model.end(); ++it) {
384 if (it->second.out_degree_num == 0) {
385 dist += it->second.score;
389 unordered_set<node_id_t> unmatched_nodes;
391 uint64_t new_node_num = 0;
392 double dist_from_new_node = 0;
393 for (node_info_map::const_iterator node_it =
local_nodes_.begin();
395 if (model.count(node_it->first) == 0) {
396 if (!is_matched_to_query(query.
node_query, node_it->second.property)) {
397 unmatched_nodes.insert(node_it->first);
400 dist_from_new_node += 1.0;
404 dist += dist_from_new_node;
406 if (model.size() + new_node_num > 0) {
407 dist /= (model.size() + new_node_num);
412 for (node_info_map::const_iterator node_it =
local_nodes_.begin();
414 if (unmatched_nodes.count(node_it->first)) {
417 if (!is_matched_to_query(query.
node_query, node_it->second.property)) {
418 unmatched_nodes.insert(node_it->first);
422 const std::vector<edge_id_t>& in_edges = node_it->second.in_edges;
424 for (
size_t i = 0; i < in_edges.size(); ++i) {
425 if (unmatched_nodes.count(in_edges[i])) {
428 edge_info_map::const_iterator edge_it =
local_edges_.find(in_edges[i]);
433 const node_id_t src = edge_it->second.src;
434 if (unmatched_nodes.count(src)) {
437 if (!is_matched_to_query(query.
edge_query, edge_it->second.p)) {
441 eigen_vector_diff::const_iterator it = model.find(edge_it->second.src);
442 if (it == model.end()) {
445 if (it->second.out_degree_num != 0) {
448 score += it->second.score / it->second.out_degree_num;
456 if (is_empty_query(query)) {
459 uint64_t out_degree = 0;
460 for (
size_t i = 0; i < node_it->second.out_edges.size(); ++i) {
461 const edge_info_map::const_iterator edge_it
464 if (unmatched_nodes.count(edge.
tgt)) {
468 unmatched_nodes.insert(edge.
tgt);
471 if (!is_matched_to_query(query.
edge_query, edge.
p)) {
479 qdiff[node_it->first] = ei;
492 for (eigen_vector_query_diff::iterator model_it =
eigen_scores_.begin();
494 normalize(model_it->second);
503 se[landmark] = std::make_pair(0, landmark);
504 for (node_info_map::const_iterator it =
local_nodes_.begin();
516 const std::vector<edge_id_t>& edges,
519 for (
size_t i = 0; i < edges.size(); ++i) {
530 spt_edges::iterator tr_it = se.find(from);
531 if (tr_it != se.end()) {
532 uint64_t
dist = tr_it->second.first + 1;
533 spt_edges::iterator tr_jt = se.find(to);
534 if (tr_jt != se.end()) {
535 if (dist < tr_jt->second.first) {
536 tr_jt->second.first =
dist;
537 tr_jt->second.second = from;
540 se.insert(std::make_pair(to, std::make_pair(dist, from)));
549 node_info_map::const_iterator it =
local_nodes_.find(
id);
553 return is_matched_to_query(query.
node_query, it->second.property);
557 for (spt_query_diff::iterator it =
spts_.begin(); it !=
spts_.end(); ++it) {
559 for (
size_t i = 0; i < mixed.size(); ++i) {
571 for (spt_query_diff::const_iterator it =
spts_.begin(); it !=
spts_.end();
574 spt_diff& diff = all_diff[it->first];
575 diff.resize(mixed.size());
577 for (uint64_t i = 0; i < mixed.size(); ++i) {
584 for (node_info_map::const_iterator it =
local_nodes_.begin();
588 spt_edges::const_iterator from_it = spt.
from_root.find(
id);
590 diff[i].from_root[id] = from_it->second;
593 spt_edges::const_iterator to_it = spt.
to_root.find(
id);
594 if (to_it != spt.
to_root.end()) {
595 diff[i].to_root[id] = to_it->second;
622 status[
"local_node_num"] = lexical_cast<
string>(
local_nodes_.size());
623 status[
"global_node_num"] = lexical_cast<
string>(
global_nodes_.size());
624 status[
"local_edge_num"] = lexical_cast<
string>(
local_edges_.size());
635 for (eigen_vector_query_diff::const_iterator model_it = diff.begin();
636 model_it != diff.end(); ++model_it) {
638 for (eigen_vector_diff::const_iterator it = model_it->second.begin();
639 it != model_it->second.end(); ++it) {
640 evm[it->first] = it->second;
648 for (spt_edges::const_iterator it = diff.
from_root.begin();
653 for (spt_edges::const_iterator it = diff.
to_root.begin();
654 it != diff.
to_root.end(); ++it) {
655 mixed.
to_root[it->first] = it->second;
662 size_t landmark_num) {
663 for (spt_query_diff::const_iterator it = all_diff.begin();
664 it != all_diff.end(); ++it) {
666 spt_diff& mixed = all_mixed[it->first];
668 map<node_id_t, uint64_t> diff_landmark2ind;
669 for (uint64_t i = 0; i < diff.size(); ++i) {
670 if (diff[i].landmark != LLONG_MAX) {
671 diff_landmark2ind[diff[i].landmark] = i;
675 map<node_id_t, uint64_t> mixed_landmark2ind;
676 for (uint64_t i = 0; i < mixed.size(); ++i) {
677 if (mixed[i].landmark != LLONG_MAX) {
678 mixed_landmark2ind[mixed[i].landmark] = i;
682 for (map<node_id_t, uint64_t>::const_iterator it
683 = diff_landmark2ind.begin(); it != diff_landmark2ind.end(); ++it) {
684 map<node_id_t, uint64_t>::iterator jt
685 = mixed_landmark2ind.find(it->first);
686 if (jt != mixed_landmark2ind.end()) {
687 mix_spt(diff[it->second], mixed[jt->second]);
688 }
else if (mixed.size() < landmark_num) {
689 mixed.push_back(diff[it->second]);
696 std::vector<edge_id_t>& edges,
698 for (
size_t i = 0; i < edges.size(); ++i) {
699 if (edges[i] == eid) {
700 if (i + 1 < edges.size()) {
701 swap(edges[i], edges.back());
703 edges.resize(edges.size() - 1);
void update_spt_node(const preset_query &query, const std::vector< edge_id_t > &edges, spt_edges &se, bool is_out)
jubatus::util::data::unordered_map< node_id_t, eigen_vector_info > eigen_vector_diff
std::vector< std::pair< std::string, std::string > > edge_query
jubatus::util::data::unordered_map< preset_query, eigen_vector_diff > eigen_vector_query_diff
void create_node(node_id_t id)
void damping_factor(double a)
void shortest_path(node_id_t src, node_id_t tgt, uint64_t max_hop, std::vector< node_id_t > &ret, const preset_query &) const
void get_diff_shortest_path_tree(spt_query_diff &diff) const
void get_status(std::map< std::string, std::string > &status) const
double dist(const common::sfv_t &p1, const common::sfv_t &p2)
void get_edge(edge_id_t eid, edge_info &ret) const
void add_centrality_query(const preset_query &)
std::vector< std::pair< std::string, std::string > > node_query
static void mix_spt(const shortest_path_tree &diff, shortest_path_tree &mixed)
void mix(const diff_type &diff, diff_type &mixed)
std::vector< edge_id_t > in_edges
jubatus::util::data::unordered_map< preset_query, spt_diff > spt_query_diff
static void remove_by_swap(std::vector< edge_id_t > &edges, edge_id_t eid)
edge_info_map local_edges_
void remove_node(node_id_t id)
#define JUBATUS_EXCEPTION(e)
void remove_shortest_path_query(const preset_query &)
jubatus::util::data::unordered_map< node_id_t, uint8_t > global_nodes_
void unpack(msgpack::object o)
void may_set_landmark(node_id_t id)
void update_node(node_id_t id, const property &p)
std::vector< shortest_path_tree > spt_diff
std::map< std::string, std::string > property
double centrality(node_id_t id, centrality_type ct, const preset_query &) const
void swap(weighted_point &p1, weighted_point &p2)
void pack(framework::packer &packer) const
bool put_diff(const diff_type &mixed)
void get_node(node_id_t id, node_info &ret) const
msgpack::packer< jubatus_packer > packer
void update_spt_edges(const preset_query &query, spt_edges &se, node_id_t landmark, bool is_out)
void update_edge(edge_id_t eid, const property &p)
eigen_vector_query_diff eigen_vector_query
std::vector< edge_id_t > out_edges
void create_edge(edge_id_t eid, node_id_t src, node_id_t tgt)
node_info_map local_nodes_
double sum(const common::sfv_t &p)
void remove_edge(edge_id_t eid)
void put_diff_eigen_score(const eigen_vector_query_diff &mixed)
void remove_centrality_query(const preset_query &)
void put_diff_shortest_path_tree(const spt_query_diff &mixed)
void create_global_node(node_id_t id)
eigen_vector_query_diff eigen_scores_
void get_diff(diff_type &diff) const
jubatus::util::data::unordered_map< node_id_t, std::pair< uint64_t, node_id_t > > spt_edges
void get_diff_eigen_score(eigen_vector_query_diff &diff) const
bool is_node_matched_to_query(const preset_query &query, node_id_t id) const
void remove_global_node(node_id_t id)
void add_shortest_path_query(const preset_query &)