Line data Source code
1 : /*
2 : * UtilJ.h
3 : *
4 : * Created on: Nov 4, 2010
5 : * Author: jjacobs
6 : */
7 :
8 : #ifndef UTILJ_H_
9 : #define UTILJ_H_
10 :
11 : // Casa Includes
12 :
13 : #include <casacore/casa/aips.h>
14 : #include <casacore/casa/BasicSL/String.h>
15 : #include <casacore/casa/Exceptions/Error.h>
16 :
17 : // C++ and System Includes
18 :
19 : #include <cassert>
20 : #include <cstdarg>
21 : #include <cstdlib>
22 : #include <sys/time.h>
23 : #include <sys/resource.h>
24 : // STL Includes
25 : #include <algorithm>
26 : #include <functional>
27 : #include <iterator>
28 : #include <map>
29 : #include <set>
30 : #include <vector>
31 :
32 : #ifdef __GNUC__
33 : #define DEPRECATED(func) func __attribute__ ((deprecated))
34 : #elif defined(_MSC_VER)
35 : #define DEPRECATED(func) __declspec(deprecated) func
36 : #else
37 : ///#pragma message("WARNING: You need to implement DEPRECATED for this compiler")
38 : #define DEPRECATED(func) func
39 : #endif
40 :
41 : #ifdef __GNUC__
42 : #define DEPRECATED_METHOD(comment) __attribute__ ((deprecated))
43 : #else
44 : ///#pragma message("WARNING: You need to implement DEPRECATED for this compiler")
45 : #define DEPRECATED_METHOD(comment)
46 : #endif
47 :
48 : #define Assert AssertCc
49 : #define Throw ThrowCc
50 :
51 : #define UnusedVariable(x) ((void) x);
52 :
53 : namespace casacore{
54 :
55 : class String;
56 : }
57 :
58 : namespace casa {
59 :
60 : namespace utilj {
61 :
62 : class AipsErrorTrace : public casacore::AipsError {
63 :
64 : public:
65 :
66 : AipsErrorTrace ( const casacore::String &msg, const casacore::String &filename, casacore::uInt lineNumber,
67 : Category c = GENERAL);
68 :
69 : };
70 :
71 : class Strings : public std::vector<casacore::String> {};
72 :
73 : //template <typename Element, typename Container>
74 : //bool
75 : //contains (const Element & e, const Container & c)
76 : //{
77 : // return c.find(e) != c.end();
78 : //}
79 :
80 :
81 : template <typename Container>
82 : bool
83 0 : containsKey (const typename Container::key_type & key,
84 : const Container & container)
85 : {
86 0 : return container.find(key) != container.end();
87 : }
88 :
89 : template <typename Container>
90 : bool
91 0 : contains (const typename Container::value_type & e,
92 : const Container & c)
93 : {
94 : // For set and map use containsKey; will work for set but
95 : // use with map requires specifying a pair as the first argument
96 :
97 0 : return std::find(c.begin(), c.end(), e) != c.end();
98 : }
99 :
100 : template <typename F, typename S>
101 : F & first (std::pair<F,S> & pair) { return pair.first;}
102 :
103 : template <typename F, typename S>
104 : const F & first (const std::pair<F,S> & pair) { return pair.first;}
105 :
106 : template <typename F, typename S>
107 : class FirstFunctor : public std::unary_function<std::pair<F,S>, F>{
108 : public:
109 0 : F & operator() (std::pair<F,S> & p) { return p.first; }
110 0 : const F & operator() (const std::pair<F,S> & p) { return p.first; }
111 : };
112 :
113 : template <typename Container, typename Element>
114 : Container
115 : fillContainer (Element sentinel, ...)
116 : {
117 : using namespace std;
118 :
119 : Container container;
120 :
121 : va_list vaList;
122 : va_start (vaList, sentinel);
123 :
124 : Element e = va_arg (vaList, Element);
125 :
126 : insert_iterator<Container> i = inserter (container, container.begin());
127 :
128 : while (e != sentinel){
129 :
130 : * i ++ = e;
131 :
132 : e = va_arg (vaList, Element);
133 : }
134 :
135 : va_end (vaList);
136 :
137 : return container;
138 : }
139 :
140 : template <typename F, typename S>
141 0 : FirstFunctor<F,S> firstFunctor () { return FirstFunctor<F,S> ();}
142 :
143 :
144 : //DEPRECATED (casacore::String format (const char * formatString, ...) /* "Use casacore::String::format"*/);
145 : casacore::String formatV (const casacore::String & formatString, va_list vaList);
146 :
147 : template<typename T>
148 : T
149 : getEnv (const casacore::String & name, const T & defaultValue)
150 : {
151 : char * value = getenv (name.c_str());
152 :
153 : if (value == NULL){
154 : return defaultValue;
155 : }
156 : else{
157 : return T (value);
158 : }
159 : }
160 :
161 : bool
162 : getEnv (const casacore::String & name, const bool & defaultValue);
163 :
164 : int
165 : getEnv (const casacore::String & name, const int & defaultValue);
166 :
167 :
168 : casacore::String getTimestamp ();
169 :
170 : bool isEnvDefined (const casacore::String & name);
171 :
172 : std::vector<casacore::String> split (const casacore::String & string, const casacore::String & splitter,
173 : bool ignoreConsecutiveSplitters = false);
174 :
175 : template <typename Itr>
176 : casacore::String
177 0 : join (Itr begin, Itr end, const casacore::String & delimiter)
178 : {
179 0 : casacore::String result;
180 0 : Itr i = begin;
181 :
182 0 : if (i != end){
183 :
184 0 : result = * i ++;
185 :
186 0 : for (; i != end; i++){
187 0 : result += delimiter + * i;
188 : }
189 : }
190 :
191 0 : return result;
192 : }
193 :
194 : template <typename T>
195 : casacore::String
196 0 : join (const T & strings, const casacore::String & delimiter)
197 : {
198 0 : return join (strings.begin(), strings.end(), delimiter);
199 : }
200 :
201 : template <typename Itr, typename F>
202 : casacore::String
203 0 : join (Itr begin, Itr end, F f, const casacore::String & delimiter)
204 : {
205 0 : casacore::String result;
206 0 : Itr i = begin;
207 :
208 0 : if (i != end){
209 :
210 0 : result = f(* i);
211 0 : ++ i;
212 :
213 0 : for (; i != end; i++){
214 0 : result += delimiter + f (* i);
215 : }
216 : }
217 :
218 0 : return result;
219 : }
220 :
221 : template <typename K, typename V>
222 : std::vector<K>
223 0 : mapKeys (const std::map<K,V> & aMap)
224 : {
225 0 : std::vector<K> result;
226 :
227 0 : std::transform (aMap.begin(), aMap.end(), back_inserter (result), firstFunctor<K,V>());
228 :
229 0 : return result;
230 : }
231 :
232 : casacore::AipsError repackageAipsError (casacore::AipsError & error,
233 : const casacore::String & message,
234 : const casacore::String & file,
235 : int line, const casacore::String & func);
236 :
237 : template <typename F, typename S>
238 : F & second (std::pair<F,S> & pair) { return pair.second;}
239 :
240 : template <typename F, typename S>
241 : const F & second (const std::pair<F,S> & pair) { return pair.second;}
242 :
243 : template <typename F, typename S>
244 : class SecondFunctor : public std::unary_function<std::pair<F,S>, F>{
245 : public:
246 : S & operator() (std::pair<F,S> & p) { return p.second; }
247 : };
248 :
249 : template <typename F, typename S>
250 : SecondFunctor<F,S> secondFunctor () { return SecondFunctor<F,S> ();}
251 :
252 : template <typename K, typename V>
253 : std::vector<V>
254 : mapValues (const std::map<K,V> & aMap)
255 : {
256 : std::vector<K> result (aMap.size());
257 :
258 : std::transform (aMap.begin(), aMap.end(), back_inserter (result), second<K,V>);
259 :
260 : return result;
261 : }
262 :
263 : void printBacktrace (std::ostream & os, const casacore::String & prefix = "");
264 :
265 : long round (double d);
266 :
267 : void sleepMs (int milliseconds);
268 : void toStdError (const casacore::String & m, const casacore::String & prefix = "*E* ");
269 : void throwIf (bool condition, const casacore::String & message, const casacore::String & file,
270 : int line, const casacore::String & func = casacore::String());
271 : void throwIfError (int errorCode, const casacore::String & prefix, const casacore::String & file,
272 : int line, const casacore::String & func = casacore::String());
273 :
274 : template <typename It, typename Obj>
275 : casacore::String
276 0 : containerToString (It begin, It end, casacore::String (Obj::* func) () const, const casacore::String & delimiter = ",",
277 : const casacore::String & wrapper = "")
278 : {
279 0 : casacore::String result;
280 0 : casacore::String d = "";
281 :
282 0 : for (It i = begin; i != end; i++){
283 0 : result += d + wrapper + ((* i) .* func) () + wrapper;
284 0 : d = delimiter;
285 : }
286 :
287 0 : return result;
288 : }
289 :
290 : class MemoryStatistics {
291 :
292 : public:
293 :
294 : MemoryStatistics ();
295 :
296 : void update (); // call to get the latest stats loaded
297 : double getRssInMB () const; // get resident set size
298 : int64_t getRssInBytes () const;
299 :
300 : double getVmInMB () const; // get the Virtual memory size
301 : int64_t getVmInBytes () const;
302 :
303 : private:
304 :
305 : double bytesPerMb_p;
306 : string filename_p;
307 : int pageSize_p;
308 : int64_t rssPages_p; // in pages
309 : int64_t vmPages_p; // in pages
310 : };
311 :
312 : class IoStatistics {
313 :
314 : public:
315 :
316 : IoStatistics ();
317 :
318 : IoStatistics operator- (const IoStatistics &) const;
319 : IoStatistics operator+ (const IoStatistics &) const;
320 : IoStatistics operator/ (const IoStatistics &) const;
321 : IoStatistics operator* (double factor) const;
322 :
323 : void capture ();
324 :
325 : double getBytesRead () const;
326 : double getBytesWritten () const;
327 : double getNReads () const;
328 : double getNWrites () const;
329 :
330 : casacore::String report (float scale = .001, const casacore::String & scaleTag = casacore::String ("K")) const;
331 :
332 : private:
333 :
334 : double nBytesRead_p;
335 : double nBytesWritten_p;
336 : double nReads_p;
337 : double nWrites_p;
338 : casacore::String statFile_p;
339 : };
340 :
341 :
342 : // These two classes, Times and DeltaTimes should be moved out of this file and
343 : // into casacore/casa/OS. In the meantime, an ifdef should keep the apple from
344 : // barfing.
345 :
346 : // <summary>
347 :
348 : // </summary>
349 :
350 : // <use visibility=local> or <use visibility=export>
351 :
352 : // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos="">
353 : // </reviewed>
354 :
355 : // <prerequisite>
356 : // <li> SomeClass
357 : // <li> SomeOtherClass
358 : // <li> some concept
359 : // </prerequisite>
360 : //
361 : // <etymology>
362 : // </etymology>
363 : //
364 : // <synopsis>
365 : // </synopsis>
366 : //
367 : // <example>
368 : // </example>
369 : //
370 : // <motivation>
371 : // </motivation>
372 : //
373 : // <templating arg=T>
374 : // <li>
375 : // <li>
376 : // </templating>
377 : //
378 : // <thrown>
379 : // <li>
380 : // <li>
381 : // </thrown>
382 : //
383 : // <todo asof="yyyy/mm/dd">
384 : // <li> add this feature
385 : // <li> fix this bug
386 : // <li> start discussion of this possible extension
387 : // </todo>
388 :
389 : class DeltaThreadTimes;
390 :
391 : class ThreadTimes {
392 :
393 : public:
394 :
395 0 : ThreadTimes () { * this = getTime();}
396 :
397 0 : double cpu () const { return cpu_p;}
398 : void clear () { empty_p = true;}
399 : bool empty () const { return empty_p;}
400 0 : double elapsed () const { return elapsed_p;}
401 :
402 : static ThreadTimes
403 0 : getTime (){
404 :
405 : struct timeval tVal;
406 0 : gettimeofday (& tVal, NULL);
407 :
408 0 : double elapsed = tVal.tv_sec + tVal.tv_usec * 1e-6;
409 :
410 : //double cpu = ((double) clock ()) / CLOCKS_PER_SEC; // should be in seconds
411 :
412 :
413 :
414 : #if defined (RUSAGE_THREAD)
415 : struct rusage usage;
416 :
417 0 : int failed = getrusage (RUSAGE_THREAD, & usage);
418 0 : assert (! failed);
419 :
420 0 : double cpu = ! failed ? toSeconds (usage.ru_utime) + toSeconds (usage.ru_stime) : 0;
421 : #else
422 : double cpu = 0;
423 : #endif
424 :
425 0 : return ThreadTimes (elapsed, cpu);
426 : }
427 :
428 : DeltaThreadTimes operator- (const ThreadTimes & tEarlier) const;
429 :
430 : static double
431 0 : toSeconds (const struct timeval & t)
432 : {
433 0 : return t.tv_sec + t.tv_usec * 1e-6;
434 : }
435 :
436 : protected:
437 :
438 : bool empty_p;
439 : double cpu_p;
440 : double elapsed_p;
441 :
442 0 : ThreadTimes (double elapsed, double cpu) : cpu_p (cpu), elapsed_p (elapsed) {}
443 : };
444 :
445 : // <summary>
446 : // </summary>
447 :
448 : // <use visibility=local> or <use visibility=export>
449 :
450 : // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos="">
451 : // </reviewed>
452 :
453 : // <prerequisite>
454 : // <li> SomeClass
455 : // <li> SomeOtherClass
456 : // <li> some concept
457 : // </prerequisite>
458 : //
459 : // <etymology>
460 : // </etymology>
461 : //
462 : // <synopsis>
463 : // </synopsis>
464 : //
465 : // <example>
466 : // </example>
467 : //
468 : // <motivation>
469 : // </motivation>
470 : //
471 : // <templating arg=T>
472 : // <li>
473 : // <li>
474 : // </templating>
475 : //
476 : // <thrown>
477 : // <li>
478 : // <li>
479 : // </thrown>
480 : //
481 : // <todo asof="yyyy/mm/dd">
482 : // <li> add this feature
483 : // <li> fix this bug
484 : // <li> start discussion of this possible extension
485 : // </todo>
486 : class DeltaThreadTimes : private ThreadTimes {
487 :
488 : friend class ThreadTimes;
489 :
490 : public:
491 :
492 0 : DeltaThreadTimes () : ThreadTimes (0, 0), doStats_p (false), n_p (0) {}
493 0 : explicit DeltaThreadTimes (bool doStats) : ThreadTimes (0,0), doStats_p (doStats), n_p (0)
494 : {
495 0 : cpuSsq_p = 0;
496 0 : cpuMin_p = 1e20;
497 0 : cpuMax_p = -1e20;
498 0 : elapsedSsq_p = 0;
499 0 : elapsedMin_p = 1e20;
500 0 : elapsedMax_p = -1e20;
501 0 : }
502 :
503 : DeltaThreadTimes & operator += (const DeltaThreadTimes & other);
504 :
505 0 : double cpu () const { return ThreadTimes::cpu();}
506 : double cpuAvg () const { return n_p == 0 ? 0 : cpu() / n_p;}
507 0 : double elapsed () const { return ThreadTimes::elapsed();}
508 0 : double elapsedAvg () const { return n_p == 0 ? 0 : elapsed() / n_p;}
509 : casacore::String formatAverage (const casacore::String & floatFormat = "%6.1f",
510 : double scale=1000.0,
511 : const casacore::String & units = "ms") const; // to convert to ms
512 : casacore::String formatStats (const casacore::String & floatFormat = "%6.1f",
513 : double scale=1000.0,
514 : const casacore::String & units = "ms") const; // to convert to ms
515 0 : int n() const { return n_p;}
516 :
517 : protected:
518 :
519 0 : DeltaThreadTimes (double elapsed, double cpu) : ThreadTimes (elapsed, cpu), n_p (0) {}
520 :
521 : private:
522 :
523 : double cpuMin_p;
524 : double cpuMax_p;
525 : double cpuSsq_p;
526 : bool doStats_p;
527 : double elapsedMin_p;
528 : double elapsedMax_p;
529 : double elapsedSsq_p;
530 : int n_p;
531 : };
532 :
533 : // Global Functions
534 :
535 : // <linkfrom anchor=unique-string-within-this-file classes="class-1,...,class-n">
536 : // <here> Global functions </here> for foo and bar.
537 : // </linkfrom>
538 :
539 : // A free function is provided that is useful for
540 : // go here...
541 :
542 : // <group name=accumulation>
543 :
544 :
545 : // </group>
546 :
547 : /*
548 :
549 : Example of using composer and unary. The composed functors have to be derived from std::unary_function
550 :
551 : int f(int x) { return x*x;}
552 : int g(int x) { return 2 * x;}
553 : int h(int x) { return 100 + x;}
554 :
555 : vector<int> a;
556 : a.push_back(1);
557 : a.push_back(2);
558 : a.push_back(3);
559 :
560 : transform (a.begin(), a.end(), std::ostream_iterator<int> (cout, "\n"), compose (unary(f), unary(f)));
561 :
562 : // prints out
563 : // 4
564 : // 16
565 : // 36
566 :
567 : transform (a.begin(), a.end(), std::ostream_iterator<int> (cout, "\n"),
568 : compose (unary(h), compose (unary(f), unary(f))));
569 :
570 : // prints out
571 : // 104
572 : // 116
573 : // 136
574 :
575 : */
576 :
577 : template <typename F, typename G>
578 : class ComposedFunctor : public std::unary_function <typename G::argument_type, typename F::result_type> {
579 :
580 : public:
581 :
582 0 : ComposedFunctor (F f, G g) : f_p (f), g_p (g) {}
583 :
584 0 : typename F::result_type operator() (typename G::argument_type x) { return f_p ( g_p (x)); }
585 :
586 : private:
587 :
588 : F f_p;
589 : G g_p;
590 : };
591 :
592 : template <typename F, typename G>
593 : ComposedFunctor<F, G>
594 0 : compose (F f, G g)
595 : {
596 0 : return ComposedFunctor <F, G> (f, g);
597 : }
598 :
599 : template <typename D, typename R>
600 : class UnaryFunctor : public std::unary_function<D,R> {
601 : public:
602 : typedef R (* F) (D);
603 :
604 : UnaryFunctor (F f) : f_p (f) {}
605 : R operator() (D x) { return f_p (x); }
606 :
607 : private:
608 :
609 : F f_p;
610 : };
611 :
612 : template <typename D, typename R>
613 : UnaryFunctor <D, R>
614 : unary (R (*f) (D)) { return UnaryFunctor<D, R> (f);}
615 :
616 : class Z {
617 : public:
618 :
619 : string getName () const { return name_p;}
620 :
621 : string name_p;
622 : };
623 :
624 :
625 :
626 : } // end namespace utilj
627 :
628 : } // end namespace casa
629 :
630 :
631 :
632 : #endif /* UTILJ_H_ */
|