00001
00002
00003
00004
00005
00006
00007
00008 #ifndef UTILJ_H_
00009 #define UTILJ_H_
00010
00011
00012
00013 #include <casa/aips.h>
00014 #include <casa/BasicSL/String.h>
00015 #include <casa/Exceptions/Error.h>
00016
00017
00018
00019 #include <cassert>
00020 #include <cstdarg>
00021 #include <cstdlib>
00022 #include <sys/time.h>
00023 #include <sys/resource.h>
00024
00025 #include <algorithm>
00026 #include <functional>
00027 #include <iterator>
00028 #include <map>
00029 #include <set>
00030 #include <vector>
00031
00032 #ifdef __GNUC__
00033 #define DEPRECATED(func) func __attribute__ ((deprecated))
00034 #elif defined(_MSC_VER)
00035 #define DEPRECATED(func) __declspec(deprecated) func
00036 #else
00038 #define DEPRECATED(func) func
00039 #endif
00040
00041 #ifdef __GNUC__
00042 #define DEPRECATED_METHOD(comment) __attribute__ ((deprecated))
00043 #else
00045 #define DEPRECATED_METHOD(comment)
00046 #endif
00047
00048 #define Assert AssertCc
00049 #define Throw ThrowCc
00050
00051 #define UnusedVariable(x) ((void) x);
00052
00053 namespace casa {
00054
00055 class String;
00056
00057 namespace utilj {
00058
00059 class AipsErrorTrace : public AipsError {
00060
00061 public:
00062
00063 AipsErrorTrace ( const String &msg, const String &filename, uInt lineNumber,
00064 Category c = GENERAL);
00065
00066 };
00067
00068 class Strings : public std::vector<String> {};
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 template <typename Container>
00079 Bool
00080 containsKey (const typename Container::key_type & key,
00081 const Container & container)
00082 {
00083 return container.find(key) != container.end();
00084 }
00085
00086 template <typename Container>
00087 Bool
00088 contains (const typename Container::value_type & e,
00089 const Container & c)
00090 {
00091
00092
00093
00094 return std::find(c.begin(), c.end(), e) != c.end();
00095 }
00096
00097 template <typename F, typename S>
00098 F & first (std::pair<F,S> & pair) { return pair.first;}
00099
00100 template <typename F, typename S>
00101 const F & first (const std::pair<F,S> & pair) { return pair.first;}
00102
00103 template <typename F, typename S>
00104 class FirstFunctor : public std::unary_function<std::pair<F,S>, F>{
00105 public:
00106 F & operator() (std::pair<F,S> & p) { return p.first; }
00107 const F & operator() (const std::pair<F,S> & p) { return p.first; }
00108 };
00109
00110 template <typename Container, typename Element>
00111 Container
00112 fillContainer (Element sentinel, ...)
00113 {
00114 using namespace std;
00115
00116 Container container;
00117
00118 va_list vaList;
00119 va_start (vaList, sentinel);
00120
00121 Element e = va_arg (vaList, Element);
00122
00123 insert_iterator<Container> i = inserter (container, container.begin());
00124
00125 while (e != sentinel){
00126
00127 * i ++ = e;
00128
00129 e = va_arg (vaList, Element);
00130 }
00131
00132 va_end (vaList);
00133
00134 return container;
00135 }
00136
00137 template <typename F, typename S>
00138 FirstFunctor<F,S> firstFunctor () { return FirstFunctor<F,S> ();}
00139
00140
00141
00142 String formatV (const String & formatString, va_list vaList);
00143
00144 template<typename T>
00145 T
00146 getEnv (const String & name, const T & defaultValue)
00147 {
00148 char * value = getenv (name.c_str());
00149
00150 if (value == NULL){
00151 return defaultValue;
00152 }
00153 else{
00154 return T (value);
00155 }
00156 }
00157
00158 Bool
00159 getEnv (const String & name, const Bool & defaultValue);
00160
00161 Int
00162 getEnv (const String & name, const Int & defaultValue);
00163
00164
00165 String getTimestamp ();
00166
00167 Bool isEnvDefined (const String & name);
00168
00169 std::vector<String> split (const String & string, const String & splitter,
00170 Bool ignoreConsecutiveSplitters = False);
00171
00172 template <typename Itr>
00173 String
00174 join (Itr begin, Itr end, const String & delimiter)
00175 {
00176 String result;
00177 Itr i = begin;
00178
00179 if (i != end){
00180
00181 result = * i ++;
00182
00183 for (; i != end; i++){
00184 result += delimiter + * i;
00185 }
00186 }
00187
00188 return result;
00189 }
00190
00191 template <typename T>
00192 String
00193 join (const T & strings, const String & delimiter)
00194 {
00195 return join (strings.begin(), strings.end(), delimiter);
00196 }
00197
00198 template <typename Itr, typename F>
00199 String
00200 join (Itr begin, Itr end, F f, const String & delimiter)
00201 {
00202 String result;
00203 Itr i = begin;
00204
00205 if (i != end){
00206
00207 result = f(* i);
00208 ++ i;
00209
00210 for (; i != end; i++){
00211 result += delimiter + f (* i);
00212 }
00213 }
00214
00215 return result;
00216 }
00217
00218 template <typename K, typename V>
00219 std::vector<K>
00220 mapKeys (const std::map<K,V> & aMap)
00221 {
00222 std::vector<K> result;
00223
00224 std::transform (aMap.begin(), aMap.end(), back_inserter (result), firstFunctor<K,V>());
00225
00226 return result;
00227 }
00228
00229 AipsError repackageAipsError (AipsError & error, const String & message, const String & file,
00230 Int line, const String & func);
00231
00232 template <typename F, typename S>
00233 F & second (std::pair<F,S> & pair) { return pair.second;}
00234
00235 template <typename F, typename S>
00236 const F & second (const std::pair<F,S> & pair) { return pair.second;}
00237
00238 template <typename F, typename S>
00239 class SecondFunctor : public std::unary_function<std::pair<F,S>, F>{
00240 public:
00241 S & operator() (std::pair<F,S> & p) { return p.second; }
00242 };
00243
00244 template <typename F, typename S>
00245 SecondFunctor<F,S> secondFunctor () { return SecondFunctor<F,S> ();}
00246
00247 template <typename K, typename V>
00248 std::vector<V>
00249 mapValues (const std::map<K,V> & aMap)
00250 {
00251 std::vector<K> result (aMap.size());
00252
00253 std::transform (aMap.begin(), aMap.end(), back_inserter (result), second<K,V>);
00254
00255 return result;
00256 }
00257
00258 void printBacktrace (ostream & os, const String & prefix = "");
00259
00260 long round (Double d);
00261
00262 void sleepMs (Int milliseconds);
00263 void toStdError (const String & m, const String & prefix = "*E* ");
00264 void throwIf (Bool condition, const String & message, const String & file,
00265 Int line, const String & func = String());
00266 void throwIfError (Int errorCode, const String & prefix, const String & file,
00267 Int line, const String & func = String());
00268
00269 template <typename It, typename Obj>
00270 string
00271 containerToString (It begin, It end, String (Obj::* func) () const, const String & delimiter = ",",
00272 const String & wrapper = "")
00273 {
00274 String result;
00275 String d = "";
00276
00277 for (It i = begin; i != end; i++){
00278 result += d + wrapper + ((* i) .* func) () + wrapper;
00279 d = delimiter;
00280 }
00281
00282 return result;
00283 }
00284
00285 class MemoryStatistics {
00286
00287 public:
00288
00289 MemoryStatistics ();
00290
00291 void update ();
00292 double getRssInMB () const;
00293 int64_t getRssInBytes () const;
00294
00295 double getVmInMB () const;
00296 int64_t getVmInBytes () const;
00297
00298 private:
00299
00300 double bytesPerMb_p;
00301 string filename_p;
00302 int pageSize_p;
00303 int64_t rssPages_p;
00304 int64_t vmPages_p;
00305 };
00306
00307 class IoStatistics {
00308
00309 public:
00310
00311 IoStatistics ();
00312
00313 IoStatistics operator- (const IoStatistics &) const;
00314 IoStatistics operator+ (const IoStatistics &) const;
00315 IoStatistics operator/ (const IoStatistics &) const;
00316 IoStatistics operator* (Double factor) const;
00317
00318 void capture ();
00319
00320 Double getBytesRead () const;
00321 Double getBytesWritten () const;
00322 Double getNReads () const;
00323 Double getNWrites () const;
00324
00325 String report (float scale = .001, const String & scaleTag = String ("K")) const;
00326
00327 private:
00328
00329 Double nBytesRead_p;
00330 Double nBytesWritten_p;
00331 Double nReads_p;
00332 Double nWrites_p;
00333 String statFile_p;
00334 };
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384 class DeltaThreadTimes;
00385
00386 class ThreadTimes {
00387
00388 public:
00389
00390 ThreadTimes () { * this = getTime();}
00391
00392 Double cpu () const { return cpu_p;}
00393 void clear () { empty_p = True;}
00394 Bool empty () const { return empty_p;}
00395 Double elapsed () const { return elapsed_p;}
00396
00397 static ThreadTimes
00398 getTime (){
00399
00400 struct timeval tVal;
00401 gettimeofday (& tVal, NULL);
00402
00403 Double elapsed = tVal.tv_sec + tVal.tv_usec * 1e-6;
00404
00405
00406
00407
00408
00409 #if defined (RUSAGE_THREAD)
00410 struct rusage usage;
00411
00412 int failed = getrusage (RUSAGE_THREAD, & usage);
00413 assert (! failed);
00414
00415 Double cpu = ! failed ? toSeconds (usage.ru_utime) + toSeconds (usage.ru_stime) : 0;
00416 #else
00417 Double cpu = 0;
00418 #endif
00419
00420 return ThreadTimes (elapsed, cpu);
00421 }
00422
00423 DeltaThreadTimes operator- (const ThreadTimes & tEarlier) const;
00424
00425 static Double
00426 toSeconds (const struct timeval & t)
00427 {
00428 return t.tv_sec + t.tv_usec * 1e-6;
00429 }
00430
00431 protected:
00432
00433 Bool empty_p;
00434 Double cpu_p;
00435 Double elapsed_p;
00436
00437 ThreadTimes (Double elapsed, Double cpu) : cpu_p (cpu), elapsed_p (elapsed) {}
00438 };
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481 class DeltaThreadTimes : private ThreadTimes {
00482
00483 friend class ThreadTimes;
00484
00485 public:
00486
00487 DeltaThreadTimes () : ThreadTimes (0, 0), doStats_p (False), n_p (0) {}
00488 explicit DeltaThreadTimes (bool doStats) : ThreadTimes (0,0), doStats_p (doStats), n_p (0)
00489 {
00490 cpuSsq_p = 0;
00491 cpuMin_p = 1e20;
00492 cpuMax_p = -1e20;
00493 elapsedSsq_p = 0;
00494 elapsedMin_p = 1e20;
00495 elapsedMax_p = -1e20;
00496 }
00497
00498 DeltaThreadTimes & operator += (const DeltaThreadTimes & other);
00499
00500 Double cpu () const { return ThreadTimes::cpu();}
00501 Double cpuAvg () const { return n_p == 0 ? 0 : cpu() / n_p;}
00502 Double elapsed () const { return ThreadTimes::elapsed();}
00503 Double elapsedAvg () const { return n_p == 0 ? 0 : elapsed() / n_p;}
00504 String formatAverage (const String & floatFormat = "%6.1f",
00505 Double scale=1000.0,
00506 const String & units = "ms") const;
00507 String formatStats (const String & floatFormat = "%6.1f",
00508 Double scale=1000.0,
00509 const String & units = "ms") const;
00510 Int n() const { return n_p;}
00511
00512 protected:
00513
00514 DeltaThreadTimes (Double elapsed, Double cpu) : ThreadTimes (elapsed, cpu), n_p (0) {}
00515
00516 private:
00517
00518 Double cpuMin_p;
00519 Double cpuMax_p;
00520 Double cpuSsq_p;
00521 Bool doStats_p;
00522 Double elapsedMin_p;
00523 Double elapsedMax_p;
00524 Double elapsedSsq_p;
00525 Int n_p;
00526 };
00527
00528 class RUsage {
00529
00530 public:
00531
00532 RUsage ();
00533
00534 void accumulate (const RUsage & recent, const RUsage & origin);
00535 void capture ();
00536 void captureAndAccumulate (const RUsage & origin);
00537
00538 RUsage operator+ (const RUsage & other) const;
00539 RUsage operator- (const RUsage & other) const;
00540
00541 double utime () const { return rusage_p.ru_utime.tv_sec + rusage_p.ru_utime.tv_usec * 1e-6;}
00542 double stime () const { return rusage_p.ru_stime.tv_sec + rusage_p.ru_stime.tv_usec * 1e-6;}
00543
00544 long maxrss () const { return rusage_p.ru_maxrss;}
00545 long ixrss () const { return rusage_p.ru_ixrss;}
00546 long idrss () const { return rusage_p.ru_idrss;}
00547 long isrss () const { return rusage_p.ru_isrss;}
00548 long minflt () const { return rusage_p.ru_minflt;}
00549 long majflt () const { return rusage_p.ru_majflt;}
00550 long nswap () const { return rusage_p.ru_nswap;}
00551 long inblock () const { return rusage_p.ru_inblock;}
00552 long oublock () const { return rusage_p.ru_oublock;}
00553 long msgsnd () const { return rusage_p.ru_msgsnd;}
00554 long msgrcv () const { return rusage_p.ru_msgrcv;}
00555 long nsignals () const { return rusage_p.ru_nsignals;}
00556 long nvcsw () const { return rusage_p.ru_nvcsw;}
00557 long nivcsw () const { return rusage_p.ru_nivcsw;}
00558
00559 String toString () const;
00560
00561 private:
00562
00563 static RUsage add (const RUsage & a, int sign, const RUsage & b);
00564 static struct timeval addTimes (const struct timeval & first, int sign, const struct timeval & second);
00565
00566 struct rusage rusage_p;
00567
00568 };
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614 template <typename F, typename G>
00615 class ComposedFunctor : public std::unary_function <typename G::argument_type, typename F::result_type> {
00616
00617 public:
00618
00619 ComposedFunctor (F f, G g) : f_p (f), g_p (g) {}
00620
00621 typename F::result_type operator() (typename G::argument_type x) { return f_p ( g_p (x)); }
00622
00623 private:
00624
00625 F f_p;
00626 G g_p;
00627 };
00628
00629 template <typename F, typename G>
00630 ComposedFunctor<F, G>
00631 compose (F f, G g)
00632 {
00633 return ComposedFunctor <F, G> (f, g);
00634 }
00635
00636 template <typename D, typename R>
00637 class UnaryFunctor : public std::unary_function<D,R> {
00638 public:
00639 typedef R (* F) (D);
00640
00641 UnaryFunctor (F f) : f_p (f) {}
00642 R operator() (D x) { return f_p (x); }
00643
00644 private:
00645
00646 F f_p;
00647 };
00648
00649 template <typename D, typename R>
00650 UnaryFunctor <D, R>
00651 unary (R (*f) (D)) { return UnaryFunctor<D, R> (f);}
00652
00653 class Z {
00654 public:
00655
00656 string getName () const { return name_p;}
00657
00658 string name_p;
00659 };
00660
00661
00662
00663 }
00664
00665 }
00666
00667
00668 #endif