88 lines
5.4 KiB
C++
88 lines
5.4 KiB
C++
#pragma once
|
|
#include <vector>
|
|
#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<BaseTree>
|
|
{
|
|
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<unsigned8>& pool) override;
|
|
bool VerifyPool(std::vector<unsigned8>& 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<unsigned8> CalculatePointerSizesPerLevel(const BaseTree* tree, const std::vector<size_t>& parentsPerNode, const std::vector<bool>& useVirtualNodes) const;
|
|
std::vector<size_t> CalculateVirtualNodesPerLevel(const BaseTree* tree, const std::vector<size_t>& parentsPerNode) const;
|
|
std::vector<size_t> CalculateFullNodesPerLevel(const BaseTree* tree) const;
|
|
std::vector<size_t> 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<size_t> CalculateSizePerLevel(const BaseTree* tree, const std::vector<unsigned8> pointerSizesPerLevel, const std::vector<size_t>& parentsPerNode, const std::vector<bool>& usesVirtualNodes) const;
|
|
std::vector<size_t> CalculateApproximateSizePerLevelVirtualNodes(const BaseTree* tree, const std::vector<size_t>& parentsPerNode) const;
|
|
std::vector<size_t> CalculateApproximateSizePerLevelStandardNodes(const BaseTree* tree) const;
|
|
std::vector<bool> DecideVirtualPointersPerLevel(const BaseTree* tree, const std::vector<size_t>& 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<unsigned8>& pointerSizesPerLevel) const;
|
|
size_t GetVirtualNodeSize(const BaseTree* tree, const unsigned8& level, const std::vector<unsigned8>& pointerSizesPerLevel) const;
|
|
size_t GetNormalNodeSize(const BaseTree* tree, const unsigned32& nodeId, const std::vector<unsigned8>& pointerSizesPerLevel, std::vector<unsigned8>& additionalPointerInfoSizesPerLevel, const bool& includingAdditionalPointerInfo) const;
|
|
|
|
inline bool HasAdditionalBytesPerNode(const BaseTree* tree) const
|
|
{
|
|
std::vector<unsigned8> 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<unsigned8> 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<unsigned8>& pool, const size_t& offset) const;
|
|
|
|
void WriteNormalNode(const BaseTree* tree, const unsigned32& nodeId, const unsigned8& additionalNodeBytes, const unsigned8& pointerSize, const std::vector<size_t>& nodePointers, const size_t& nextLevelOffset, std::vector<unsigned8>& pool, const size_t& offset) const;
|
|
|
|
void WriteAdditionalPointerInfo(const BaseTree* tree, const unsigned32& nodeId, const ChildIndex& childId, const unsigned8& additionalPointerBytes, std::vector<unsigned8>& 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); }
|
|
};
|
|
}; |