diff --git a/include/mapnik/mapped_memory_cache.hpp b/include/mapnik/mapped_memory_cache.hpp index 6b6102c4e..c67d63ad7 100644 --- a/include/mapnik/mapped_memory_cache.hpp +++ b/include/mapnik/mapped_memory_cache.hpp @@ -52,6 +52,8 @@ public: void clear(); }; +extern template class MAPNIK_DECL singleton; + } #endif // MAPNIK_MAPPED_MEMORY_CACHE_HPP diff --git a/src/mapped_memory_cache.cpp b/src/mapped_memory_cache.cpp index db4fce897..f35a379af 100644 --- a/src/mapped_memory_cache.cpp +++ b/src/mapped_memory_cache.cpp @@ -37,6 +37,8 @@ namespace mapnik { +template class singleton; + void mapped_memory_cache::clear() { #ifdef MAPNIK_THREADSAFE @@ -58,6 +60,7 @@ boost::optional mapped_memory_cache::find(std::string const& #ifdef MAPNIK_THREADSAFE std::lock_guard lock(mutex_); #endif + using iterator_type = std::unordered_map::const_iterator; boost::optional result; iterator_type itr = cache_.find(uri); @@ -76,7 +79,7 @@ boost::optional mapped_memory_cache::find(std::string const& result.reset(region); if (update_cache) { - cache_.emplace(uri,*result); + cache_.emplace(uri, *result); } return result; } diff --git a/test/unit/datasource/shapeindex.cpp b/test/unit/datasource/shapeindex.cpp index a0eef2d02..51f47ac7c 100644 --- a/test/unit/datasource/shapeindex.cpp +++ b/test/unit/datasource/shapeindex.cpp @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -36,6 +37,9 @@ namespace { std::size_t count_shapefile_features(std::string const& filename) { +#if defined(MAPNIK_MEMORY_MAPPED_FILE) + mapnik::mapped_memory_cache::instance().clear(); +#endif mapnik::parameters params; params["type"] = "shape"; params["file"] = filename; @@ -93,31 +97,41 @@ TEST_CASE("invalid shapeindex") { SECTION("Invalid index") { - std::string path = "test/data/shp/boundaries.shp"; - std::string index_path = path.substr(0, path.rfind(".")) + ".index"; - // remove *.index if present - if (mapnik::util::exists(index_path)) + for (auto val : {std::make_tuple(true, std::string("mapnik-invalid-index.................")), // invalid header + std::make_tuple(false, std::string("mapnik-index................."))}) // valid header + invalid index { - mapnik::util::remove(index_path); - } - // count features + std::string path = "test/data/shp/boundaries.shp"; + std::string index_path = path.substr(0, path.rfind(".")) + ".index"; + // remove *.index if present + if (mapnik::util::exists(index_path)) + { + mapnik::util::remove(index_path); + } + // count features - std::size_t feature_count = count_shapefile_features(path); + std::size_t feature_count = count_shapefile_features(path); - // create invalid index - std::ofstream index(index_path.c_str(), std::ios::binary); - std::string buf("mapnik-invalid-index................."); - index.write(buf.c_str(), buf.size()); - index.close(); + // create index + std::ofstream index(index_path.c_str(), std::ios::binary); + index.write(std::get<1>(val).c_str(), std::get<1>(val).size()); + index.close(); - // count features - std::size_t feature_count_indexed = count_shapefile_features(path); - // ensure number of features are the same - REQUIRE(feature_count == feature_count_indexed); - // remove *.index if present - if (mapnik::util::exists(index_path)) - { - mapnik::util::remove(index_path); + // count features + std::size_t feature_count_indexed = count_shapefile_features(path); + if (std::get<0>(val)) // fallback to un-indexed access + { + // ensure number of features are the same + CHECK(feature_count == feature_count_indexed); + } + else // the header is valid but index file itself is not - expect datasource to fail and return 0 features. + { + CHECK(feature_count_indexed == 0); + } + // remove *.index if present + if (mapnik::util::exists(index_path)) + { + mapnik::util::remove(index_path); + } } } }