diff options
author | Claudius "keldu" Holeksa <mail@keldu.de> | 2023-12-04 12:20:01 +0100 |
---|---|---|
committer | Claudius "keldu" Holeksa <mail@keldu.de> | 2023-12-04 12:20:01 +0100 |
commit | fb7ed24d557c9f9ac5eaa60dbf22cba509953c1a (patch) | |
tree | fd9da3393972d07bef6aafaaafe7e3c7b27184e0 /modules/core/id_map.h | |
parent | a14896f9ed209dd3f9597722e5a5697bd7dbf531 (diff) |
core: Moving structure around
Diffstat (limited to 'modules/core/id_map.h')
-rw-r--r-- | modules/core/id_map.h | 137 |
1 files changed, 0 insertions, 137 deletions
diff --git a/modules/core/id_map.h b/modules/core/id_map.h deleted file mode 100644 index d8329cf..0000000 --- a/modules/core/id_map.h +++ /dev/null @@ -1,137 +0,0 @@ -#pragma once - -#include "id.h" -#include "error.h" - -#include <deque> - -namespace saw { -/** - * Fast random access id based container. - * - * Access - O(1) - * Insert - O(1) - * Erase - O(n) ? Dunno - */ -template<typename T> -class id_map final { -private: - /** - * Container which stores the primary data - */ - std::vector<T> data_; - /** - * Container which tracks free'd/fragmented elements within the - * main container - */ - std::deque<id<T>> free_ids_; - -private: - /** - * Tries to reduce top ids - */ - void reduce_free_ids() noexcept { - for(;;){ - if(free_ids_.empty()){ - break; - } - - if((free_ids_.front().get_value() + 1) < data_.size()){ - break; - } - - /** - * Can this throw? - */ - free_ids_.pop_front(); - } - } -public: - /** - * Default constructor - */ - id_map() = default; - - SAW_FORBID_COPY(id_map); - SAW_DEFAULT_MOVE(id_map); - - /** - * Inserts an element into the container and returns either an id on success - * or an error on failure. - */ - error_or<id<T>> insert(T val) noexcept { - /// @todo Fix size_t and id base type - if(free_ids_.empty()){ - try { - size_t i = data_.size(); - data_.emplace_back(std::move(val)); - return saw::id<T>{i}; - } catch(std::exception& e) { - return make_error<err::out_of_memory>(); - } - } else { - auto f_id = std::move(free_ids_.back()); - free_ids_.pop_back(); - data_.at(f_id.get_value()) = std::move(val); - return f_id; - } - - exit(-1); - // Dummy return since this is not reachable - return make_error<err::critical>(); - } - - /** - * Erase a value at this id. - */ - error_or<void> erase(const id<T>& val) noexcept { - /** - * If id is bigger than the available vector then return an error. - */ - if(val.get_value() >= data_.size()){ - return make_error<err::not_found>("ID is too large"); - } - - /** - * Check if it's the highest ID. Then we can just try to reduce the highest - * IDs. - */ - if((val.get_value() + 1) == data_.size()){ - data_.pop_back(); - this->reduce_free_ids(); - if(data_.size()*2 <= data_.capacity()){ - try { - data_.shrink_to_fit(); - }catch(std::exception& e){ - return make_error<err::out_of_memory>(); - } - } - return void_t{}; - } - - /** - * Check if ID already exists with the free IDs. - * This would mean that a double free has occured. - */ - auto find_id = std::find(free_ids_.begin(), free_ids_.end(), val); - if(find_id != free_ids_.end()){ - return make_error<err::not_found>("ID value has already been freed"); - } - - /** - * Insert id into deque and sort it. - */ - try { - free_ids_.push_back(val); - } catch(std::exception& e){ - return make_error<err::out_of_memory>(); - } - std::stable_sort(free_ids_.begin(), free_ids_.end(), - [](const id<T>& left, const id<T>& right) -> bool { - return left.get_value() > right.get_value(); - } - ); - return void_t{}; - } -}; -} |