1 // Author: Bruce Allen 2 // Created: 2/25/2013 3 // 4 // The software provided here is released by the Naval Postgraduate 5 // School, an agency of the U.S. Department of Navy. The software 6 // bears no warranty, either expressed or implied. NPS does not assume 7 // legal liability nor responsibility for a User's use of the software 8 // or the results of such use. 9 // 10 // Please note that within the United States, copyright protection, 11 // under Section 105 of the United States Code, Title 17, is not 12 // available for any work of the United States Government and/or for 13 // any works created by United States Government employees. User 14 // acknowledges that this software contains work which was created by 15 // NPS government employees and is therefore in the public domain and 16 // not subject to copyright. 17 // 18 // Released into the public domain on February 25, 2013 by Bruce Allen. 19 20 /** 21 * \file 22 * Track progress to show that long iterative actions are not hung. 23 * Writes progress to cout and to <dir>/timestamp.json log. 24 * Use total=0 if total is not known. 25 */ 26 27 #ifndef PROGRESS_TRACKER_HPP 28 #define PROGRESS_TRACKER_HPP 29 30 // Standard includes 31 #include <cstdlib> 32 #include <cstdio> 33 #include <cerrno> 34 #include <cstring> 35 #include <sstream> 36 #include <iostream> 37 #include <fstream> 38 #include "../src_libhashdb/hashdb.hpp" // for timestamp 39 40 class progress_tracker_t { 41 private: 42 const std::string dir; 43 const uint64_t total; 44 uint64_t index; 45 std::ofstream os; 46 hashdb::timestamp_t timestamp; 47 48 // do not allow copy or assignment 49 progress_tracker_t(const progress_tracker_t&); 50 progress_tracker_t& operator=(const progress_tracker_t&); 51 show_progress()52 void show_progress() { 53 std::stringstream ss; 54 if (total > 0) { 55 // total is known 56 ss << "# Processing " << index << " of " << total; 57 } else { 58 // total is not known 59 ss << "# Processing " << index << " of ?"; 60 } 61 std::cout << ss.str() << "..." << std::endl; 62 os << timestamp.stamp(ss.str()) << std::endl; 63 } 64 65 public: progress_tracker_t(const std::string & p_dir,const uint64_t p_total,const std::string & cmd)66 progress_tracker_t(const std::string& p_dir, const uint64_t p_total, 67 const std::string& cmd) : 68 dir(p_dir), 69 total(p_total), 70 index(0), 71 os(), 72 timestamp() { 73 std::string filename(dir+"/timestamp.json"); 74 75 // open, fatal if unable to open 76 os.open(filename.c_str()); 77 if (!os.is_open()) { 78 std::cout << "Cannot open progress tracker file " << filename 79 << ": " << strerror(errno) << "\n"; 80 exit(1); 81 } 82 83 // put header in log 84 os << "# command: '" << cmd << "'\n" 85 << "# hashdb-Version: " << PACKAGE_VERSION << "\n"; 86 } 87 track()88 void track() { 89 ++index; 90 if (index%100000 == 0) { 91 show_progress(); 92 } 93 } 94 track_count(const size_t count)95 void track_count(const size_t count) { 96 size_t old_index = index; 97 index += count; 98 if ((index > 0) && (index / 100000 > old_index / 100000)) { 99 show_progress(); 100 } 101 } 102 track_hash_data(const uint64_t count)103 void track_hash_data(const uint64_t count) { 104 // The amount of hash data traversed is calculated from count, 105 // which is 1 or size + 1, see hashdb_data store. 106 track_count(count == 1? 1 : count + 1); 107 } 108 ~progress_tracker_t()109 ~progress_tracker_t() { 110 std::stringstream ss; 111 if (total > 0) { 112 // total is known 113 ss << "# Processing " << index << " of " << total << " completed."; 114 } else { 115 // total is not known 116 ss << "# Processing " << index << " of " << index << " completed."; 117 } 118 std::cout << ss.str() << std::endl; 119 os << timestamp.stamp(ss.str()) << std::endl; 120 121 os.close(); 122 } 123 }; 124 125 #endif 126 127