Use FileWriter for writing LeafNode data to improve error handling.

This commit is contained in:
Daniel Patterson 2017-05-27 22:37:53 -07:00 committed by Patrick Niklaus
parent 6d2353c302
commit 382a5cebab

View File

@ -19,7 +19,6 @@
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/format.hpp> #include <boost/format.hpp>
#include <boost/iostreams/device/mapped_file.hpp> #include <boost/iostreams/device/mapped_file.hpp>
@ -204,14 +203,16 @@ class StaticRTree
} }
}); });
// open leaf file std::vector<TreeNode> tree_nodes_in_level;
boost::filesystem::ofstream leaf_node_file(leaf_node_filename, std::ios::binary);
// sort the hilbert-value representatives // sort the hilbert-value representatives
tbb::parallel_sort(input_wrapper_vector.begin(), input_wrapper_vector.end()); tbb::parallel_sort(input_wrapper_vector.begin(), input_wrapper_vector.end());
std::vector<TreeNode> tree_nodes_in_level;
// pack M elements into leaf node, write to leaf file and add child index to the parent node {
storage::io::FileWriter leaf_node_file(leaf_node_filename,
storage::io::FileWriter::HasNoFingerprint);
// pack M elements into leaf node, write to leaf file and add child index to the parent
// node
uint64_t wrapped_element_index = 0; uint64_t wrapped_element_index = 0;
for (std::uint32_t node_index = 0; wrapped_element_index < element_count; ++node_index) for (std::uint32_t node_index = 0; wrapped_element_index < element_count; ++node_index)
{ {
@ -238,10 +239,14 @@ class StaticRTree
Coordinate projected_v{ Coordinate projected_v{
web_mercator::fromWGS84(Coordinate{m_coordinate_list[object.v]})}; web_mercator::fromWGS84(Coordinate{m_coordinate_list[object.v]})};
BOOST_ASSERT(std::abs(toFloating(projected_u.lon).operator double()) <= 180.); BOOST_ASSERT(std::abs(toFloating(projected_u.lon).operator double()) <=
BOOST_ASSERT(std::abs(toFloating(projected_u.lat).operator double()) <= 180.); 180.);
BOOST_ASSERT(std::abs(toFloating(projected_v.lon).operator double()) <= 180.); BOOST_ASSERT(std::abs(toFloating(projected_u.lat).operator double()) <=
BOOST_ASSERT(std::abs(toFloating(projected_v.lat).operator double()) <= 180.); 180.);
BOOST_ASSERT(std::abs(toFloating(projected_v.lon).operator double()) <=
180.);
BOOST_ASSERT(std::abs(toFloating(projected_v.lat).operator double()) <=
180.);
rectangle.min_lon = rectangle.min_lon =
std::min(rectangle.min_lon, std::min(projected_u.lon, projected_v.lon)); std::min(rectangle.min_lon, std::min(projected_u.lon, projected_v.lon));
@ -264,13 +269,12 @@ class StaticRTree
current_leaf.minimum_bounding_rectangle); current_leaf.minimum_bounding_rectangle);
// write leaf_node to leaf node file // write leaf_node to leaf node file
leaf_node_file.write((char *)&current_leaf, sizeof(current_leaf)); leaf_node_file.WriteOne(current_leaf);
} }
tree_nodes_in_level.emplace_back(current_node); tree_nodes_in_level.emplace_back(current_node);
} }
leaf_node_file.flush(); }
leaf_node_file.close();
std::uint32_t processing_level = 0; std::uint32_t processing_level = 0;
while (1 < tree_nodes_in_level.size()) while (1 < tree_nodes_in_level.size())
@ -332,6 +336,7 @@ class StaticRTree
} }
}); });
{
// open tree file // open tree file
storage::io::FileWriter tree_node_file(tree_node_filename, storage::io::FileWriter tree_node_file(tree_node_filename,
storage::io::FileWriter::GenerateFingerprint); storage::io::FileWriter::GenerateFingerprint);
@ -341,6 +346,7 @@ class StaticRTree
tree_node_file.WriteOne(size_of_tree); tree_node_file.WriteOne(size_of_tree);
tree_node_file.WriteFrom(&m_search_tree[0], size_of_tree); tree_node_file.WriteFrom(&m_search_tree[0], size_of_tree);
}
MapLeafNodesFile(leaf_node_filename); MapLeafNodesFile(leaf_node_filename);
} }
@ -379,6 +385,24 @@ class StaticRTree
std::size_t num_leaves = m_leaves_region.size() / sizeof(LeafNode); std::size_t num_leaves = m_leaves_region.size() / sizeof(LeafNode);
auto data_ptr = m_leaves_region.data(); auto data_ptr = m_leaves_region.data();
BOOST_ASSERT(reinterpret_cast<uintptr_t>(data_ptr) % alignof(LeafNode) == 0); BOOST_ASSERT(reinterpret_cast<uintptr_t>(data_ptr) % alignof(LeafNode) == 0);
#ifndef NDEBUG
// Find the maximum leaf node ID and make sure we have that many from our file
BOOST_ASSERT(m_search_tree.size() > 0);
std::uint32_t max_leaf_node_id = 0;
// Search in reverse, the bottom of the tree is at the end of the array
for (auto iter = m_search_tree.rbegin(); iter != m_search_tree.rend(); iter++)
{
// If we find a non-leaf node, we can quit, we've seen the
// bottom level of the tree
if (iter->child_count > 0 && !iter->children[0].is_leaf)
break;
for (std::uint32_t i = 0; i < iter->child_count; ++i)
{
max_leaf_node_id = std::max(max_leaf_node_id, iter->children[i].index);
}
}
BOOST_ASSERT(max_leaf_node_id == num_leaves - 1);
#endif
m_leaves.reset(reinterpret_cast<const LeafNode *>(data_ptr), num_leaves); m_leaves.reset(reinterpret_cast<const LeafNode *>(data_ptr), num_leaves);
} }
catch (const std::exception &exc) catch (const std::exception &exc)