1 /**** 2 DIAMOND protein aligner 3 Copyright (C) 2013-2020 Max Planck Society for the Advancement of Science e.V. 4 Benjamin Buchfink 5 Eberhard Karls Universitaet Tuebingen 6 7 Code developed by Benjamin Buchfink <benjamin.buchfink@tue.mpg.de> 8 9 This program is free software: you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation, either version 3 of the License, or 12 (at your option) any later version. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program. If not, see <http://www.gnu.org/licenses/>. 21 ****/ 22 23 #pragma once 24 #include <ostream> 25 #include <fstream> 26 #include <mutex> 27 #include <limits.h> 28 #include <chrono> 29 #include <stdint.h> 30 31 struct Message_stream 32 { 33 Message_stream(bool to_cout = true, bool to_file = false); 34 template<typename _t> 35 Message_stream& operator<<(const _t& x) 36 { 37 if(to_cout_) 38 (*out_stream_) << x; 39 if (to_file_) { 40 std::ofstream f("diamond.log", std::ios_base::out | std::ios_base::app); 41 f << x; 42 f.close(); 43 } 44 return *this; 45 } 46 //Message_stream& operator<<(std::ostream & (__cdecl *_Pfn)(std::ostream&)) 47 Message_stream& operator<<(std::ostream& (*_Pfn)(std::ostream&)); 48 static std::mutex mtx; 49 private: 50 std::ostream* out_stream_; 51 bool to_cout_, to_file_; 52 }; 53 54 extern Message_stream message_stream; 55 extern Message_stream verbose_stream; 56 extern Message_stream log_stream; 57 58 struct task_timer 59 { 60 task_timer(unsigned level = 1) : level_task_timer61 level_(level), 62 msg_(nullptr) 63 { 64 start(nullptr); 65 } 66 task_timer(const char *msg, unsigned level=1) : level_task_timer67 level_(level), 68 msg_(msg) 69 { 70 start(msg); 71 } ~task_timertask_timer72 ~task_timer() 73 { 74 finish(); 75 } 76 void go(const char* msg = nullptr) 77 { 78 finish(); 79 start(msg); 80 msg_ = msg; 81 } finishtask_timer82 void finish() 83 { 84 if (!msg_ || level_ == UINT_MAX) 85 return; 86 get_stream() << " [" << get() << "s]" << std::endl; 87 msg_ = 0; 88 } gettask_timer89 double get() 90 { 91 return (double)std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - t).count() / 1000.0; 92 } secondstask_timer93 uint64_t seconds() const { 94 return (uint64_t)std::chrono::duration_cast<std::chrono::seconds>(std::chrono::high_resolution_clock::now() - t).count(); 95 } millisecondstask_timer96 uint64_t milliseconds() const { 97 return (uint64_t)std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - t).count(); 98 } microsecondstask_timer99 uint64_t microseconds() const { 100 return (uint64_t)std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now() - t).count(); 101 } nanosecondstask_timer102 uint64_t nanoseconds() const { 103 return (uint64_t)std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now() - t).count(); 104 } get_streamtask_timer105 Message_stream& get_stream() const 106 { 107 switch (level_) { 108 case 1: 109 return message_stream; 110 case 2: 111 return verbose_stream; 112 case 3: 113 return log_stream; 114 default: 115 return message_stream; 116 } 117 } 118 private: starttask_timer119 void start(const char *msg) 120 { 121 t = std::chrono::high_resolution_clock::now(); 122 if (level_ == UINT_MAX) 123 return; 124 if (!msg) 125 return; 126 get_stream() << msg << "... " << std::flush; 127 128 } 129 unsigned level_; 130 const char *msg_; 131 std::chrono::high_resolution_clock::time_point t; 132 }; 133 134 void exit_with_error(const std::exception& e);