in analytical_engine/core/fragment/dynamic_fragment.h [259:413]
void Mutate(mutation_t& mutation) {
vertex_t v;
if (!mutation.vertices_to_remove.empty() &&
static_cast<double>(mutation.vertices_to_remove.size()) /
static_cast<double>(this->GetVerticesNum()) <
0.1) {
std::set<vertex_t> sparse_set;
for (auto gid : mutation.vertices_to_remove) {
if (Gid2Vertex(gid, v) && IsAliveVertex(v)) {
if (IsInnerVertex(v)) {
if (load_strategy_ == grape::LoadStrategy::kBothOutIn) {
ie_.remove_vertex(v.GetValue());
}
oe_.remove_vertex(v.GetValue());
iv_alive_.reset_bit(v.GetValue());
--alive_ivnum_;
is_selfloops_.reset_bit(v.GetValue());
} else {
ov_alive_.reset_bit(outerVertexLidToIndex(v.GetValue()));
}
sparse_set.insert(v);
}
}
if (!sparse_set.empty()) {
auto func = [&sparse_set](vid_t i, const nbr_t& e) {
return sparse_set.find(e.neighbor) != sparse_set.end();
};
if (load_strategy_ == grape::LoadStrategy::kBothOutIn) {
ie_.remove_if(func);
}
oe_.remove_if(func);
}
} else if (!mutation.vertices_to_remove.empty()) {
grape::DenseVertexSet<vertices_t> dense_bitset(Vertices());
for (auto gid : mutation.vertices_to_remove) {
if (Gid2Vertex(gid, v) && IsAliveVertex(v)) {
if (IsInnerVertex(v)) {
if (load_strategy_ == grape::LoadStrategy::kBothOutIn) {
ie_.remove_vertex(v.GetValue());
}
oe_.remove_vertex(v.GetValue());
iv_alive_.reset_bit(v.GetValue());
--alive_ivnum_;
is_selfloops_.reset_bit(v.GetValue());
} else {
ov_alive_.reset_bit(outerVertexLidToIndex(v.GetValue()));
}
dense_bitset.Insert(v);
}
}
auto func = [&dense_bitset](vid_t i, const nbr_t& e) {
return dense_bitset.Exist(e.neighbor);
};
if (!dense_bitset.Empty()) {
if (load_strategy_ == grape::LoadStrategy::kBothOutIn) {
ie_.remove_if(func);
}
oe_.remove_if(func);
}
}
if (!mutation.edges_to_remove.empty()) {
removeEdges(mutation.edges_to_remove);
}
if (!mutation.edges_to_update.empty()) {
for (auto& e : mutation.edges_to_update) {
if (IsInnerVertexGid(e.src)) {
e.src = id_parser_.get_local_id(e.src);
} else {
e.src = parseOuterVertexGid(e.src);
}
if (IsInnerVertexGid(e.dst)) {
e.dst = id_parser_.get_local_id(e.dst);
} else {
e.dst = parseOuterVertexGid(e.dst);
}
}
updateEdges(mutation.edges_to_update);
}
{
auto& edges_to_add = mutation.edges_to_add;
static constexpr vid_t invalid_vid = std::numeric_limits<vid_t>::max();
vid_t old_ovnum = ovgid_.size();
// parseOrAddOuterVertexGid will update ovnum_
for (auto& e : edges_to_add) {
if (IsInnerVertexGid(e.src)) {
e.src = id_parser_.get_local_id(e.src);
if (IsInnerVertexGid(e.dst)) {
e.dst = id_parser_.get_local_id(e.dst);
} else {
mutation.vertices_to_add.emplace_back(e.dst);
e.dst = parseOrAddOuterVertexGid(e.dst);
}
} else {
if (IsInnerVertexGid(e.dst)) {
mutation.vertices_to_add.emplace_back(e.src);
e.src = parseOrAddOuterVertexGid(e.src);
e.dst = id_parser_.get_local_id(e.dst);
} else {
e.src = invalid_vid;
}
}
}
vid_t new_ivnum = vm_ptr_->GetInnerVertexSize(fid_);
vid_t new_ovnum = ovgid_.size();
assert(new_ovnum == ovnum_);
assert(new_ivnum >= ivnum_ && new_ovnum >= old_ovnum);
is_selfloops_.resize(new_ivnum);
oe_.add_vertices(new_ivnum - ivnum_, new_ovnum - old_ovnum);
ie_.add_vertices(new_ivnum - ivnum_, new_ovnum - old_ovnum);
this->ivnum_ = new_ivnum;
if (old_ovnum != new_ovnum) {
initOuterVerticesOfFragment();
}
if (!edges_to_add.empty()) {
addEdges(edges_to_add);
}
this->inner_vertices_.SetRange(0, new_ivnum);
this->outer_vertices_.SetRange(id_parser_.max_local_id() - new_ovnum,
id_parser_.max_local_id());
this->vertices_.SetRange(0, new_ivnum,
id_parser_.max_local_id() - new_ovnum,
id_parser_.max_local_id());
}
ivdata_.resize(this->ivnum_, dynamic::Value(rapidjson::kObjectType));
iv_alive_.resize(this->ivnum_);
ov_alive_.resize(this->ovnum_);
alive_ovnum_ = this->ovnum_;
for (auto& v : mutation.vertices_to_add) {
vid_t lid;
if (IsInnerVertexGid(v.vid)) {
this->InnerVertexGid2Lid(v.vid, lid);
ivdata_[lid].Update(v.vdata);
if (iv_alive_.get_bit(lid) == false) {
iv_alive_.set_bit(lid);
++alive_ivnum_;
}
} else {
if (this->OuterVertexGid2Lid(v.vid, lid)) {
auto index = outerVertexLidToIndex(lid);
if (ov_alive_.get_bit(index) == false) {
ov_alive_.set_bit(index);
}
}
}
}
for (auto& v : mutation.vertices_to_update) {
vid_t lid;
if (IsInnerVertexGid(v.vid)) {
this->InnerVertexGid2Lid(v.vid, lid);
ivdata_[lid] = std::move(v.vdata);
}
}
}