#pragma once #include #include "BasePoolBuilder.h" #include "../Octree/BaseTree.h" class BoolArray; // Virtual Node Pool is a node pool in which the children of a node are stored consequetively in memory. // Nodes that are reused (because of the DAG structure) will appear as so-called "virtual nodes". // These nodes are basically only a pointer to the actual node and do appear consecutively in memory to the ordinary nodes. // This has the advantage that only 1 pointer is needed per node (a pointer to the first child). class VirtualNodePoolBuilder : public BasePoolBuilder { public: VirtualNodePoolBuilder() { mIsBuilding = false; } virtual ~VirtualNodePoolBuilder() override {} std::string GetFullFileName(const std::string& fileName) const override; size_t GetPoolSize(const BaseTree* tree) override; bool BuildPool(const BaseTree* tree, std::vector& pool) override; bool VerifyPool(std::vector& pool, const unsigned8& depth) const override; private: // Returns the size of a node without the pointers (but with the additional pointer information if needed) std::vector CalculatePointerSizesPerLevel(const BaseTree* tree, const std::vector& parentsPerNode, const std::vector& useVirtualNodes) const; std::vector CalculateVirtualNodesPerLevel(const BaseTree* tree, const std::vector& parentsPerNode) const; std::vector CalculateFullNodesPerLevel(const BaseTree* tree) const; std::vector CalculatePointersToPerLevel(const BaseTree* tree) const; size_t CalculateSizeOfLevel(const BaseTree* tree, const unsigned8& level, const size_t& virtualNodesThisLevel, const size_t& fullNodesThisLevel, const size_t& pointersToThisLevel, const size_t& pointersFromThisLevel, const unsigned8& pointerSizeToThisLevel, const unsigned8& pointerSizeFromThisLevel, const unsigned8& additionalBytesPointersToThisLevel, const unsigned8& additionalBytesPointersFromThisLevel, const bool& useVirtualNodesThisLevel, const bool& useVirtualNodesPreviousLevel) const; std::vector CalculateSizePerLevel(const BaseTree* tree, const std::vector pointerSizesPerLevel, const std::vector& parentsPerNode, const std::vector& usesVirtualNodes) const; std::vector CalculateApproximateSizePerLevelVirtualNodes(const BaseTree* tree, const std::vector& parentsPerNode) const; std::vector CalculateApproximateSizePerLevelStandardNodes(const BaseTree* tree) const; std::vector DecideVirtualPointersPerLevel(const BaseTree* tree, const std::vector& parentsPerNode) const; size_t CalculatePoolInfoSize(const BaseTree* tree); size_t GetFullNodeSize(const BaseTree* tree, const unsigned8& level, const unsigned8& pointerSize) const; size_t GetVirtualNodeSize(const BaseTree* tree, const unsigned8& level, const unsigned8& pointerSize) const; size_t GetFullNodeSize(const BaseTree* tree, const unsigned8& level, const std::vector& pointerSizesPerLevel) const; size_t GetVirtualNodeSize(const BaseTree* tree, const unsigned8& level, const std::vector& pointerSizesPerLevel) const; size_t GetNormalNodeSize(const BaseTree* tree, const unsigned32& nodeId, const std::vector& pointerSizesPerLevel, std::vector& additionalPointerInfoSizesPerLevel, const bool& includingAdditionalPointerInfo) const; inline bool HasAdditionalBytesPerNode(const BaseTree* tree) const { std::vector additionalBytesPerNode = tree->GetAdditionalBytesPerNode(); bool hasAdditionalBytesPerNode = false; for (auto abpn : additionalBytesPerNode) if (abpn != 0) hasAdditionalBytesPerNode = true; return hasAdditionalBytesPerNode; } inline bool HasAdditionalBytesPerPointer(const BaseTree* tree) const { std::vector additionalBytesPerPointer = tree->GetAdditionalBytesPerPointer(); bool hasAdditionalBytesPerPointer = false; for (auto abpp : additionalBytesPerPointer) if (abpp != 0) hasAdditionalBytesPerPointer = true; return hasAdditionalBytesPerPointer; } void WriteFullNode(const BaseTree* tree, const unsigned32& nodeId, const unsigned32& childPointer, const unsigned8& childPointerSize, BoolArray& writtenNodes, const unsigned8& additionalNodeBytes, std::vector& pool, const size_t& offset) const; void WriteNormalNode(const BaseTree* tree, const unsigned32& nodeId, const unsigned8& additionalNodeBytes, const unsigned8& pointerSize, const std::vector& nodePointers, const size_t& nextLevelOffset, std::vector& pool, const size_t& offset) const; void WriteAdditionalPointerInfo(const BaseTree* tree, const unsigned32& nodeId, const ChildIndex& childId, const unsigned8& additionalPointerBytes, std::vector& pool, const size_t& offset) const; unsigned8 GetVMask(const BaseTree* tree, const unsigned32& nodeId, BoolArray& writtenNodes) const; bool mIsBuilding; enum NodeType { VIRTUAL, FULL, NORMAL }; struct NodeToWrite { unsigned32 nodeId; unsigned8 level; NodeType type; ChildIndex childIndexOfParent; unsigned32 parentId; NodeToWrite(const unsigned32& nodeId, const unsigned8& level, const NodeType& type, const unsigned32& parentId, const ChildIndex childOfParent) : nodeId(nodeId), level(level), type(type), childIndexOfParent(childOfParent), parentId(parentId) {} const Node* GetNode(const BaseTree* tree) { return tree->GetNode(nodeId); } }; };