diff options
author | ShadowNinja <shadowninja@minetest.net> | 2015-10-29 23:26:03 -0400 |
---|---|---|
committer | ShadowNinja <shadowninja@minetest.net> | 2016-03-07 16:33:20 -0500 |
commit | 0079887b645e0ee441bd2cfcd7874a1148fdd656 (patch) | |
tree | 2de01cef8f7ceb82f29cc38362dbdbb5eb391565 /src/areastore.cpp | |
parent | f021db724301f082cbde719afb2405ec1d8cf82c (diff) | |
download | minetest-0079887b645e0ee441bd2cfcd7874a1148fdd656.tar.gz minetest-0079887b645e0ee441bd2cfcd7874a1148fdd656.tar.bz2 minetest-0079887b645e0ee441bd2cfcd7874a1148fdd656.zip |
Move AreaStore to util
Diffstat (limited to 'src/areastore.cpp')
-rw-r--r-- | src/areastore.cpp | 338 |
1 files changed, 0 insertions, 338 deletions
diff --git a/src/areastore.cpp b/src/areastore.cpp deleted file mode 100644 index b1b5c0db4..000000000 --- a/src/areastore.cpp +++ /dev/null @@ -1,338 +0,0 @@ -/* -Minetest -Copyright (C) 2015 est31 <mtest31@outlook.com> - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation; either version 2.1 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License along -with this program; if not, write to the Free Software Foundation, Inc., -51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "areastore.h" -#include "util/serialize.h" -#include "util/container.h" - -#if USE_SPATIAL - #include <spatialindex/SpatialIndex.h> - #include <spatialindex/RTree.h> - #include <spatialindex/Point.h> -#endif - -#define AST_SMALLER_EQ_AS(p, q) (((p).X <= (q).X) && ((p).Y <= (q).Y) && ((p).Z <= (q).Z)) - -#define AST_OVERLAPS_IN_DIMENSION(amine, amaxe, b, d) \ - (!(((amine).d > (b)->maxedge.d) || ((amaxe).d < (b)->minedge.d))) - -#define AST_CONTAINS_PT(a, p) (AST_SMALLER_EQ_AS((a)->minedge, (p)) && \ - AST_SMALLER_EQ_AS((p), (a)->maxedge)) - -#define AST_CONTAINS_AREA(amine, amaxe, b) \ - (AST_SMALLER_EQ_AS((amine), (b)->minedge) \ - && AST_SMALLER_EQ_AS((b)->maxedge, (amaxe))) - -#define AST_AREAS_OVERLAP(amine, amaxe, b) \ - (AST_OVERLAPS_IN_DIMENSION((amine), (amaxe), (b), X) && \ - AST_OVERLAPS_IN_DIMENSION((amine), (amaxe), (b), Y) && \ - AST_OVERLAPS_IN_DIMENSION((amine), (amaxe), (b), Z)) - -u16 AreaStore::size() const -{ - return areas_map.size(); -} - -const Area *AreaStore::getArea(u32 id) const -{ - const Area *res = NULL; - std::map<u32, Area>::const_iterator itr = areas_map.find(id); - if (itr != areas_map.end()) { - res = &itr->second; - } - return res; -} - -#if 0 -Currently, serialisation is commented out. This is because of multiple reasons: -1. Why do we store the areastore into a file, why not into the database? -2. We don't use libspatial's serialisation, but we should, or perhaps not, because - it would remove the ability to switch. Perhaps write migration routines? -3. Various things need fixing, e.g. the size is serialized as - c++ implementation defined size_t -bool AreaStore::deserialize(std::istream &is) -{ - u8 ver = readU8(is); - if (ver != 1) - return false; - u16 count_areas = readU16(is); - for (u16 i = 0; i < count_areas; i++) { - // deserialize an area - Area a; - a.id = readU32(is); - a.minedge = readV3S16(is); - a.maxedge = readV3S16(is); - a.datalen = readU16(is); - a.data = new char[a.datalen]; - is.read((char *) a.data, a.datalen); - insertArea(a); - } - return true; -} - - -static bool serialize_area(void *ostr, Area *a) -{ - std::ostream &os = *((std::ostream *) ostr); - writeU32(os, a->id); - writeV3S16(os, a->minedge); - writeV3S16(os, a->maxedge); - writeU16(os, a->datalen); - os.write(a->data, a->datalen); - - return false; -} - - -void AreaStore::serialize(std::ostream &os) const -{ - // write initial data - writeU8(os, 1); // serialisation version - writeU16(os, areas_map.size()); //DANGER: not platform independent - forEach(&serialize_area, &os); -} - -#endif - -void AreaStore::invalidateCache() -{ - if (m_cache_enabled) { - m_res_cache.invalidate(); - } -} - -void AreaStore::setCacheParams(bool enabled, u8 block_radius, size_t limit) -{ - m_cache_enabled = enabled; - m_cacheblock_radius = MYMAX(block_radius, 16); - m_res_cache.setLimit(MYMAX(limit, 20)); - invalidateCache(); -} - -void AreaStore::cacheMiss(void *data, const v3s16 &mpos, std::vector<Area *> *dest) -{ - AreaStore *as = (AreaStore *)data; - u8 r = as->m_cacheblock_radius; - - // get the points at the edges of the mapblock - v3s16 minedge(mpos.X * r, mpos.Y * r, mpos.Z * r); - v3s16 maxedge( - minedge.X + r - 1, - minedge.Y + r - 1, - minedge.Z + r - 1); - - as->getAreasInArea(dest, minedge, maxedge, true); - - /* infostream << "Cache miss with " << dest->size() << " areas, between (" - << minedge.X << ", " << minedge.Y << ", " << minedge.Z - << ") and (" - << maxedge.X << ", " << maxedge.Y << ", " << maxedge.Z - << ")" << std::endl; // */ -} - -void AreaStore::getAreasForPos(std::vector<Area *> *result, v3s16 pos) -{ - if (m_cache_enabled) { - v3s16 mblock = getContainerPos(pos, m_cacheblock_radius); - const std::vector<Area *> *pre_list = m_res_cache.lookupCache(mblock); - - size_t s_p_l = pre_list->size(); - for (size_t i = 0; i < s_p_l; i++) { - Area *b = (*pre_list)[i]; - if (AST_CONTAINS_PT(b, pos)) { - result->push_back(b); - } - } - } else { - return getAreasForPosImpl(result, pos); - } -} - - -//// -// VectorAreaStore -//// - - -bool VectorAreaStore::insertArea(Area *a) -{ - a->id = getNextId(); - std::pair<std::map<u32, Area>::iterator, bool> res = - areas_map.insert(std::make_pair(a->id, *a)); - if (!res.second) - // ID is not unique - return false; - m_areas.push_back(&res.first->second); - invalidateCache(); - return true; -} - -void VectorAreaStore::reserve(size_t count) -{ - m_areas.reserve(count); -} - -bool VectorAreaStore::removeArea(u32 id) -{ - std::map<u32, Area>::iterator itr = areas_map.find(id); - if (itr != areas_map.end()) { - size_t msiz = m_areas.size(); - for (size_t i = 0; i < msiz; i++) { - Area * b = m_areas[i]; - if (b->id == id) { - areas_map.erase(itr); - m_areas.erase(m_areas.begin() + i); - invalidateCache(); - return true; - } - } - // we should never get here, it means we did find it in map, - // but not in the vector - } - return false; -} - -void VectorAreaStore::getAreasForPosImpl(std::vector<Area *> *result, v3s16 pos) -{ - size_t msiz = m_areas.size(); - for (size_t i = 0; i < msiz; i++) { - Area *b = m_areas[i]; - if (AST_CONTAINS_PT(b, pos)) { - result->push_back(b); - } - } -} - -void VectorAreaStore::getAreasInArea(std::vector<Area *> *result, - v3s16 minedge, v3s16 maxedge, bool accept_overlap) -{ - size_t msiz = m_areas.size(); - for (size_t i = 0; i < msiz; i++) { - Area * b = m_areas[i]; - if (accept_overlap ? AST_AREAS_OVERLAP(minedge, maxedge, b) : - AST_CONTAINS_AREA(minedge, maxedge, b)) { - result->push_back(b); - } - } -} - -#if 0 -bool VectorAreaStore::forEach(bool (*callback)(void *args, Area *a), void *args) const -{ - size_t msiz = m_areas.size(); - for (size_t i = 0; i < msiz; i++) { - if (callback(args, m_areas[i])) { - return true; - } - } - return false; -} -#endif - -#if USE_SPATIAL - -static inline SpatialIndex::Region get_spatial_region(const v3s16 minedge, - const v3s16 maxedge) -{ - const double p_low[] = {(double)minedge.X, - (double)minedge.Y, (double)minedge.Z}; - const double p_high[] = {(double)maxedge.X, (double)maxedge.Y, - (double)maxedge.Z}; - return SpatialIndex::Region(p_low, p_high, 3); -} - -static inline SpatialIndex::Point get_spatial_point(const v3s16 pos) -{ - const double p[] = {(double)pos.X, (double)pos.Y, (double)pos.Z}; - return SpatialIndex::Point(p, 3); -} - - -bool SpatialAreaStore::insertArea(Area *a) -{ - a->id = getNextId(); - if (!areas_map.insert(std::make_pair(a->id, *a)).second) - // ID is not unique - return false; - m_tree->insertData(0, NULL, get_spatial_region(a->minedge, a->maxedge), a->id); - invalidateCache(); - return true; -} - -bool SpatialAreaStore::removeArea(u32 id) -{ - std::map<u32, Area>::iterator itr = areas_map.find(id); - if (itr != areas_map.end()) { - Area *a = &itr->second; - bool result = m_tree->deleteData(get_spatial_region(a->minedge, - a->maxedge), id); - invalidateCache(); - return result; - } else { - return false; - } -} - -void SpatialAreaStore::getAreasForPosImpl(std::vector<Area *> *result, v3s16 pos) -{ - VectorResultVisitor visitor(result, this); - m_tree->pointLocationQuery(get_spatial_point(pos), visitor); -} - -void SpatialAreaStore::getAreasInArea(std::vector<Area *> *result, - v3s16 minedge, v3s16 maxedge, bool accept_overlap) -{ - VectorResultVisitor visitor(result, this); - if (accept_overlap) { - m_tree->intersectsWithQuery(get_spatial_region(minedge, maxedge), - visitor); - } else { - m_tree->containsWhatQuery(get_spatial_region(minedge, maxedge), visitor); - } -} - -#if 0 -bool SpatialAreaStore::forEach(bool (*callback)(void *args, Area *a), void *args) const -{ - // TODO ?? (this is only needed for serialisation, but libspatial has its own serialisation) - return false; -} -#endif - -SpatialAreaStore::~SpatialAreaStore() -{ - delete m_tree; -} - -SpatialAreaStore::SpatialAreaStore() -{ - m_storagemanager = - SpatialIndex::StorageManager::createNewMemoryStorageManager(); - SpatialIndex::id_type id; - m_tree = SpatialIndex::RTree::createNewRTree( - *m_storagemanager, - .7, // Fill factor - 100, // Index capacity - 100, // Leaf capacity - 3, // dimension :) - SpatialIndex::RTree::RV_RSTAR, - id); -} - -#endif |