const auto &source = items_by_id[id_from];
g_assert(source.get() != nullptr);
- source->deps.emplace_back(nullptr,
- std::string(to),
- id_from,
- -1);
+ if (!source->deps.contains(id_from)) {
+ msg_debug_cache("add dependency %s -> %s",
+ source->symbol.c_str(), to.data());
+ source->deps.emplace(id_from, cache_dependency{nullptr,
+ std::string(to),
+ id_from,
+ -1});
+ }
+ else {
+ msg_debug_cache("duplicate dependency %s -> %s",
+ source->symbol.c_str(), to.data());
+ return;
+ }
if (virtual_id_from >= 0) {
/* We need that for settings id propagation */
const auto &vsource = items_by_id[virtual_id_from];
g_assert(vsource.get() != nullptr);
- vsource->deps.emplace_back(nullptr,
- std::string(to),
- -1,
- virtual_id_from);
+
+ if (!vsource->deps.contains(virtual_id_from)) {
+ msg_debug_cache("add virtual dependency %s -> %s",
+ vsource->symbol.c_str(), to.data());
+ vsource->deps.emplace(virtual_id_from, cache_dependency{nullptr,
+ std::string(to),
+ -1,
+ virtual_id_from});
+ }
+ else {
+ msg_debug_cache("duplicate virtual dependency %s -> %s",
+ vsource->symbol.c_str(), to.data());
+ }
}
}
tsort_mark(it, tsort_mask::TEMP);
msg_debug_cache_lambda("visiting node: %s (%d)", it->symbol.c_str(), cur_order);
- for (const auto &dep: it->deps) {
+ for (const auto &[id, dep]: it->deps) {
msg_debug_cache_lambda("visiting dep: %s (%d)", dep.item->symbol.c_str(), cur_order + 1);
rec(dep.item, cur_order + 1, rec);
}
auto own_timeout = get_item_timeout(it);
auto max_child_timeout = 0.0;
- for (const auto &dep: it->deps) {
+ for (const auto &[id, dep]: it->deps) {
auto cld_timeout = self(dep.item, self);
if (cld_timeout > max_child_timeout) {
/* Allow logging macros to work */
auto log_tag = [&]() { return cache.log_tag(); };
- for (auto &dep: deps) {
+ for (auto &[_id, dep]: deps) {
msg_debug_cache("process real dependency %s on %s", symbol.c_str(), dep.sym.c_str());
auto *dit = cache.get_item_by_name_mut(dep.sym, true);
continue;
}
+
+ dep.item = dit;
}
else {
if (dit->id == id) {
auto *parent = get_parent_mut(cache);
if (parent) {
- dit->rdeps.emplace_back(parent, parent->symbol, parent->id, -1);
+ if (!dit->rdeps.contains(parent->id)) {
+ dit->rdeps.emplace(parent->id, cache_dependency{parent, parent->symbol, parent->id, -1});
+ msg_debug_cache("added reverse dependency from %d on %d", parent->id,
+ dit->id);
+ }
+ else {
+ msg_debug_cache("reverse dependency from %d on %d already exists",
+ parent->id, dit->id);
+ }
dep.item = dit;
dep.id = dit->id;
-
- msg_debug_cache("added reverse dependency from %d on %d", parent->id,
- dit->id);
+ }
+ else {
+ msg_err_cache("cannot find parent for virtual symbol %s, when resolving dependency %s",
+ symbol.c_str(), dep.sym.c_str());
}
}
else {
dep.item = dit;
dep.id = dit->id;
- dit->rdeps.emplace_back(this, symbol, id, -1);
- msg_debug_cache("added reverse dependency from %d on %d", id,
- dit->id);
+ if (!dit->rdeps.contains(id)) {
+ dit->rdeps.emplace(id, cache_dependency{this, symbol, id, -1});
+ msg_debug_cache("added reverse dependency from %d on %d", id,
+ dit->id);
+ }
+ else {
+ msg_debug_cache("reverse dependency from %d on %d already exists",
+ id, dit->id);
+ }
}
}
}
continue;
}
+ else {
+ msg_err_cache("cannot find dependency named %s for symbol %s",
+ dep.sym.c_str(), symbol.c_str());
+ }
}
// Remove empty deps
- deps.erase(std::remove_if(std::begin(deps), std::end(deps),
- [](const auto &dep) { return !dep.item; }),
- std::end(deps));
+ for (auto it = deps.begin(); it != deps.end();) {
+ if (it->second.item == nullptr) {
+ it = deps.erase(it);
+ }
+ else {
+ ++it;
+ }
+ }
}
auto cache_item::resolve_parent(const symcache &cache) -> bool
augmentations;
/* Dependencies */
- std::vector<cache_dependency> deps;
+ ankerl::unordered_dense::map<int, cache_dependency> deps;
/* Reverse dependencies */
- std::vector<cache_dependency> rdeps;
+ ankerl::unordered_dense::map<int, cache_dependency> rdeps;
public:
/**
auto ret = true;
- for (const auto &dep: item->deps) {
+ for (const auto &[id, dep]: item->deps) {
if (!dep.item) {
/* Assume invalid deps as done */
msg_debug_cache_task_lambda("symbol %d(%s) has invalid dependencies on %d(%s)",
return;
}
- for (const auto &rdep: item->rdeps) {
+ for (const auto &[id, rdep]: item->rdeps.values()) {
if (rdep.item) {
auto *dyn_item = get_dynamic_item(rdep.item->id);
if (dyn_item->status == cache_item_status::not_started) {