~siborgium/prelockdpp

c8eed1220ae727dcfa2cdddaa167a4e6b1f03186 — Sergey Smirnykh 2 years ago 9540c80
Store iterators in uniq_id using raw storage
1 files changed, 34 insertions(+), 11 deletions(-)

M main.cpp
M main.cpp => main.cpp +34 -11
@@ 162,6 162,17 @@ struct uniq_id: public uniq_alive_hook, public uniq_temp_hook {
    timespec start_time;
    int      pid;

    // we want to be able to easily remove id from it's storage, colony,
    // and we want to do it efficiently & from anywhere
    // thus we need to keep it's iterator here
    //
    // we can't insert plf::colony<uniq_id>::iterator as a field
    // due to compiler error (application of sizeof to incomplete type)
    // but iterators are small, so we can try & fit them
    // into this storage
    constexpr static std::size_t store_size = 4 * sizeof(void*);
    char store[store_size];

    uniq_id(timespec time, int pid): start_time{ time }, pid{ pid } {}
    constexpr bool operator == (const uniq_id& id) const {
        return start_time.tv_sec == id.start_time.tv_sec


@@ 179,6 190,17 @@ struct uniq_id: public uniq_alive_hook, public uniq_temp_hook {
    }
};

// see comment to uniq_id
using uniq_colony_iterator = plf::colony<uniq_id>::iterator;
auto& get_self_iter(uniq_id& id) {
    return *reinterpret_cast<uniq_colony_iterator*>(id.store);
}
void set_self_iter(uniq_id& id, uniq_colony_iterator iter) {
    new (id.store) uniq_colony_iterator { iter };
}

static_assert(sizeof(plf::colony<uniq_id>::iterator) <= uniq_id::store_size);

using uniq_alive_set = intr::set<
    uniq_id, intr::compare<std::less<uniq_id>>, intr::base_hook<uniq_alive_hook>
>;


@@ 481,7 503,9 @@ struct context {
                    current_ids.insert(*iter);
                    alive_ids.erase(iter);
                } else {
                    current_ids.insert(*ids.emplace(id));
                    auto colony_iter = ids.emplace(id);
                    set_self_iter(*colony_iter, colony_iter);
                    current_ids.insert(*colony_iter);
                }

#if 0


@@ 506,17 530,16 @@ struct context {
        // FIXME: figure out how to store iterators
        //        and enjoy cheap removal
        {
            auto maybe_dead = ids.begin();
            while (maybe_dead != ids.end()) {
                if (auto dead = alive_ids.find(*maybe_dead); dead != alive_ids.end()) {
                    alive_ids.erase(dead);
                    auto iter = maybe_dead;
                    ids.erase(iter);
                    ++maybe_dead;
                    continue;
                }
                ++maybe_dead;
            auto dead = alive_ids.begin();
            while (dead != alive_ids.end()) {
                auto copy = dead;
                ++dead;

                auto orig = get_self_iter(*copy);
                alive_ids.erase(copy);
                ids.erase(orig);
            }

        }
        for (auto&& id: current_ids) {
            alive_ids.insert(id);