UtilJ.h

Go to the documentation of this file.
00001 /*
00002  * UtilJ.h
00003  *
00004  *  Created on: Nov 4, 2010
00005  *      Author: jjacobs
00006  */
00007 
00008 #ifndef UTILJ_H_
00009 #define UTILJ_H_
00010 
00011 // Casa Includes
00012 
00013 #include <casa/aips.h>
00014 #include <casa/BasicSL/String.h>
00015 #include <casa/Exceptions/Error.h>
00016 
00017 // C++ and System Includes
00018 
00019 #include <cassert>
00020 #include <cstdarg>
00021 #include <cstdlib>
00022 #include <sys/time.h>
00023 #include <sys/resource.h>
00024 // STL Includes
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 //template <typename Element, typename Container>
00071 //Bool
00072 //contains (const Element & e, const Container & c)
00073 //{
00074 //      return c.find(e) != c.end();
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     // For set and map use containsKey; will work for set but
00092     // use with map requires specifying a pair as the first argument
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 //DEPRECATED (String format (const char * formatString, ...) /* "Use String::format"*/);
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 (); // call to get the latest stats loaded
00292     double getRssInMB () const; // get resident set size
00293     int64_t getRssInBytes () const;
00294 
00295     double getVmInMB () const; // get the Virtual memory size
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; // in pages
00304     int64_t vmPages_p; // in pages
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 // These two classes, Times and DeltaTimes should be moved out of this file and
00338 // into casacore/casa/OS.  In the meantime, an ifdef should keep the apple from
00339 // barfing.
00340 
00341 // <summary>
00342 
00343 // </summary>
00344 
00345 // <use visibility=local>   or   <use visibility=export>
00346 
00347 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos="">
00348 // </reviewed>
00349 
00350 // <prerequisite>
00351 //   <li> SomeClass
00352 //   <li> SomeOtherClass
00353 //   <li> some concept
00354 // </prerequisite>
00355 //
00356 // <etymology>
00357 // </etymology>
00358 //
00359 // <synopsis>
00360 // </synopsis>
00361 //
00362 // <example>
00363 // </example>
00364 //
00365 // <motivation>
00366 // </motivation>
00367 //
00368 // <templating arg=T>
00369 //    <li>
00370 //    <li>
00371 // </templating>
00372 //
00373 // <thrown>
00374 //    <li>
00375 //    <li>
00376 // </thrown>
00377 //
00378 // <todo asof="yyyy/mm/dd">
00379 //   <li> add this feature
00380 //   <li> fix this bug
00381 //   <li> start discussion of this possible extension
00382 // </todo>
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         //Double cpu = ((Double) clock ()) / CLOCKS_PER_SEC; // should be in seconds
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 // <summary>
00441 // </summary>
00442 
00443 // <use visibility=local>   or   <use visibility=export>
00444 
00445 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos="">
00446 // </reviewed>
00447 
00448 // <prerequisite>
00449 //   <li> SomeClass
00450 //   <li> SomeOtherClass
00451 //   <li> some concept
00452 // </prerequisite>
00453 //
00454 // <etymology>
00455 // </etymology>
00456 //
00457 // <synopsis>
00458 // </synopsis>
00459 //
00460 // <example>
00461 // </example>
00462 //
00463 // <motivation>
00464 // </motivation>
00465 //
00466 // <templating arg=T>
00467 //    <li>
00468 //    <li>
00469 // </templating>
00470 //
00471 // <thrown>
00472 //    <li>
00473 //    <li>
00474 // </thrown>
00475 //
00476 // <todo asof="yyyy/mm/dd">
00477 //   <li> add this feature
00478 //   <li> fix this bug
00479 //   <li> start discussion of this possible extension
00480 // </todo>
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; // to convert to ms
00507     String formatStats (const String & floatFormat = "%6.1f",
00508                         Double scale=1000.0,
00509                         const String & units = "ms")  const; // to convert to ms
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;}        /* maximum resident set size */
00545     long   ixrss () const { return rusage_p.ru_ixrss;}         /* integral shared memory size */
00546     long   idrss () const { return rusage_p.ru_idrss;}         /* integral unshared data size */
00547     long   isrss () const { return rusage_p.ru_isrss;}         /* integral unshared stack size */
00548     long   minflt () const { return rusage_p.ru_minflt;}        /* page reclaims */
00549     long   majflt () const { return rusage_p.ru_majflt;}        /* page faults */
00550     long   nswap () const { return rusage_p.ru_nswap;}         /* swaps */
00551     long   inblock () const { return rusage_p.ru_inblock;}       /* block input operations */
00552     long   oublock () const { return rusage_p.ru_oublock;}       /* block output operations */
00553     long   msgsnd () const { return rusage_p.ru_msgsnd;}        /* messages sent */
00554     long   msgrcv () const { return rusage_p.ru_msgrcv;}        /* messages received */
00555     long   nsignals () const { return rusage_p.ru_nsignals;}      /* signals received */
00556     long   nvcsw () const { return rusage_p.ru_nvcsw;}         /* voluntary context switches */
00557     long   nivcsw () const { return rusage_p.ru_nivcsw;}        /* involuntary context switches */
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 // Global Functions
00571 
00572 // <linkfrom anchor=unique-string-within-this-file classes="class-1,...,class-n">
00573 //     <here> Global functions </here> for foo and bar.
00574 // </linkfrom>
00575 
00576 // A free function is provided that is useful for
00577 // go here...
00578 
00579 // <group name=accumulation>
00580 
00581 
00582 // </group>
00583 
00584 /*
00585 
00586 Example of using composer and unary.  The composed functors have to be derived from std::unary_function
00587 
00588   int f(int x) { return x*x;}
00589   int g(int x) { return 2 * x;}
00590   int h(int x) { return 100 + x;}
00591 
00592   vector<int> a;
00593   a.push_back(1);
00594   a.push_back(2);
00595   a.push_back(3);
00596 
00597   transform (a.begin(), a.end(), std::ostream_iterator<int> (cout, "\n"), compose (unary(f), unary(f)));
00598 
00599   // prints out
00600   // 4
00601   // 16
00602   // 36
00603 
00604   transform (a.begin(), a.end(), std::ostream_iterator<int> (cout, "\n"),
00605              compose (unary(h), compose (unary(f), unary(f))));
00606 
00607   // prints out
00608   // 104
00609   // 116
00610   // 136
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 } // end namespace utilj
00664 
00665 } // end namespace casa
00666 
00667 
00668 #endif /* UTILJ_H_ */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 31 Aug 2016 for casa by  doxygen 1.6.1