HTTP API: Allow binary downloads and headers (#8573)
[oweals/minetest.git] / src / util / areastore.h
index dee1f8bab4f6e3274d327a7a0efe77d536c40339..24840210e4cb57815f0cd59a1dee53efa3f39853 100644 (file)
@@ -17,8 +17,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
-#ifndef AREA_STORE_H_
-#define AREA_STORE_H_
+#pragma once
 
 #include "irr_v3d.h"
 #include "noise.h" // for PcgRandom
@@ -38,121 +37,143 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 
 struct Area {
-       Area() {}
-       Area(const v3s16 &mine, const v3s16 &maxe)
+       Area() = default;
+
+       Area(const v3s16 &mine, const v3s16 &maxe) :
+               minedge(mine), maxedge(maxe)
        {
-               minedge = mine;
-               maxedge = maxe;
                sortBoxVerticies(minedge, maxedge);
        }
 
-       u32 id;
-       v3s16 minedge;
-       v3s16 maxedge;
+       u32 id = U32_MAX;
+       v3s16 minedge, maxedge;
        std::string data;
 };
 
 
 class AreaStore {
-protected:
-       void invalidateCache();
-       virtual void getAreasForPosImpl(std::vector<Area *> *result, v3s16 pos) = 0;
-       u32 getNextId() { return m_next_id++; }
-
-       // TODO change to unordered_map when we can
-       std::map<u32, Area> areas_map;
 public:
-       // Updates the area's ID
-       virtual bool insertArea(Area *a) = 0;
+       AreaStore() :
+               m_res_cache(1000, &cacheMiss, this)
+       {}
+
+       virtual ~AreaStore() = default;
+
+       static AreaStore *getOptimalImplementation();
+
        virtual void reserve(size_t count) {};
+       size_t size() const { return areas_map.size(); }
+
+       /// Add an area to the store.
+       /// Updates the area's ID if it hasn't already been set.
+       /// @return Whether the area insertion was successful.
+       virtual bool insertArea(Area *a) = 0;
+
+       /// Removes an area from the store by ID.
+       /// @return Whether the area was in the store and removed.
        virtual bool removeArea(u32 id) = 0;
+
+       /// Finds areas that the passed position is contained in.
+       /// Stores output in passed vector.
        void getAreasForPos(std::vector<Area *> *result, v3s16 pos);
+
+       /// Finds areas that are completely contained inside the area defined
+       /// by the passed edges.  If @p accept_overlap is true this finds any
+       /// areas that intersect with the passed area at any point.
        virtual void getAreasInArea(std::vector<Area *> *result,
                v3s16 minedge, v3s16 maxedge, bool accept_overlap) = 0;
 
-#if 0
-       // calls a passed function for every stored area, until the
-       // callback returns true. If that happens, it returns true,
-       // if the search is exhausted, it returns false
-       virtual bool forEach(bool (*callback)(void *args, Area *a), void *args) const = 0;
-#endif
-
-       virtual ~AreaStore()
-       {}
-
-       AreaStore() :
-               m_cacheblock_radius(64),
-               m_res_cache(1000, &cacheMiss, this),
-               m_next_id(0),
-               m_cache_enabled(true)
-       {
-       }
-
+       /// Sets cache parameters.
        void setCacheParams(bool enabled, u8 block_radius, size_t limit);
 
+       /// Returns a pointer to the area coresponding to the passed ID,
+       /// or NULL if it doesn't exist.
        const Area *getArea(u32 id) const;
-       u16 size() const;
 
-       static AreaStore *getOptimalImplementation();
-#if 0
-       bool deserialize(std::istream &is);
+       /// Serializes the store's areas to a binary ostream.
        void serialize(std::ostream &is) const;
-#endif
+
+       /// Deserializes the Areas from a binary istream.
+       /// This does not currently clear the AreaStore before adding the
+       /// areas, making it possible to deserialize multiple serialized
+       /// AreaStores.
+       void deserialize(std::istream &is);
+
+protected:
+       /// Invalidates the getAreasForPos cache.
+       /// Call after adding or removing an area.
+       void invalidateCache();
+
+       /// Implementation of getAreasForPos.
+       /// getAreasForPos calls this if the cache is disabled.
+       virtual void getAreasForPosImpl(std::vector<Area *> *result, v3s16 pos) = 0;
+
+       /// Returns the next area ID and increments it.
+       u32 getNextId() { return m_next_id++; }
+
+       // Note: This can't be an unordered_map, since all
+       // references would be invalidated on rehash.
+       typedef std::map<u32, Area> AreaMap;
+       AreaMap areas_map;
+
 private:
+       /// Called by the cache when a value isn't found in the cache.
        static void cacheMiss(void *data, const v3s16 &mpos, std::vector<Area *> *dest);
-       u8 m_cacheblock_radius; // if you modify this, call invalidateCache()
+
+       bool m_cache_enabled = true;
+       /// Range, in nodes, of the getAreasForPos cache.
+       /// If you modify this, call invalidateCache()
+       u8 m_cacheblock_radius = 64;
        LRUCache<v3s16, std::vector<Area *> > m_res_cache;
-       u32 m_next_id;
-       bool m_cache_enabled;
+
+       u32 m_next_id = 0;
 };
 
 
 class VectorAreaStore : public AreaStore {
-protected:
-       virtual void getAreasForPosImpl(std::vector<Area *> *result, v3s16 pos);
 public:
+       virtual void reserve(size_t count) { m_areas.reserve(count); }
        virtual bool insertArea(Area *a);
-       virtual void reserve(size_t count);
        virtual bool removeArea(u32 id);
        virtual void getAreasInArea(std::vector<Area *> *result,
                v3s16 minedge, v3s16 maxedge, bool accept_overlap);
-       // virtual bool forEach(bool (*callback)(void *args, Area *a), void *args) const;
+
+protected:
+       virtual void getAreasForPosImpl(std::vector<Area *> *result, v3s16 pos);
+
 private:
        std::vector<Area *> m_areas;
 };
 
+
 #if USE_SPATIAL
 
 class SpatialAreaStore : public AreaStore {
-protected:
-       virtual void getAreasForPosImpl(std::vector<Area *> *result, v3s16 pos);
 public:
        SpatialAreaStore();
+       virtual ~SpatialAreaStore();
+
        virtual bool insertArea(Area *a);
        virtual bool removeArea(u32 id);
        virtual void getAreasInArea(std::vector<Area *> *result,
                v3s16 minedge, v3s16 maxedge, bool accept_overlap);
-       // virtual bool forEach(bool (*callback)(void *args, Area *a), void *args) const;
 
-       virtual ~SpatialAreaStore();
+protected:
+       virtual void getAreasForPosImpl(std::vector<Area *> *result, v3s16 pos);
+
 private:
-       SpatialIndex::ISpatialIndex *m_tree;
-       SpatialIndex::IStorageManager *m_storagemanager;
+       SpatialIndex::ISpatialIndex *m_tree = nullptr;
+       SpatialIndex::IStorageManager *m_storagemanager = nullptr;
 
        class VectorResultVisitor : public SpatialIndex::IVisitor {
-       private:
-               SpatialAreaStore *m_store;
-               std::vector<Area *> *m_result;
        public:
-               VectorResultVisitor(std::vector<Area *> *result, SpatialAreaStore *store)
-               {
-                       m_store = store;
-                       m_result = result;
-               }
+               VectorResultVisitor(std::vector<Area *> *result, SpatialAreaStore *store) :
+                       m_store(store),
+                       m_result(result)
+               {}
+               ~VectorResultVisitor() {}
 
-               virtual void visitNode(const SpatialIndex::INode &in)
-               {
-               }
+               virtual void visitNode(const SpatialIndex::INode &in) {}
 
                virtual void visitData(const SpatialIndex::IData &in)
                {
@@ -169,10 +190,10 @@ private:
                                visitData(*(v[i]));
                }
 
-               ~VectorResultVisitor() {}
+       private:
+               SpatialAreaStore *m_store = nullptr;
+               std::vector<Area *> *m_result = nullptr;
        };
 };
 
-#endif
-
-#endif // AREA_STORE_H_
+#endif // USE_SPATIAL