Osmium  0.1
include/osmium/handler/progress.hpp
Go to the documentation of this file.
00001 #ifndef OSMIUM_HANDLER_PROGRESS_HPP
00002 #define OSMIUM_HANDLER_PROGRESS_HPP
00003 
00004 /*
00005 
00006 Copyright 2011 Jochen Topf <jochen@topf.org> and others (see README).
00007 
00008 This file is part of Osmium (https://github.com/joto/osmium).
00009 
00010 Osmium is free software: you can redistribute it and/or modify it under the
00011 terms of the GNU Lesser General Public License or (at your option) the GNU
00012 General Public License as published by the Free Software Foundation, either
00013 version 3 of the Licenses, or (at your option) any later version.
00014 
00015 Osmium is distributed in the hope that it will be useful, but WITHOUT ANY
00016 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
00017 PARTICULAR PURPOSE. See the GNU Lesser General Public License and the GNU
00018 General Public License for more details.
00019 
00020 You should have received a copy of the Licenses along with Osmium. If not, see
00021 <http://www.gnu.org/licenses/>.
00022 
00023 */
00024 
00025 #include <unistd.h>
00026 #include <sys/time.h>
00027 
00028 namespace Osmium {
00029 
00030     namespace Handler {
00031 
00044         class Progress : public Base {
00045 
00046             uint64_t count_nodes;
00047             uint64_t count_ways;
00048             uint64_t count_relations;
00049 
00050             int step;
00051 
00052             bool is_a_tty;
00053 
00054             timeval first_node;
00055             timeval first_way;
00056             timeval first_relation;
00057 
00058             void update_display(bool show_per_second=true) const {
00059                 std::cout << "[" << count_nodes << "]";
00060                 if (count_ways > 0 || count_relations > 0) {
00061                     std::cout << " [" << count_ways << "]";
00062                     if (count_relations > 0) {
00063                         std::cout << " [" << count_relations << "]";
00064                     }
00065                 }
00066 
00067                 if (show_per_second) {
00068                     timeval now;
00069                     gettimeofday(&now, 0);
00070 
00071                     if (count_relations > 0) {
00072                         float relation_diff = (now.tv_sec - first_relation.tv_sec) * 1000000 + (now.tv_usec - first_relation.tv_usec);
00073                         int relations_per_sec = (float)count_relations / relation_diff * 1000000;
00074                         std::cout << " (" << relations_per_sec << " Relations per second)   ";
00075                     } else if (count_ways > 0) {
00076                         float way_diff = (now.tv_sec - first_way.tv_sec) * 1000000 + (now.tv_usec - first_way.tv_usec);
00077                         int ways_per_sec = (float)count_ways / way_diff * 1000000;
00078                         std::cout << " (" << ways_per_sec << " Ways per second)   ";
00079                     } else if (count_nodes > 0) {
00080                         float node_diff = (now.tv_sec - first_node.tv_sec) * 1000000 + (now.tv_usec - first_node.tv_usec);
00081                         int nodes_per_sec = (float)count_nodes / node_diff * 1000000;
00082                         std::cout << " (" << nodes_per_sec << " Nodes per second)   ";
00083                     }
00084                 } else {
00085                     std::cout << "                                   ";
00086                 }
00087 
00088                 std::cout << "\r";
00089                 std::cout.flush();
00090             }
00091 
00092         public:
00093 
00099             Progress(int s=1000) : Base(), count_nodes(0), count_ways(0), count_relations(0), step(s), is_a_tty(false), first_node(), first_way(), first_relation() {
00100                 if (isatty(1)) {
00101                     is_a_tty = true;
00102                 }
00103             }
00104 
00105             void hide_cursor() const {
00106                 std::cout << "\x1b[?25l";
00107             }
00108 
00109             void show_cursor() const {
00110                 std::cout << "\x1b[?25h";
00111             }
00112 
00113             void init(Osmium::OSM::Meta&) const {
00114                 if (is_a_tty) {
00115                     hide_cursor();
00116                     update_display();
00117                 }
00118             }
00119 
00120             void node(const shared_ptr<Osmium::OSM::Node const>& /*object*/) {
00121                 if (first_node.tv_sec == 0) {
00122                     gettimeofday(&first_node, 0);
00123                 }
00124                 if (is_a_tty && ++count_nodes % step == 0) {
00125                     update_display();
00126                 }
00127             }
00128 
00129             void way(const shared_ptr<Osmium::OSM::Way const>& /*object*/) {
00130                 if (first_way.tv_sec == 0) {
00131                     gettimeofday(&first_way, 0);
00132                 }
00133                 if (is_a_tty && ++count_ways % step == 0) {
00134                     update_display();
00135                 }
00136             }
00137 
00138             void relation(const shared_ptr<Osmium::OSM::Relation const>& /*object*/) {
00139                 if (first_relation.tv_sec == 0) {
00140                     gettimeofday(&first_relation, 0);
00141                 }
00142                 if (is_a_tty && ++count_relations % step == 0) {
00143                     update_display();
00144                 }
00145             }
00146 
00147             void final() const {
00148                 if (is_a_tty) {
00149                     update_display(false);
00150                     std::cout << std::endl;
00151 
00152                     std::cout << "  Average: ";
00153 
00154                     timeval now;
00155                     gettimeofday(&now, 0);
00156 
00157                     if (count_nodes > 0) {
00158                         float node_diff = (first_way.tv_sec - first_node.tv_sec) * 1000000 + (first_way.tv_usec - first_node.tv_usec);
00159                         int nodes_per_sec = (float)count_nodes / node_diff * 1000000;
00160                         std::cout << nodes_per_sec << " Nodes ";
00161                     }
00162 
00163                     if (count_ways > 0) {
00164                         float way_diff = (first_relation.tv_sec - first_way.tv_sec) * 1000000 + (first_relation.tv_usec - first_way.tv_usec);
00165                         int ways_per_sec = (float)count_ways / way_diff * 1000000;
00166                         std::cout << ways_per_sec << " Ways ";
00167                     }
00168 
00169                     if (count_relations > 0) {
00170                         float relation_diff = (now.tv_sec - first_relation.tv_sec) * 1000000 + (now.tv_usec - first_relation.tv_usec);
00171                         int relations_per_sec = (float)count_relations / relation_diff * 1000000;
00172                         std::cout << relations_per_sec << " Relations ";
00173                     }
00174 
00175                     show_cursor();
00176                     std::cout  << "per second" << std::endl;
00177                     std::cout.flush();
00178                 }
00179             }
00180 
00181         }; // class Progress
00182 
00183     } // namespace Handler
00184 
00185 } // namespace Osmium
00186 
00187 #endif // OSMIUM_HANDLER_PROGRESS_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines