diff options
Diffstat (limited to 'intellect-framework-from-internet/starts/meaning-vm/level-0/memorystore.cpp')
-rw-r--r-- | intellect-framework-from-internet/starts/meaning-vm/level-0/memorystore.cpp | 179 |
1 files changed, 0 insertions, 179 deletions
diff --git a/intellect-framework-from-internet/starts/meaning-vm/level-0/memorystore.cpp b/intellect-framework-from-internet/starts/meaning-vm/level-0/memorystore.cpp deleted file mode 100644 index 24e91b0..0000000 --- a/intellect-framework-from-internet/starts/meaning-vm/level-0/memorystore.cpp +++ /dev/null @@ -1,179 +0,0 @@ -#include "memorystore.hpp" -#include "concept.hpp" -#include "errors.hpp" -#include "ref.hpp" - -#include <memory> -#include <unordered_map> - -namespace intellect { -namespace level0 { - -static auto & index() -{ - static std::unordered_map<ref, std::unique_ptr<concept>, std::hash<concept*>> index; - return index; -} - - -namespace concepts { - ref allocator() { static ref ret = basic_alloc(); return ret; } - ref allocates() { static ref ret = basic_alloc(); return ret; } - ref allocations() { static ref ret = basic_alloc(); return ret; } - ref level0allocations() { static ref ret = basic_alloc(); return ret; } -} - -struct init { init() -{ - concepts::allocator().link(concepts::allocator(), concepts::level0allocations()); - concepts::level0allocations().link(concepts::allocates(), concepts::allocator()); - - concepts::allocates().link(concepts::allocator(), concepts::level0allocations()); - concepts::level0allocations().link(concepts::allocates(), concepts::allocates()); - - concepts::allocations().link(concepts::allocator(), concepts::level0allocations()); - concepts::level0allocations().link(concepts::allocates(), concepts::allocations()); - - concepts::level0allocations().link(concepts::allocator(), concepts::level0allocations()); - concepts::level0allocations().link(concepts::allocates(), concepts::level0allocations()); -} } _init; - -ref basic_alloc(std::any data) -{ - ref r = new concept(); - r.ptr()->data = data; - index().emplace(r, r.ptr()); - return r; -} - -ref alloc(ref source, std::any data) -{ - ref r = basic_alloc(data); - alloc(r, source); - return r; -} - -void alloc(ref r, ref source) -{ - r.link(concepts::allocator(), source); - source.link(concepts::allocates(), r); -} - -void realloc(ref r, ref newsource) -{ - ref oldsource = r.get(concepts::allocator()); - alloc(r, newsource); - dealloc(r, oldsource); -} - -static concept* referenced(ref r, concept* source = 0) { - for (auto & r2pair : index()) { - ref r2 = r2pair.first; - if (r2.ptr() == source) { - continue; - } - if (r2 == r) { - continue; - } - for (auto & l : r2.links()) { - if (ref(l.first) == r) { - return r2; - } - if (ref(l.second) == r) { - return r2; - } - } - } - return 0; -} - -void basic_dealloc(ref r) -{ - if (r.crucial()) { throw crucial_concept(r); } - auto it = index().find(r); - if (it == index().end()) { throw no_such_concept(r); } - - concept * referenced = intellect::level0::referenced(r); - if (referenced) { - throw still_referenced_by(r, referenced); - } - - index().erase(it); -} - -void dealloc_from(ref source) -{ - std::remove_reference<decltype(index())>::type forgotten; - - auto ours = source.getAll(concepts::allocates()); - for (auto allocation : ours) { - if (allocation.crucial()) { throw crucial_concept(allocation); } - source.unlink(concepts::allocates(), allocation); - allocation.unlink(concepts::allocator(), source); - if (allocation.linked(concepts::allocator())) { continue; } - - auto it = index().find(allocation); - if (it != index().end()) { - forgotten.insert(index().extract(it)); - } - } - try { - for (auto allocation : ours ) { - for (auto suballocation : allocation.getAll(concepts::allocates())) { - // check for this link to find subgroups - throw still_referenced_by(allocation, suballocation); - } - } - for (auto ghost : ours) { - concept * referenced = intellect::level0::referenced(ghost, source); - if (referenced) { - throw still_referenced_by(ghost, referenced); - } - } - } catch(...) { - // NOTE: this doesn't rebuild deallocated subgroups, but that could be done - // by returning them. - index().merge(forgotten); - for (auto allocation : ours) { - source.link(concepts::allocates(), allocation); - allocation.link(concepts::allocator(), source); - } - throw; - } - - // concepts in forgotten will be deallocated when they leave scope - // note: scoped allocation is just a plan to forget (at the end of a { } block) -} - -void dealloc(ref r, ref source) -{ - auto it = index().find(r); - if (it == index().end()) { throw no_such_concept(r); } - - source.unlink(concepts::allocates(), r); - r.unlink(concepts::allocator(), source); - if (r.linked(concepts::allocator())) { return; } - - try { - if (r.crucial()) { throw crucial_concept(r); } - dealloc_from(r); - concept * referenced = intellect::level0::referenced(r, source); - if (referenced) { - throw still_referenced_by(r, referenced); - } - - index().erase(it); - } catch(...) { - source.link(concepts::allocates(), r); - r.link(concepts::allocator(), source); - throw; - } -} - -std::size_t allocated() -{ - return index().size(); -} - -} -} |