/** * Tell the Collector that you are interested in this relation * and want it kept until all members have been assembled and * it is handed back to you. * * The relation is copied and stored in a buffer inside the * collector. */ void add_relation(const osmium::Relation& relation) { const size_t offset = m_relations_buffer.committed(); m_relations_buffer.add_item(relation); RelationMeta relation_meta(offset); int n = 0; for (auto& member : m_relations_buffer.get<osmium::Relation>(offset).members()) { if (static_cast<TCollector*>(this)->keep_member(relation_meta, member)) { member_meta(member.type()).emplace_back(member.ref(), m_relations.size(), n); relation_meta.increment_need_members(); } else { member.ref(0); // set member id to zero to indicate we are not interested } ++n; } assert(offset == m_relations_buffer.committed()); if (relation_meta.has_all_members()) { m_relations_buffer.rollback(); } else { m_relations_buffer.commit(); m_relations.push_back(std::move(relation_meta)); // std::cerr << "added relation id=" << relation.id() << "\n"; } }
/** * Decide whether to purge removed members and then do it. * * Currently the purging is done every thousand calls. * This could probably be improved upon. */ void possibly_purge_removed_members() { ++m_count_complete; if (m_count_complete > 10000) { // XXX const size_t size_before = m_members_buffer.committed(); m_members_buffer.purge_removed(this); const size_t size_after = m_members_buffer.committed(); double percent = static_cast<double>(size_before - size_after); percent /= size_before; percent *= 100; std::cerr << "PURGE (size before=" << size_before << " after=" << size_after << " purged=" << (size_before - size_after) << " / " << static_cast<int>(percent) << "%)\n"; m_count_complete = 0; } }
void run() final { osmium::thread::set_thread_name("_osmium_opl_in"); line_by_line(*this); if (m_buffer.committed() > 0) { send_to_output_queue(std::move(m_buffer)); } }
void maybe_flush() { if (m_buffer.committed() > 800*1024) { osmium::memory::Buffer buffer{1024*1024}; using std::swap; swap(m_buffer, buffer); send_to_output_queue(std::move(buffer)); } }
void possibly_flush_output_buffer() { if (m_output_buffer.committed() > max_buffer_size_for_flush) { flush_output_buffer(); } }
std::string fail_in; osmium::io::CompressionFactory::instance().register_compression(osmium::io::file_compression::gzip, [&](int, osmium::io::fsync) { return new MockCompressor(fail_in); }, [](int) { return nullptr; }, [](const char*, size_t) { return nullptr; } ); osmium::io::Header header; header.set("generator", "test_writer_with_mock_compression.cpp"); osmium::io::Reader reader{with_data_dir("t/io/data.osm")}; osmium::memory::Buffer buffer = reader.read(); REQUIRE(buffer); REQUIRE(buffer.committed() > 0); REQUIRE(buffer.select<osmium::OSMObject>().size() > 0); SECTION("fail on construction") { fail_in = "constructor"; REQUIRE_THROWS_AS([&](){ osmium::io::Writer writer("test-writer-mock-fail-on-construction.osm.gz", header, osmium::io::overwrite::allow); writer(std::move(buffer)); writer.close(); }(), const std::logic_error&); } SECTION("fail on write") {
// XXX void operator()(const osmium::memory::Buffer& buffer) { osmium::io::detail::reliable_write(m_data_fd, buffer.data(), buffer.committed()); osmium::apply(buffer.begin(), buffer.end(), *this); }
osmium::memory::Buffer invalid_buffer2; osmium::memory::Buffer empty_buffer1{1024}; osmium::memory::Buffer empty_buffer2{2048}; REQUIRE_FALSE(invalid_buffer1); REQUIRE_FALSE(invalid_buffer2); REQUIRE(empty_buffer1); REQUIRE(empty_buffer2); REQUIRE(invalid_buffer1 == invalid_buffer2); REQUIRE(invalid_buffer1 != empty_buffer1); REQUIRE(empty_buffer1 != empty_buffer2); REQUIRE(invalid_buffer1.capacity() == 0); REQUIRE(invalid_buffer1.written() == 0); REQUIRE(invalid_buffer1.committed() == 0); REQUIRE(invalid_buffer1.clear() == 0); REQUIRE(empty_buffer1.capacity() == 1024); REQUIRE(empty_buffer1.written() == 0); REQUIRE(empty_buffer1.committed() == 0); REQUIRE(empty_buffer1.is_aligned()); REQUIRE(empty_buffer1.clear() == 0); REQUIRE(empty_buffer2.capacity() == 2048); REQUIRE(empty_buffer2.written() == 0); REQUIRE(empty_buffer2.committed() == 0); REQUIRE(empty_buffer2.is_aligned()); REQUIRE(empty_buffer2.clear() == 0); }