Merge commit '879f7eb04200d7d2c28af565229bf6e3d54274fd' into retry/libosmium

This commit is contained in:
karenzshea
2016-10-03 13:08:59 -04:00
208 changed files with 11590 additions and 4051 deletions
+15 -2
View File
@@ -35,6 +35,7 @@ DEALINGS IN THE SOFTWARE.
#include <cstdlib>
#include <cstring>
#include <string>
#ifdef _MSC_VER
# define strcasecmp _stricmp
@@ -44,7 +45,7 @@ namespace osmium {
namespace config {
inline int get_pool_threads() {
inline int get_pool_threads() noexcept {
const char* env = getenv("OSMIUM_POOL_THREADS");
if (env) {
return std::atoi(env);
@@ -52,7 +53,7 @@ namespace osmium {
return 0;
}
inline bool use_pool_threads_for_pbf_parsing() {
inline bool use_pool_threads_for_pbf_parsing() noexcept {
const char* env = getenv("OSMIUM_USE_POOL_THREADS_FOR_PBF_PARSING");
if (env) {
if (!strcasecmp(env, "off") ||
@@ -65,6 +66,18 @@ namespace osmium {
return true;
}
inline size_t get_max_queue_size(const char* queue_name, size_t default_value) noexcept {
std::string name {"OSMIUM_MAX_"};
name += queue_name;
name += "_QUEUE_SIZE";
const char* env = getenv(name.c_str());
if (env) {
auto value = std::atoi(env);
return value == 0 ? default_value : value;
}
return default_value;
}
} // namespace config
} // namespace osmium
+1 -50
View File
@@ -33,7 +33,7 @@ DEALINGS IN THE SOFTWARE.
*/
#include <iterator>
#include <cstdint>
#include <type_traits>
#include <utility>
@@ -118,55 +118,6 @@ namespace osmium {
}; // class DeltaDecode
template <typename TBaseIterator, typename TTransform, typename TValue, typename TDelta = int64_t>
class DeltaEncodeIterator : public std::iterator<std::input_iterator_tag, TValue> {
TBaseIterator m_it;
TBaseIterator m_end;
TTransform m_trans;
DeltaEncode<TValue, TDelta> m_value;
TDelta m_delta;
public:
using value_type = TValue;
using delta_type = TDelta;
DeltaEncodeIterator(TBaseIterator first, TBaseIterator last, TTransform& trans) :
m_it(first),
m_end(last),
m_trans(trans),
m_value(m_it != m_end ? m_trans(m_it) : 0),
m_delta(static_cast_with_assert<TDelta>(m_value.value())) {
}
DeltaEncodeIterator& operator++() {
if (++m_it != m_end) {
m_delta = m_value.update(m_trans(m_it));
}
return *this;
}
DeltaEncodeIterator operator++(int) {
DeltaEncodeIterator tmp(*this);
operator++();
return tmp;
}
TDelta operator*() {
return m_delta;
}
bool operator==(const DeltaEncodeIterator& rhs) const {
return m_it == rhs.m_it && m_end == rhs.m_end;
}
bool operator!=(const DeltaEncodeIterator& rhs) const {
return !(*this == rhs);
}
}; // class DeltaEncodeIterator
} // namespace util
} // namespace osmium
+1 -2
View File
@@ -35,7 +35,6 @@ DEALINGS IN THE SOFTWARE.
#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <iterator>
#include <string>
@@ -44,7 +43,7 @@ namespace osmium {
namespace util {
constexpr int max_double_length = 20; // should fit any double
constexpr const int max_double_length = 20; // should fit any double
/**
* Write double to iterator, removing superfluous '0' characters at
+77 -5
View File
@@ -36,6 +36,7 @@ DEALINGS IN THE SOFTWARE.
#include <cerrno>
#include <cstddef>
#include <cstdio>
#include <string>
#include <system_error>
#include <sys/stat.h>
#include <sys/types.h>
@@ -47,9 +48,6 @@ DEALINGS IN THE SOFTWARE.
#ifndef _MSC_VER
# include <unistd.h>
#else
// https://msdn.microsoft.com/en-us/library/whx354w1.aspx
# define ftruncate _chsize_s
#endif
#include <osmium/util/cast.hpp>
@@ -70,7 +68,7 @@ namespace osmium {
#ifdef _MSC_VER
// Windows implementation
// https://msdn.microsoft.com/en-us/library/dfbc2kec.aspx
auto size = ::_filelengthi64(fd);
const auto size = ::_filelengthi64(fd);
if (size == -1L) {
throw std::system_error(errno, std::system_category(), "_filelengthi64 failed");
}
@@ -85,6 +83,44 @@ namespace osmium {
#endif
}
/**
* Get file size.
* This is a small wrapper around a system call.
*
* @param name File name
* @returns file size
* @throws std::system_error If system call failed
*/
inline size_t file_size(const char* name) {
#ifdef _MSC_VER
// Windows implementation
// https://msdn.microsoft.com/en-us/library/14h5k7ff.aspx
struct _stat64 s;
if (::_stati64(name, &s) != 0) {
throw std::system_error(errno, std::system_category(), "_stati64 failed");
}
#else
// Unix implementation
struct stat s;
if (::stat(name, &s) != 0) {
throw std::system_error(errno, std::system_category(), "stat failed");
}
#endif
return size_t(s.st_size);
}
/**
* Get file size.
* This is a small wrapper around a system call.
*
* @param name File name
* @returns file size
* @throws std::system_error If system call failed
*/
inline size_t file_size(const std::string& name) {
return file_size(name.c_str());
}
/**
* Resize file.
* Small wrapper around ftruncate(2) system call.
@@ -94,8 +130,13 @@ namespace osmium {
* @throws std::system_error If ftruncate(2) call failed
*/
inline void resize_file(int fd, size_t new_size) {
#ifdef _WIN32
// https://msdn.microsoft.com/en-us/library/whx354w1.aspx
if (::_chsize_s(fd, static_cast_with_assert<__int64>(new_size)) != 0) {
#else
if (::ftruncate(fd, static_cast_with_assert<off_t>(new_size)) != 0) {
throw std::system_error(errno, std::system_category(), "ftruncate failed");
#endif
throw std::system_error(errno, std::system_category(), "resizing file failed");
}
}
@@ -114,6 +155,37 @@ namespace osmium {
#endif
}
/**
* Get current offset into file.
*
* @param fd Open file descriptor.
* @returns File offset or 0 if it is not available.
*/
inline size_t file_offset(int fd) {
#ifdef _MSC_VER
// https://msdn.microsoft.com/en-us/library/1yee101t.aspx
auto offset = _lseeki64(fd, 0, SEEK_CUR);
#else
auto offset = ::lseek(fd, 0, SEEK_CUR);
#endif
if (offset == -1) {
return 0;
}
return size_t(offset);
}
/**
* Check whether the file descriptor refers to a TTY.
*/
inline bool isatty(int fd) {
#ifdef _MSC_VER
// https://msdn.microsoft.com/en-us/library/f4s0ddew.aspx
return _isatty(fd) != 0;
#else
return ::isatty(fd) != 0;
#endif
}
} // namespace util
} // namespace osmium
+14 -4
View File
@@ -34,6 +34,7 @@ DEALINGS IN THE SOFTWARE.
*/
#include <cstddef>
#include <type_traits>
#include <utility>
namespace osmium {
@@ -43,10 +44,10 @@ namespace osmium {
using iterator = It;
iterator_range(P&& p) :
explicit iterator_range(P&& p) :
P(std::forward<P>(p)) {
}
/*
It begin() {
return this->first;
}
@@ -54,7 +55,7 @@ namespace osmium {
It end() {
return this->second;
}
*/
It begin() const {
return this->first;
}
@@ -67,7 +68,16 @@ namespace osmium {
return begin() == end();
}
};
}; // struct iterator_range
/**
* Helper function to create iterator_range from std::pair.
*/
template <typename P, typename It = typename P::first_type>
inline iterator_range<It> make_range(P&& p) {
static_assert(std::is_same<P, std::pair<It, It>>::value, "make_range needs pair of iterators as argument");
return iterator_range<It>(std::forward<P>(p));
}
} // namespace osmium
+11 -14
View File
@@ -35,6 +35,7 @@ DEALINGS IN THE SOFTWARE.
#include <cassert>
#include <cerrno>
#include <cstddef>
#include <stdexcept>
#include <system_error>
@@ -126,22 +127,18 @@ private:
void make_invalid() noexcept;
#ifdef _WIN32
typedef DWORD flag_type;
using flag_type = DWORD;
#else
typedef int flag_type;
using flag_type = int;
#endif
flag_type get_protection() const noexcept;
flag_type get_flags() const noexcept;
// A zero-sized mapping is not allowed by the operating system.
// So if the user asks for a mapping of size 0, we map a full
// page instead. This way we don't have a special case in the rest
// of the code.
static size_t initial_size(size_t size) {
static size_t check_size(size_t size) {
if (size == 0) {
return osmium::util::get_pagesize();
throw std::runtime_error("Zero-sized mapping is not allowed.");
}
return size;
}
@@ -218,7 +215,7 @@ private:
~MemoryMapping() noexcept {
try {
unmap();
} catch (std::system_error&) {
} catch (const std::system_error&) {
// Ignore any exceptions because destructor must not throw.
}
}
@@ -306,7 +303,7 @@ private:
public:
AnonymousMemoryMapping(size_t size) :
explicit AnonymousMemoryMapping(size_t size) :
MemoryMapping(size, mapping_mode::write_private) {
}
@@ -342,7 +339,7 @@ private:
* @param size Number of objects of type T to be mapped
* @throws std::system_error if the mapping fails
*/
TypedMemoryMapping(size_t size) :
explicit TypedMemoryMapping(size_t size) :
m_mapping(sizeof(T) * size, MemoryMapping::mapping_mode::write_private) {
}
@@ -491,7 +488,7 @@ private:
public:
AnonymousTypedMemoryMapping(size_t size) :
explicit AnonymousTypedMemoryMapping(size_t size) :
TypedMemoryMapping<T>(size) {
}
@@ -550,7 +547,7 @@ inline int osmium::util::MemoryMapping::get_flags() const noexcept {
}
inline osmium::util::MemoryMapping::MemoryMapping(size_t size, mapping_mode mode, int fd, off_t offset) :
m_size(initial_size(size)),
m_size(check_size(size)),
m_offset(offset),
m_fd(resize_fd(fd)),
m_mapping_mode(mode),
@@ -689,7 +686,7 @@ inline void osmium::util::MemoryMapping::make_invalid() noexcept {
}
inline osmium::util::MemoryMapping::MemoryMapping(size_t size, MemoryMapping::mapping_mode mode, int fd, off_t offset) :
m_size(initial_size(size)),
m_size(check_size(size)),
m_offset(offset),
m_fd(resize_fd(fd)),
m_mapping_mode(mode),
+52
View File
@@ -0,0 +1,52 @@
#ifndef OSMIUM_UTIL_MISC_HPP
#define OSMIUM_UTIL_MISC_HPP
/*
This file is part of Osmium (http://osmcode.org/libosmium).
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include <tuple>
namespace osmium {
/**
* Like std::tie(), but takes its arguments as const references. Used
* as a helper function when sorting.
*/
template<typename... Ts>
inline std::tuple<const Ts&...>
const_tie(const Ts&... args) noexcept {
return std::tuple<const Ts&...>(args...);
}
} // namespace osmium
#endif // OSMIUM_UTIL_MISC_HPP
+5 -4
View File
@@ -33,6 +33,7 @@ DEALINGS IN THE SOFTWARE.
*/
#include <cstddef>
#include <initializer_list>
#include <map>
#include <string>
@@ -107,7 +108,7 @@ namespace osmium {
* be set to "true".
*/
void set(std::string data) {
size_t pos = data.find_first_of('=');
const size_t pos = data.find_first_of('=');
if (pos == std::string::npos) {
m_options[data] = "true";
} else {
@@ -122,7 +123,7 @@ namespace osmium {
* empty string) is returned.
*/
std::string get(const std::string& key, const std::string& default_value="") const noexcept {
auto it = m_options.find(key);
const auto it = m_options.find(key);
if (it == m_options.end()) {
return default_value;
}
@@ -134,7 +135,7 @@ namespace osmium {
* Will return false if the value is unset.
*/
bool is_true(const std::string& key) const noexcept {
std::string value = get(key);
const std::string value = get(key);
return (value == "true" || value == "yes");
}
@@ -143,7 +144,7 @@ namespace osmium {
* Will return true if the value is unset.
*/
bool is_not_false(const std::string& key) const noexcept {
std::string value = get(key);
const std::string value = get(key);
return !(value == "false" || value == "no");
}
@@ -0,0 +1,179 @@
#ifndef OSMIUM_UTIL_PROGRESS_BAR_HPP
#define OSMIUM_UTIL_PROGRESS_BAR_HPP
/*
This file is part of Osmium (http://osmcode.org/libosmium).
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include <iostream>
namespace osmium {
/**
* Displays a progress bar on STDERR. Can be used together with the
* osmium::io::Reader class for instance.
*/
class ProgressBar {
static const char* bar() noexcept {
return "======================================================================";
}
static const char* spc() noexcept {
return " ";
}
static constexpr const size_t length = 70;
// The max size is the file size if there is a single file and the
// sum of all file sizes if there are multiple files. It corresponds
// to 100%.
size_t m_max_size;
// The sum of the file sizes already done.
size_t m_done_size = 0;
// The currently read size in the current file.
size_t m_current_size = 0;
// The percentage calculated when it was last displayed. Used to decide
// whether we need to update the display. Start setting is one that
// will always be different from any legal setting.
size_t m_prev_percent = 100 + 1;
// Is the progress bar enabled at all?
bool m_enable;
// Used to make sure we do cleanup in the destructor if it was not
// already done.
bool m_do_cleanup = true;
void display() {
const size_t percent = 100 * (m_done_size + m_current_size) / m_max_size;
if (m_prev_percent == percent) {
return;
}
m_prev_percent = percent;
const size_t num = size_t(percent * (length / 100.0));
std::cerr << '[';
if (num >= length) {
std::cerr << bar();
} else {
std::cerr << (bar() + length - num) << '>' << (spc() + num);
}
std::cerr << "] ";
if (percent < 10) {
std::cerr << ' ';
}
if (percent < 100) {
std::cerr << ' ';
}
std::cerr << percent << "% \r";
}
public:
/**
* Initializes the progress bar. No output yet.
*
* @param max_size Max size equivalent to 100%.
* @param enable Set to false to disable (for instance if stderr is
* not a TTY).
*/
ProgressBar(size_t max_size, bool enable) noexcept :
m_max_size(max_size),
m_enable(max_size > 0 && enable) {
}
~ProgressBar() {
if (m_do_cleanup) {
try {
done();
} catch (...) {
// Swallow any exceptions, because a destructor should
// not throw.
}
}
}
/**
* Call this function to update the progress bar. Actual update will
* only happen if the percentage changed from the last time this
* function was called.
*
* @param current_size Current size. Used together with the max_size
* from constructor to calculate the percentage.
*/
void update(size_t current_size) {
if (!m_enable) {
return;
}
m_current_size = current_size;
display();
}
/**
* If you are reading multiple files, call this function after each
* file is finished.
*
* @param file_size The size of the file just finished.
*/
void file_done(size_t file_size) {
if (m_enable) {
m_done_size += file_size;
m_current_size = 0;
display();
}
}
/**
* Call this at the end. Will update the progress bar to 100% and
* print a final line feed. If this is not called explicitly the
* destructor will also call this.
*/
void done() {
m_do_cleanup = false;
if (m_enable) {
m_done_size = m_max_size;
m_current_size = 0;
display();
std::cerr << '\n';
}
}
}; // class ProgressBar
} // namespace osmium
#endif // OSMIUM_UTIL_PROGRESS_BAR_HPP
+1 -1
View File
@@ -33,9 +33,9 @@ DEALINGS IN THE SOFTWARE.
*/
#include <cstddef>
#include <string>
#include <vector>
#include <iostream>
namespace osmium {
+98
View File
@@ -0,0 +1,98 @@
#ifndef OSMIUM_UTIL_TIMER_HPP
#define OSMIUM_UTIL_TIMER_HPP
/*
This file is part of Osmium (http://osmcode.org/libosmium).
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include <cstdint>
#ifdef OSMIUM_WITH_TIMER
#include <chrono>
namespace osmium {
class Timer {
using clock = std::chrono::high_resolution_clock;
std::chrono::time_point<clock> m_start;
std::chrono::time_point<clock> m_stop;
public:
Timer() :
m_start(clock::now()) {
}
void start() {
m_start = clock::now();
}
void stop() {
m_stop = clock::now();
}
int64_t elapsed_microseconds() const {
return std::chrono::duration_cast<std::chrono::microseconds>(m_stop - m_start).count();
}
};
} // namespace osmium
#else
namespace osmium {
class Timer {
public:
Timer() = default;
void start() {
}
void stop() {
}
int64_t elapsed_microseconds() const {
return 0;
}
};
} // namespace osmium
#endif
#endif // OSMIUM_UTIL_TIMER_HPP
@@ -33,11 +33,11 @@ DEALINGS IN THE SOFTWARE.
*/
#include <time.h>
#include <ctime>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>
namespace osmium {
@@ -75,9 +75,9 @@ namespace osmium {
*/
void start_line() {
if (m_newline) {
time_t elapsed = runtime();
const time_t elapsed = runtime();
char old_fill = std::cerr.fill();
const char old_fill = std::cerr.fill();
std::cerr << '[' << std::setw(2) << (elapsed / 60) << ':' << std::setw(2) << std::setfill('0') << (elapsed % 60) << "] ";
std::cerr.fill(old_fill);