util.h
Go to the documentation of this file.
1 // File: $Id$
2 // Author: John Wu <John.Wu at acm.org> Lawrence Berkeley National Laboratory
3 // Copyright (c) 2000-2016 the Regents of the University of California
4 #ifndef IBIS_UTIL_H
5 #define IBIS_UTIL_H
6 #include "const.h"
11 
12 #include <map> // std::map
13 #include <string> // std::string
14 #include <limits> // std::numeric_limits
15 #include <sstream> // std::ostringstream used by ibis::util::logger
16 #include <cctype> // std::isspace
17 #include <cstring> // std::strcpy
18 
19 #include <float.h>
20 #include <math.h> // fabs, floor, ceil, log10, nextafter...
21 #include <stdlib.h>
22 #include <stdio.h> // sprintf, remove
23 #include <sys/stat.h> // stat, mkdir, chmod
24 #include <fcntl.h> // open, close
25 #if !defined(unix) && defined(_WIN32)
26 # include <windows.h>
27 # include <io.h>
28 # include <fcntl.h> // _O_..
29 # include <direct.h> // _rmdir
30 # include <sys/stat.h> // _stat, mkdir, chmod
31 # define rmdir _rmdir
32  int truncate(const char*, uint32_t);
33 //#elif HAVE_UNISTD_H
34 #else
35 # include <unistd.h> // read, lseek, truncate, rmdir
36 #endif
37 #if defined(HAVE_FLOCK)
38 # include <sys/file.h> // flock
39 #endif
40 #if defined(HAVE_ATOMIC_TEMPLATE)
41 # include <atomic>
42 #endif
43 
44 // minimum size for invoking mmap operation, default to 1 MB
45 #ifndef FASTBIT_MIN_MAP_SIZE
46 #define FASTBIT_MIN_MAP_SIZE 1048576
47 #endif
48 
49 #if ! (defined(HAVE_MMAP) || defined(_MSC_VER))
50 # if defined(unix)||defined(__linux__)||defined(__APPLE__)||defined(__CYGWIN__)
51 # define HAVE_MMAP 1
52 # elif defined(__MINGW32__)
53 # undef HAVE_MMAP
54 # elif defined(_XOPEN_SOURCE)
55 # define HAVE_MMAP _XOPEN_SOURCE - 0 >= 500
56 # elif defined(_POSIX_C_SOURCE)
57 # define HAVE_MMAP _POSIX_C_SOURCE - 0 >= 0
58 # else
59 # undef HAVE_MMAP
60 # endif
61 #endif
62 
63 #if (HAVE_MMAP+0>0) || (defined(_WIN32) && defined(_MSC_VER))
64 #define HAVE_FILE_MAP 1
65 #endif
66 
67 #ifndef DBL_EPSILON
68 #define DBL_EPSILON 2.2204460492503131e-16
69 #else
70 // some wrongly define it to be 1.1e-16
71 #undef DBL_EPSILON
72 #define DBL_EPSILON 2.2204460492503131e-16
73 #endif
74 
75 #ifndef FASTBIT_FLOAT_NULL
76 #define FASTBIT_FLOAT_NULL std::numeric_limits<float>::quiet_NaN()
77 #endif
78 #ifndef FASTBIT_DOUBLE_NULL
79 #define FASTBIT_DOUBLE_NULL std::numeric_limits<double>::quiet_NaN()
80 #endif
81 
83 #if !defined(HAVE_GCC_ATOMIC32) && defined(WITHOUT_FASTBIT_CONFIG_H)
84 #if __GNUC__+0 >= 4 && defined(__linux__)
85 #define HAVE_GCC_ATOMIC32 2
86 #endif
87 #endif
88 #if !defined(HAVE_GCC_ATOMIC64) && defined(WITHOUT_FASTBIT_CONFIG_H)
89 #if defined(__IA64__) || defined(__x86_64__) || defined(__ppc64__)
90 #if __GNUC__+0 >= 4 && defined(__linux__)
91 #define HAVE_GCC_ATOMIC64 2
92 #endif
93 #endif
94 #endif
95 
97 #if defined(_MSC_VER) && defined(_WIN32)
98 #ifndef HAVE_WIN_ATOMIC32
99 #if defined(NTDDI_VERSION) && defined(NTDDI_WIN2K)
100 #if NTDDI_VERSION >= NTDDI_WIN2K
101 #define HAVE_WIN_ATOMIC32
102 #endif
103 #elif defined(WINVER)
104 #if WINVER >= 0x0500
105 #define HAVE_WIN_ATOMIC32
106 #endif
107 #endif
108 #endif
109 #ifndef HAVE_WIN_ATOMIC64
110 #if defined(NTDDI_VERSION) && defined(NTDDI_WINVISTA)
111 #if NTDDI_VERSION >= NTDDI_WINVISTA
112 #define HAVE_WIN_ATOMIC64
113 #endif
114 #elif defined(WINVER)
115 #if WINVER >= 0x0600
116 #define HAVE_WIN_ATOMIC64
117 #endif
118 #endif
119 #endif
120 #endif
121 
122 // mapping the names of the low level IO functions defined in <unistd.h>
123 #if defined(_MSC_VER) && defined(_WIN32)
124 #define UnixOpen ::_open
125 #define UnixClose ::_close
126 #define UnixRead ::_read
127 #define UnixWrite ::_write
128 #define UnixSeek ::_lseek
129 #define UnixFlush ::_commit
130 #define UnixSnprintf ::_snprintf
131 #define UnixStat ::_stat
132 #define UnixFStat ::_fstat
133 #define Stat_T struct _stat
134 #else //_BSD_SOURCE || _ISOC99_SOURCE || _XOPEN_SOURCE >= 500 || _POSIX_C_SOURCE >= 200112L
135 #define UnixOpen ::open
136 #define UnixClose ::close
137 #define UnixRead ::read
138 #define UnixWrite ::write
139 #define UnixSeek ::lseek
140 #define UnixFlush ::fsync
141 #define UnixSnprintf ::snprintf
142 #define UnixStat ::stat
143 #define UnixFStat ::fstat
144 #define Stat_T struct stat
145 #endif
146 
147 // define the option for opening a file in read only mode
148 #if defined(O_RDONLY)
149 #if defined(O_LARGEFILE)
150 #if defined(O_BINARY)
151 #define OPEN_READONLY O_RDONLY | O_BINARY | O_LARGEFILE
152 #else
153 #define OPEN_READONLY O_RDONLY | O_LARGEFILE
154 #endif
155 #elif defined(O_BINARY)
156 #define OPEN_READONLY O_RDONLY | O_BINARY
157 #else
158 #define OPEN_READONLY O_RDONLY
159 #endif
160 #elif defined(_O_RDONLY)
161 #if defined(_O_LARGEFILE)
162 #define OPEN_READONLY _O_RDONLY | _O_LARGEFILE | _O_BINARY
163 #else
164 #define OPEN_READONLY _O_RDONLY | _O_BINARY
165 #endif
166 #endif
167 // define the option for opening a new file for writing
168 #if defined(O_WRONLY)
169 #if defined(O_LARGEFILE)
170 #if defined(O_BINARY)
171 #define OPEN_WRITENEW O_WRONLY | O_BINARY | O_CREAT | O_TRUNC | O_LARGEFILE
172 #else
173 #define OPEN_WRITENEW O_WRONLY | O_CREAT | O_TRUNC | O_LARGEFILE
174 #endif
175 #elif defined(O_BINARY)
176 #define OPEN_WRITENEW O_WRONLY | O_BINARY | O_CREAT | O_TRUNC
177 #else
178 #define OPEN_WRITENEW O_WRONLY | O_CREAT | O_TRUNC
179 #endif
180 #elif defined(_O_WRONLY)
181 #if defined(_O_LARGEFILE)
182 #define OPEN_WRITENEW _O_WRONLY|_O_CREAT|_O_TRUNC|_O_LARGEFILE|_O_BINARY
183 #else
184 #define OPEN_WRITENEW _O_WRONLY|_O_CREAT|_O_TRUNC|_O_BINARY
185 #endif
186 #endif
187 // define the option for opening an existing file for writing
188 #if defined(O_WRONLY)
189 #if defined(O_LARGEFILE)
190 #if defined(O_BINARY)
191 #define OPEN_WRITEADD O_WRONLY | O_BINARY | O_CREAT | O_LARGEFILE
192 #else
193 #define OPEN_WRITEADD O_WRONLY | O_CREAT| O_LARGEFILE
194 #endif
195 #elif defined(O_BINARY)
196 #define OPEN_WRITEADD O_WRONLY | O_BINARY | O_CREAT
197 #else
198 #define OPEN_WRITEADD O_WRONLY | O_CREAT
199 #endif
200 #elif defined(_O_WRONLY)
201 #if defined(_O_LARGEFILE)
202 #define OPEN_WRITEADD _O_WRONLY | _O_CREAT | _O_LARGEFILE | _O_BINARY
203 #else
204 #define OPEN_WRITEADD _O_WRONLY | _O_CREAT | _O_BINARY
205 #endif
206 #endif
207 // define the option for opening a file for reading and writing
208 #if defined(O_RDWR)
209 #if defined(O_LARGEFILE)
210 #if defined(O_BINARY)
211 #define OPEN_READWRITE O_RDWR | O_BINARY | O_CREAT | O_LARGEFILE
212 #else
213 #define OPEN_READWRITE O_RDWR | O_CREAT | O_LARGEFILE
214 #endif
215 #elif defined(O_BINARY)
216 #define OPEN_READWRITE O_RDWR | O_BINARY | O_CREAT
217 #else
218 #define OPEN_READWRITE O_RDWR | O_CREAT
219 #endif
220 #elif defined(_O_RDWR)
221 #if defined(_O_LARGEFILE)
222 #define OPEN_READWRITE _O_RDWR | _O_CREAT | _O_LARGEFILE | _O_BINARY
223 #else
224 #define OPEN_READWRITE _O_RDWR | _O_CREAT | _O_BINARY
225 #endif
226 #endif
227 // define the option for opening an existing file for appending only
228 #if defined(O_WRONLY)
229 #if defined(O_LARGEFILE)
230 #if defined(O_BINARY)
231 #define OPEN_APPENDONLY O_WRONLY | O_BINARY | O_CREAT | O_APPEND | O_LARGEFILE
232 #else
233 #define OPEN_APPENDONLY O_WRONLY | O_CREAT | O_APPEND | O_LARGEFILE
234 #endif
235 #elif defined(O_BINARY)
236 #define OPEN_APPENDONLY O_WRONLY | O_BINARY | O_CREAT | O_APPEND
237 #else
238 #define OPEN_APPENDONLY O_WRONLY | O_CREAT | O_APPEND
239 #endif
240 #elif defined(_O_WRONLY)
241 #if defined(_O_LARGEFILE)
242 #define OPEN_APPENDONLY _O_WRONLY | _O_CREAT | _O_APPEND | _O_LARGEFILE | _O_BINARY
243 #else
244 #define OPEN_APPENDONLY _O_WRONLY | _O_CREAT | _O_APPEND | _O_BINARY
245 #endif
246 #endif
247 // the default file mode (associate with _O_CREAT)
248 #if defined(_MSC_VER) && defined(_WIN32)
249 #define OPEN_FILEMODE _S_IREAD | _S_IWRITE
250 #elif defined(S_IRGRP) && defined(S_IWGRP) && defined(S_IROTH)
251 #define OPEN_FILEMODE S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH
252 #else
253 #define OPEN_FILEMODE S_IRUSR | S_IWUSR
254 #endif
255 
256 #if defined(_MSC_VER)
257 
258 #define FORCE_INLINE __forceinline
259 
260 #include <stdlib.h>
261 
262 #define BIG_CONSTANT(x) (x)
263 
264 // Other compilers
265 
266 #else // defined(_MSC_VER)
267 
268 #define FORCE_INLINE inline __attribute__((always_inline))
269 
270 inline uint32_t _rotl32( uint32_t x, int8_t r ) {
271  return (x << r) | (x >> (32 - r));
272 }
273 
274 inline uint64_t _rotl64( uint64_t x, int8_t r ) {
275  return (x << r) | (x >> (64 - r));
276 }
277 
278 #define BIG_CONSTANT(x) (x##LLU)
279 #endif // !defined(_MSC_VER)
280 #define FASTBIT_ROTL32(x,y) _rotl32(x,y)
281 #define FASTBIT_ROTL64(x,y) _rotl64(x,y)
282 
283 #if defined(_WIN32) && defined(_MSC_VER)
284 // needed for numeric_limits<>::max, min function calls
285 #ifdef max
286 #undef max
287 #endif
288 #ifdef min
289 #undef min
290 #endif
291 #endif
292 
293 #ifndef FASTBIT_CASE_SENSITIVE_COMPARE
294 // By default use case sensitive comparisons for string values when
295 // evaluating SQL LIKE statements. Explicitly set this to 0 before
296 // compiling to allow case insensitive evaluations.
297 #define FASTBIT_CASE_SENSITIVE_COMPARE 1
298 #endif
299 
300 // The meta characters used in ibis::util::strMatch.
301 #define STRMATCH_META_CSH_ANY '*'
302 #define STRMATCH_META_CSH_ONE '?'
303 #define STRMATCH_META_SQL_ANY '%'
304 #define STRMATCH_META_SQL_ONE '_'
305 #define STRMATCH_META_ESCAPE '\\'
306 
307 // // The function isfinite is a macro defined in math.h according to
308 // // opengroup.org. As of 2011, only MS visual studio does not have a
309 // // definition for isfinite, but it has _finite in float,h.
310 // #if defined(_MSC_VER) && defined(_WIN32)
311 // inline int isfinite(double x) {return _finite(x);}
312 // #elif !defined(isfinite)
313 // #define isfinite finite
314 // #endif
315 #define IBIS_2STR(x) #x
316 #define IBIS_INT_STR(x) IBIS_2STR(x)
317 #define IBIS_FILE_LINE " -- " __FILE__ ":" IBIS_INT_STR(__LINE__)
318 
319 #define LOGGER(v) \
320  if (false == (v)) ; else ibis::util::logger(0)()
321 // need these silly intermediate macro functions to force the arguments to
322 // be evaluated before ## is applied
323 #define IBIS_JOIN_MACRO2(X, Y) X##Y
324 #define IBIS_JOIN_MACRO(X, Y) IBIS_JOIN_MACRO2(X, Y)
325 #ifdef __GNUC__
326 #define IBIS_GUARD_NAME IBIS_JOIN_MACRO(_guard, __LINE__) __attribute__( ( unused ) )
327 #else
328 #define IBIS_GUARD_NAME IBIS_JOIN_MACRO(_guard, __LINE__)
329 #endif
330 #define IBIS_BLOCK_GUARD \
331  ibis::util::guard IBIS_GUARD_NAME = ibis::util::makeGuard
332 
333 namespace std { // extend namespace std slightly
334  // specialization of less<> to work with char*
335  template <> struct less< char* > {
336  bool operator()(const char*x, const char*y) const {
337  return std::strcmp(x, y) < 0;
338  }
339  };
340 
341  // specialization of less<> on const char* (case sensitive comparison)
342  template <> struct less< const char* > {
343  bool operator()(const char* x, const char* y) const {
344  return std::strcmp(x, y) < 0;
345  }
346  };
347 
348  // specialization of equal_to<> on const char* (case sensitive comparison)
349  template <> struct equal_to< const char* > {
350  bool operator()(const char* x, const char* y) const {
351  return std::strcmp(x, y) == 0;
352  }
353  };
354 
355  template <> struct less< ibis::rid_t > {
356  bool operator()(const ibis::rid_t& x, const ibis::rid_t& y) const {
357  return (x < y);
358  }
359  };
360 
361  template <> struct less< const ibis::rid_t* > {
362  bool operator()(const ibis::rid_t* x, const ibis::rid_t* y) const {
363  return (*x < *y);
364  }
365  };
366 } // namespace std
367 
368 namespace ibis {
371  class resource;
372  class bitvector;
373  class column;
374  class fileManager;
375  class horometer;
376  class index;
377  class roster;
378  class bitvector64;
379 
380  class dictionary;
381  class bundle;
382  class colValues;
383 
384  class fromClause;
385  class whereClause;
386  class selectClause;
387 
390  extern FASTBIT_CXX_DLLSPEC partList datasets;
391 
392  typedef std::vector<colValues*> colList;
393 
395  FASTBIT_CXX_DLLSPEC ibis::resource& gParameters();
396 
399  class FASTBIT_CXX_DLLSPEC nameList {
400  public:
401  nameList() : cstr(0), buff(0) {};
402  nameList(const char* str) : cstr(0), buff(0) {select(str);}
403  ~nameList() {if (cstr) clear();}
404 
405  bool empty() const {return cstr == 0;}
406  const char* operator*() const {return cstr;};
407  uint32_t size() const {return cvec.size();};
408 
410  void select(const char* str);
412  void add(const char* str);
416  uint32_t find(const char* key) const;
417 
418  const char* operator[](uint32_t i) const {return cvec[i];}
419  typedef std::vector< const char* >::const_iterator const_iterator;
420  const_iterator begin() const {return cvec.begin();}
421  const_iterator end() const {return cvec.end();}
422 
423  void clear()
424  {cvec.clear(); delete [] cstr; delete [] buff; buff=0; cstr=0;}
425 
426  private:
427  typedef std::vector< const char * > compStore;
428  char* cstr; // copy of the names as a single string
429  char* buff; // same as cstr, but delimiter is \0
430  compStore cvec; // contains pointers to buff, for easier access
431 
432  nameList(const nameList&);
433  nameList& operator=(const nameList&);
434  }; // class nameList
435 
438  typedef std::map< const char*, part*, lessi > partAssoc;
439 
441  class bad_alloc : public std::bad_alloc {
442  public:
446  bad_alloc(const char *m="unknown") throw() : mesg_(m) {};
447  virtual ~bad_alloc() throw() {}
448  virtual const char* what() const throw() {return mesg_;}
449 
450  private:
453  const char *mesg_;
454  }; // bad_alloc
455 
457  namespace util {
459  extern const char* charTable;
461  extern const short unsigned charIndex[];
463  extern const char* delimiters;
465  extern const int log2table[256];
472  extern FASTBIT_CXX_DLLSPEC pthread_mutex_t envLock;
473 
475  inline char* trim(char* str);
477  char* strnewdup(const char* s);
479  char* strnewdup(const char* s, const uint32_t n);
481  inline void removeTail(char* str, char tail);
482  char* getString(const char* buf);
483  const char* getToken(char*& str, const char* tok_chrs);
484  int readInt(int64_t& val, const char *&str,
485  const char* del=ibis::util::delimiters);
486  int readUInt(uint64_t& val, const char *&str,
487  const char* del=ibis::util::delimiters);
488  int readDouble(double& val, const char *&str,
489  const char* del=ibis::util::delimiters);
490  FASTBIT_CXX_DLLSPEC int
491  readString(std::string& str, const char*& buf,
492  const char *delim=0);
493  FASTBIT_CXX_DLLSPEC const char*
494  readString(char*& buf, const char *delim=0);
495 
496  int64_t read(int, void*, int64_t);
497  int64_t write(int, const void*, int64_t);
498 
499  void removeDir(const char* name, bool leaveDir=false);
500  int makeDir(const char* dir);
501  FASTBIT_CXX_DLLSPEC off_t getFileSize(const char* name);
502  int copy(const char* to, const char* from);
503 
507  inline void setVerboseLevel(int v) {ibis::gVerbose=v;}
509  FASTBIT_CXX_DLLSPEC const char* userName();
510  uint32_t serialNumber();
511  void uniformFraction(const long unsigned idx,
512  long unsigned &denominator,
513  long unsigned &numerator);
514  inline double rand();
515 
517  FASTBIT_CXX_DLLSPEC uint32_t checksum(const char* str, uint32_t sz);
518  inline uint32_t checksum(uint32_t a, uint32_t b);
519  std::string shortName(const std::string& longname);
520  std::string randName(const std::string& longname);
522 
524  void int2string(std::string &str, unsigned val);
525  void int2string(std::string &str, unsigned v1, unsigned v2);
526  void int2string(std::string &str, unsigned v1,
527  unsigned v2, unsigned v3);
528  void int2string(std::string &str, const std::vector<unsigned>& val);
529  void encode64(uint64_t, std::string&);
530  int decode64(uint64_t&, const std::string&);
531  int decode16(uint64_t&, const char*);
532  std::string groupby1000(uint64_t);
534 
537  double incrDouble(const double&);
538  double decrDouble(const double&);
539  void eq2range(const double&, double&, double&);
542  inline double coarsen(const double in, unsigned prec=2);
545  double compactValue(double left, double right,
546  double start=0.0);
547 
550  double compactValue2(double left, double right,
551  double start=0.0);
552 
554  void setNaN(double& val);
555  void setNaN(float& val);
556 
560  template <typename Tin, typename Tout>
561  void round_down(const Tin& inval, Tout& outval) {
562  outval = (std::numeric_limits<Tout>::min() > inval ?
563  std::numeric_limits<Tout>::min() :
564  (double)std::numeric_limits<Tout>::max() <= inval ?
565  std::numeric_limits<Tout>::max() :
566  static_cast<Tout>(inval));
567  }
571  template <typename Tin, typename Tout>
572  void round_up(const Tin& inval, Tout& outval) {
573  outval = (std::numeric_limits<Tout>::min() >= inval ?
574  std::numeric_limits<Tout>::min() :
575  (double) std::numeric_limits<Tout>::max() < inval ?
576  std::numeric_limits<Tout>::max() :
577  static_cast<Tout>(inval) +
578  ((inval-static_cast<Tin>(static_cast<Tout>(inval))) > 0));
579  }
581  template <typename Tin>
582  void round_up(const Tin& inval, float&);
584  template <typename Tin>
585  void round_up(const Tin& inval, double& outval) {
586  outval = static_cast<double>(inval);
587  }
588 
590  inline int log2(uint32_t x) {
591  uint32_t xx, xxx;
592  return (xx = x >> 16)
593  ? (xxx = xx >> 8) ? 24 + log2table[xxx] : 16 + log2table[xx]
594  : (xxx = x >> 8) ? 8 + log2table[xxx] : log2table[x];
595  }
597  inline int log2(uint64_t x) {
598  uint32_t xx;
599  return (xx = x >> 32)
600  ? 32 + log2(xx)
601  : log2(static_cast<uint32_t>(x));
602  }
604 
605  FASTBIT_CXX_DLLSPEC void
606  logMessage(const char* event, const char* fmt, ...);
607  FASTBIT_CXX_DLLSPEC FILE* getLogFile();
608  int writeLogFileHeader(FILE *fptr, const char* fname);
609  FASTBIT_CXX_DLLSPEC void closeLogFile();
610  FASTBIT_CXX_DLLSPEC int setLogFileName(const char* filename);
611  FASTBIT_CXX_DLLSPEC const char* getLogFileName();
612 
613  FASTBIT_CXX_DLLSPEC bool strMatch(const char* str, const char* pat);
614  FASTBIT_CXX_DLLSPEC bool nameMatch(const char* str, const char* pat);
615 
618  const ibis::bitvector& b,
619  ibis::bitvector64& c);
623  const ibis::bitvector& b,
624  ibis::bitvector64& c);
625 
627  long intersect(const std::vector<ibis::bitvector> &bits1,
628  const std::vector<ibis::bitvector> &bits2,
629  std::vector<ibis::bitvector> &res);
631  long intersect(const std::vector<ibis::bitvector> &bits1,
632  const std::vector<ibis::bitvector> &bits2,
633  const std::vector<ibis::bitvector> &bits3,
634  std::vector<ibis::bitvector> &res);
635  void clear(ibis::array_t<ibis::bitvector*> &bv) throw();
636  void clear(ibis::partList &pl) throw();
637  void updateDatasets(void);
638  void emptyCache(void);
639 
642  inline const char* getVersionString() {
643  return FASTBIT_STRING;
644  }
651  inline int getVersionNumber() {
652 #ifdef FASTBIT_IBIS_INT_VERSION
653  return FASTBIT_IBIS_INT_VERSION;
654 #else
655  return 1030000;
656 #endif
657  }
658 
660  void getLocalTime(char *str);
662  void getGMTime(char *str);
663  void secondsToString(const time_t, char *str);
664 
665 
666 #if defined(WIN32) && ! defined(__CYGWIN__)
667  char* getpass_r(const char *prompt, char *buffer, uint32_t buflen);
668  char* getpass(const char* prompt);
669 #else
670  inline char *itoa(int value, char *str, int /* radix */) {
671  sprintf(str,"%d",value);
672  return str;
673  }
674 #endif
675 
677  template <typename T> inline void
678  clearVec(std::vector<T*> &v) {
679  const size_t nv = v.size();
680  for (size_t j = 0; j < nv; ++j)
681  delete v[j];
682  v.clear();
683  } // clearVec
684 
693  class FASTBIT_CXX_DLLSPEC logger {
694  public:
696  logger(int blanks=0);
698  ~logger();
700  std::ostream& operator()(void) {return mybuffer;}
701  std::string str() const;
702  const char* c_str() const;
703 
704  protected:
706  std::ostringstream mybuffer;
707 
708  private:
709  logger(const logger&);
710  logger& operator=(const logger&);
711  }; // logger
712 
715  class ioLock {
716  public:
717  ioLock() {
718 #if defined(PTW32_STATIC_LIB)
719  if (mutex == PTHREAD_MUTEX_INITIALIZER) {
720  int ierr = pthread_mutex_init(&mutex, 0);
721  if (ierr != 0)
722  throw "ioLock failed to initialize the necessary mutex";
723  }
724 #endif
725  if (0 != pthread_mutex_lock(&mutex))
726  throw "ioLock failed to obtain a lock";
727  }
728  ~ioLock() {
729  (void) pthread_mutex_unlock(&mutex);
730  }
731  private:
732  // every instantiation of this class locks on the same mutex
733  static pthread_mutex_t mutex;
734 
735  ioLock(const ioLock&) {}; // can not copy
736  ioLock& operator=(const ioLock&);
737  };
738 
740  class mutexLock {
741  public:
742  mutexLock(pthread_mutex_t* lk, const char* m)
743  : mesg(m), lock(lk) {
744  LOGGER(ibis::gVerbose > 10)
745  << "util::mutexLock -- acquiring lock (" << lock
746  << ") for " << mesg;
747  if (0 != pthread_mutex_lock(lock)) {
748  throw "mutexLock failed to obtain a lock";
749  }
750  }
751  ~mutexLock() {
752  LOGGER(ibis::gVerbose > 10)
753  << "util::mutexLock -- releasing lock (" << lock
754  << ") for " << mesg;
755  (void) pthread_mutex_unlock(lock);
756  }
757 
758  private:
759  const char *mesg;
760  pthread_mutex_t *lock;
761 
762  mutexLock() : mesg(0), lock(0) {}; // no default constructor
763  mutexLock(const mutexLock&); // can not copy
764  mutexLock& operator=(const mutexLock&);
765  }; // mutexLock
766 
770  class quietLock {
771  public:
773  quietLock(pthread_mutex_t *lk) : lock(lk) {
774  if (0 != pthread_mutex_lock(lock))
775  throw "quietLock failed to obtain a mutex lock";
776  }
779  (void) pthread_mutex_unlock(lock);
780  }
781 
782  private:
784  pthread_mutex_t *lock;
785 
786  quietLock(); // no default constructor
787  quietLock(const quietLock&); // can not copy
788  quietLock& operator=(const quietLock&);
789  }; // quietLock
790 
793  class softLock {
794  public:
796  softLock(pthread_mutex_t *lk)
797  : lock_(lk), locked_(pthread_mutex_trylock(lock_)) {}
800  bool isLocked() const {return (locked_==0);}
803  (void) pthread_mutex_unlock(lock_);
804  }
805 
806  private:
808  pthread_mutex_t *lock_;
810  const int locked_;
811 
812  softLock(); // no default constructor
813  softLock(const softLock&); // can not copy
814  softLock& operator=(const softLock&);
815  }; // softLock
816 
818  class readLock {
819  public:
820  readLock(pthread_rwlock_t* lk, const char* m)
821  : mesg(m), lock(lk) {
822  if (0 != pthread_rwlock_rdlock(lock)) {
823  throw "readLock failed to obtain a lock";
824  }
825  }
826  ~readLock() {
827  (void) pthread_rwlock_unlock(lock);
828  }
829 
830  private:
831  const char *mesg;
832  pthread_rwlock_t *lock;
833 
834  readLock() : mesg(0), lock(0) {}; // no default constructor
835  readLock(const readLock&); // can not copy
836  readLock& operator=(const readLock&);
837  }; // readLock
838 
840  class writeLock {
841  public:
843  writeLock(pthread_rwlock_t* lk, const char* m)
844  : mesg(m), lock(lk) {
845  if (0 != pthread_rwlock_wrlock(lock)) {
846  throw "writeLock failed to obtain a lock";
847  }
848  }
851  (void) pthread_rwlock_unlock(lock);
852  }
853 
854  private:
855  const char *mesg;
856  pthread_rwlock_t *lock;
857 
858  writeLock() : mesg(0), lock(0) {}; // no default constructor
859  writeLock(const writeLock&); // can not copy
860  writeLock& operator=(const writeLock&);
861  }; // writeLock
862 
869  class FASTBIT_CXX_DLLSPEC counter {
870  public:
871  ~counter() {
872 #if defined(HAVE_GCC_ATOMIC32)
873 #elif defined(HAVE_WIN_ATOMIC32)
874 #else
875  (void)pthread_mutex_destroy(&lock_);
876 #endif
877  }
878  counter() : count_(0) {
879 #if defined(HAVE_GCC_ATOMIC32)
880 #elif defined(HAVE_WIN_ATOMIC32)
881 #else
882  if (0 != pthread_mutex_init(&lock_, 0))
883  throw ibis::bad_alloc
884  ("util::counter failed to initialize mutex lock");
885 #endif
886  }
887 
889  uint32_t operator()() {
890 #if defined(HAVE_GCC_ATOMIC32)
891  return __sync_fetch_and_add(&count_, 1);
892 #elif defined(HAVE_WIN_ATOMIC32)
893  return InterlockedIncrement((volatile long *)&count_)-1;
894 #else
895  ibis::util::quietLock lck(&lock_);
896  uint32_t ret = count_;
897  ++ count_;
898  return ret;
899 #endif
900  }
902  void reset() {
903 #if defined(HAVE_GCC_ATOMIC32)
904  (void) __sync_fetch_and_sub(&count_, count_);
905 #elif defined(HAVE_WIN_ATOMIC32)
906  (void) InterlockedExchange((volatile long *)&count_, 0);
907 #else
908  ibis::util::quietLock lck(&lock_);
909  count_ = 0;
910 #endif
911  }
913  uint32_t value() const {
914  return count_;
915  }
916 
917  private:
918 #if defined(HAVE_GCC_ATOMIC32)
919 #elif defined(HAVE_WIN_ATOMIC32)
920 #else
921  mutable pthread_mutex_t lock_;
922 #endif
923  volatile uint32_t count_;
924 
926  counter(const counter&);
928  counter& operator=(const counter&);
929  }; // counter
930 
945  class FASTBIT_CXX_DLLSPEC sharedInt32 {
946  public:
947  sharedInt32() : val_(0) {
948 #if defined(HAVE_ATOMIC_TEMPLATE)
949 #elif defined(HAVE_GCC_ATOMIC32)
950 #elif defined(HAVE_WIN_ATOMIC32)
951 #else
952  if (pthread_mutex_init(&mytex, 0) != 0)
953  throw "pthread_mutex_init failed for sharedInt";
954 #endif
955  }
956 
957  ~sharedInt32() {
958 #if defined(HAVE_ATOMIC_TEMPLATE)
959 #elif defined(HAVE_GCC_ATOMIC32)
960 #elif defined(HAVE_WIN_ATOMIC32)
961 #else
962  (void)pthread_mutex_destroy(&mytex);
963 #endif
964  }
965 
967  uint32_t operator()() const {
968 #if defined(HAVE_ATOMIC_TEMPLATE)
969  return val_.load();
970 #elif defined(HAVE_GCC_ATOMIC32)
971  return __sync_add_and_fetch(const_cast<uint32_t*>(&val_), 0);
972 #elif defined(HAVE_WIN_ATOMIC32)
973  return val_;
974 #else
975  ibis::util::quietLock lck(const_cast<pthread_mutex_t*>(&mytex));
976  return val_;
977 #endif
978  }
979 
981  uint32_t operator++() {
982 #if defined(HAVE_ATOMIC_TEMPLATE)
983  ++ val_;
984  return val_.load();
985 #elif defined(HAVE_GCC_ATOMIC32)
986  return __sync_add_and_fetch(&val_, 1);
987 #elif defined(HAVE_WIN_ATOMIC32)
988  return InterlockedIncrement((volatile long *)&val_);
989 #else
990  ibis::util::quietLock lock(&mytex);
991  ++ val_;
992  return val_;
993 #endif
994  }
995 
997  uint32_t operator--() {
998 #if defined(HAVE_ATOMIC_TEMPLATE)
999  -- val_;
1000  return val_.load();
1001 #elif defined(HAVE_GCC_ATOMIC32)
1002  return __sync_sub_and_fetch(&val_, 1);
1003 #elif defined(HAVE_WIN_ATOMIC32)
1004  return InterlockedDecrement((volatile long *)&val_);
1005 #else
1006  ibis::util::quietLock lock(&mytex);
1007  -- val_;
1008  return val_;
1009 #endif
1010  }
1011 
1013  void operator+=(const uint32_t rhs) {
1014 #if defined(HAVE_ATOMIC_TEMPLATE)
1015  (void) val_.fetch_add(rhs);
1016 #elif defined(HAVE_GCC_ATOMIC32)
1017  (void) __sync_add_and_fetch(&val_, rhs);
1018 #elif defined(HAVE_WIN_ATOMIC32)
1019  (void) InterlockedExchangeAdd((volatile long *)&val_, rhs);
1020 #else
1021  ibis::util::quietLock lock(&mytex);
1022  val_ += rhs;
1023 #endif
1024  }
1025 
1027  void operator-=(const uint32_t rhs) {
1028 #if defined(HAVE_ATOMIC_TEMPLATE)
1029  (void) val_.fetch_sub(rhs);
1030 #elif defined(HAVE_GCC_ATOMIC32)
1031  (void) __sync_sub_and_fetch(&val_, rhs);
1032 #elif defined(HAVE_WIN_ATOMIC32)
1033  (void) InterlockedExchangeAdd((volatile long *)&val_,
1034  -(long)rhs);
1035 #else
1036  ibis::util::quietLock lock(&mytex);
1037  val_ -= rhs;
1038 #endif
1039  }
1040 
1041 // /// Swap the contents of two integer variables.
1042 // void swap(sharedInt32 &rhs) {
1043 // #if defined(HAVE_GCC_ATOMIC32)
1044 // uint32_t tmp = rhs.val_;
1045 // rhs.val_ = val_;
1046 // val_ = tmp;
1047 // #elif defined(HAVE_WIN_ATOMIC32)
1048 // uint32_t tmp = rhs.val_;
1049 // rhs.val_ = val_;
1050 // val_ = tmp;
1051 // #else
1052 // ibis::util::quietLock lock(&mytex);
1053 // uint32_t tmp = rhs.val_;
1054 // rhs.val_ = val_;
1055 // val_ = tmp;
1056 // #endif
1057 // }
1058 
1059  private:
1060 #if defined(HAVE_ATOMIC_TEMPLATE)
1061  std::atomic<uint32_t> val_;
1063 #elif defined(HAVE_GCC_ATOMIC32)
1064  uint32_t volatile val_;
1066 #elif defined(HAVE_WIN_ATOMIC32)
1067  uint32_t volatile val_;
1069 #else
1070  uint32_t volatile val_;
1073  pthread_mutex_t mytex;
1074 #endif
1075 
1076  sharedInt32(const sharedInt32&); // no copy constructor
1077  sharedInt32& operator=(const sharedInt32&); // no assignment
1078  }; // sharedInt32
1079 
1086  class sharedInt64 {
1087  public:
1088  sharedInt64() : val_(0) {
1089 #if defined(HAVE_ATOMIC_TEMPLATE)
1090 #elif defined(HAVE_GCC_ATOMIC64)
1091 #elif defined(HAVE_WIN_ATOMIC64)
1092 #else
1093  if (pthread_mutex_init(&mytex, 0) != 0)
1094  throw "pthread_mutex_init failed for sharedInt";
1095 #endif
1096  }
1097 
1098  ~sharedInt64() {
1099 #if defined(HAVE_ATOMIC_TEMPLATE)
1100 #elif defined(HAVE_GCC_ATOMIC64)
1101 #elif defined(HAVE_WIN_ATOMIC64)
1102 #else
1103  (void)pthread_mutex_destroy(&mytex);
1104 #endif
1105  }
1106 
1108  uint64_t operator()() const {
1109 #if defined(HAVE_ATOMIC_TEMPLATE)
1110  return val_.load();
1111 #elif defined(HAVE_GCC_ATOMIC64)
1112  return __sync_add_and_fetch(const_cast<uint64_t*>(&val_), 0);
1113 #elif defined(HAVE_WIN_ATOMIC64)
1114  return val_;
1115 #else
1116  ibis::util::quietLock lck(const_cast<pthread_mutex_t*>(&mytex));
1117  return val_;
1118 #endif
1119  }
1120 
1122  uint64_t operator++() {
1123 #if defined(HAVE_ATOMIC_TEMPLATE)
1124  ++ val_;
1125  return val_.load();
1126 #elif defined(HAVE_GCC_ATOMIC64)
1127  return __sync_add_and_fetch(&val_, 1);
1128 #elif defined(HAVE_WIN_ATOMIC64)
1129  return InterlockedIncrement64((volatile LONGLONG *)&val_);
1130 #else
1131  ibis::util::quietLock lock(&mytex);
1132  ++ val_;
1133  return val_;
1134 #endif
1135  }
1136 
1138  uint64_t operator--() {
1139 #if defined(HAVE_ATOMIC_TEMPLATE)
1140  -- val_;
1141  return val_.load();
1142 #elif defined(HAVE_GCC_ATOMIC64)
1143  return __sync_sub_and_fetch(&val_, 1);
1144 #elif defined(HAVE_WIN_ATOMIC64)
1145  return InterlockedDecrement64((volatile LONGLONG *)&val_);
1146 #else
1147  ibis::util::quietLock lock(&mytex);
1148  -- val_;
1149  return val_;
1150 #endif
1151  }
1152 
1154  void operator+=(const uint64_t rhs) {
1155 #if defined(HAVE_ATOMIC_TEMPLATE)
1156  (void) val_.fetch_add(rhs);
1157 #elif defined(HAVE_GCC_ATOMIC64)
1158  (void) __sync_add_and_fetch(&val_, rhs);
1159 #elif defined(HAVE_WIN_ATOMIC64)
1160  (void) InterlockedExchangeAdd64((volatile LONGLONG *)&val_,
1161  rhs);
1162 #else
1163  ibis::util::quietLock lock(&mytex);
1164  val_ += rhs;
1165 #endif
1166  }
1167 
1169  void operator-=(const uint64_t rhs) {
1170 #if defined(HAVE_ATOMIC_TEMPLATE)
1171  (void) val_.fetch_sub(rhs);
1172 #elif defined(HAVE_GCC_ATOMIC64)
1173  (void) __sync_sub_and_fetch(&val_, rhs);
1174 #elif defined(HAVE_WIN_ATOMIC64)
1175  (void) InterlockedExchangeAdd64((volatile LONGLONG *)&val_,
1176  -(long)rhs);
1177 #else
1178  ibis::util::quietLock lock(&mytex);
1179  val_ -= rhs;
1180 #endif
1181  }
1182 
1183 // /// Swap the contents of two integer variables.
1184 // void swap(sharedInt64 &rhs) {
1185 // #if defined(HAVE_GCC_ATOMIC64)
1186 // uint64_t tmp = rhs.val_;
1187 // rhs.val_ = val_;
1188 // val_ = tmp;
1189 // #elif defined(HAVE_WIN_ATOMIC64)
1190 // uint64_t tmp = rhs.val_;
1191 // rhs.val_ = val_;
1192 // val_ = tmp;
1193 // #else
1194 // ibis::util::quietLock lock(&mytex);
1195 // uint64_t tmp = rhs.val_;
1196 // rhs.val_ = val_;
1197 // val_ = tmp;
1198 // #endif
1199 // }
1200 
1201  private:
1202 #if defined(HAVE_ATOMIC_TEMPLATE)
1203  std::atomic<uint64_t> val_;
1205 #elif defined(HAVE_GCC_ATOMIC64)
1206  uint64_t volatile val_;
1208 #elif defined(HAVE_WIN_ATOMIC64)
1209  uint64_t volatile val_;
1211 #else
1212  uint64_t volatile val_;
1215  pthread_mutex_t mytex;
1216 #endif
1217 
1218  sharedInt64(const sharedInt64&); // no copy constructor
1219  sharedInt64& operator=(const sharedInt64&); // no assignment
1220  }; // sharedInt64
1221 
1230  class timer {
1231  public:
1232  explicit timer(const char* msg, int lvl=1);
1233  ~timer();
1234 
1235  private:
1236  ibis::horometer *chrono_;
1237  std::string mesg_;
1238 
1239  timer(); // no default constructor
1240  timer(const timer&); // no copying
1241  timer& operator=(const timer&); // no assignment
1242  }; // timer
1243 
1245  template <class T> class refHolder {
1246  public:
1247  refHolder(T& r) : ref_(r) {}
1248  operator T& () const {return ref_;}
1249 
1250  private:
1251  T& ref_;
1252 
1253  refHolder();
1254  }; // refHolder
1255 
1257  template <class T>
1258  inline refHolder<T> ref(T& r) {return refHolder<T>(r);}
1259 
1262  class guardBase {
1263  public:
1266  void dismiss() const {done_ = true;}
1267 
1268  protected:
1269  mutable volatile bool done_;
1270 
1273  guardBase() : done_(false) {};
1274  guardBase(const guardBase& rhs) : done_(rhs.done_) {
1277  rhs.dismiss();
1278  }
1279 
1282  template <typename T>
1283  static void cleanup(T& task) throw () {
1284  try {
1285  if (!task.done_)
1286  task.execute();
1287  }
1288  catch (const std::exception& e) {
1289  LOGGER(ibis::gVerbose > 1)
1290  << " ... caught a std::exception (" << e.what()
1291  << ") in util::gard";
1292  }
1293  catch (const char* s) {
1294  LOGGER(ibis::gVerbose > 1)
1295  << " ... caught a string exception (" << s
1296  << ") in util::guard";
1297  }
1298  catch (...) {
1299  LOGGER(ibis::gVerbose > 1)
1300  << " ... caught a unknown exception in util::guard";
1301  }
1302  task.done_ = true;
1303  }
1304  }; // guardBase
1305 
1319  typedef const guardBase& guard;
1320 
1323  template <typename F>
1324  class guardImpl0 : public guardBase {
1325  public:
1326  static guardImpl0<F> makeGuard(F f) {
1327  return guardImpl0<F>(f);
1328  }
1329 
1331  ~guardImpl0() {cleanup(*this);}
1332 
1333  protected:
1334  friend class guardBase; // to call function execute
1335  void execute() {fun_();}
1336 
1338  explicit guardImpl0(F f) : fun_(f) {}
1339 
1340  private:
1342  F fun_;
1343 
1344  guardImpl0();
1345  guardImpl0& operator=(const guardImpl0&);
1346  }; // guardImpl0
1347 
1348  template <typename F>
1349  inline guardImpl0<F> makeGuard(F f) {
1350  return guardImpl0<F>::makeGuard(f);
1351  }
1352 
1355  template <typename F, typename A>
1356  class guardImpl1 : public guardBase {
1357  public:
1358  static guardImpl1<F, A> makeGuard(F f, A a) {
1359  return guardImpl1<F, A>(f, a);
1360  }
1361 
1363  ~guardImpl1() {cleanup(*this);}
1364 
1365  protected:
1366  friend class guardBase; // to call function execute
1367  void execute() {fun_(arg_);}
1368 
1370  explicit guardImpl1(F f, A a) : fun_(f), arg_(a) {}
1371 
1372  private:
1374  F fun_;
1376  A arg_;
1377 
1378  guardImpl1();
1379  guardImpl1& operator=(const guardImpl1&);
1380  }; // guardImpl1
1381 
1382  template <typename F, typename A>
1383  inline guardImpl1<F, A> makeGuard(F f, A a) {
1384  return guardImpl1<F, A>::makeGuard(f, a);
1385  }
1386 
1389  template <typename F, typename A1, typename A2>
1390  class guardImpl2 : public guardBase {
1391  public:
1392  static guardImpl2<F, A1, A2> makeGuard(F f, A1 a1, A2 a2) {
1393  return guardImpl2<F, A1, A2>(f, a1, a2);
1394  }
1395 
1397  ~guardImpl2() {cleanup(*this);}
1398 
1399  protected:
1400  friend class guardBase; // to call function execute
1401  void execute() {fun_(arg1_, arg2_);}
1402 
1404  explicit guardImpl2(F f, A1 a1, A2 a2)
1405  : fun_(f), arg1_(a1), arg2_(a2) {}
1406 
1407  private:
1409  F fun_;
1411  A1 arg1_;
1413  A2 arg2_;
1414 
1415  guardImpl2();
1416  //guardImpl2(const guardImpl2&);
1417  guardImpl2& operator=(const guardImpl2&);
1418  }; // guardImpl2
1419 
1420  template <typename F, typename A1, typename A2>
1421  inline guardImpl2<F, A1, A2> makeGuard(F f, A1 a1, A2 a2) {
1422  return guardImpl2<F, A1, A2>::makeGuard(f, a1, a2);
1423  }
1424 
1426  template <class C, typename F>
1427  class guardObj0 : public guardBase {
1428  public:
1429  static guardObj0<C, F> makeGuard(C& o, F f) {
1430  return guardObj0<C, F>(o, f);
1431  }
1432 
1434  ~guardObj0() {cleanup(*this);}
1435 
1436  protected:
1437  friend class guardBase; // to call function execute
1438  void execute() {(obj_.*fun_)();}
1439 
1441  guardObj0(C& o, F f) : obj_(o), fun_(f) {}
1442 
1443  private:
1444  C& obj_;
1445  F fun_;
1446 
1447  guardObj0();
1448  guardObj0& operator=(const guardObj0&);
1449  }; // guardObj0
1450 
1451  template <class C, typename F>
1452  inline guardObj0<C, F> objectGuard(C o, F f) {
1453  return guardObj0<C, F>::makeGuard(o, f);
1454  }
1455 
1456 #if defined(HAVE_FLOCK)
1457  class flock {
1459  public:
1462  flock(int fd)
1463  : fd_(fd),
1464  locked(0 == ::flock(fd, LOCK_EX|LOCK_NB)) {
1465  }
1468  if (locked)
1469  (void) ::flock(fd_, LOCK_UN);
1470  }
1473  bool isLocked() const {return locked;}
1474 
1475  private:
1476  const int fd_;
1477  const bool locked;
1478  }; // FLock
1479 #endif
1480  } // namespace util
1481 } // namespace ibis
1482 
1483 #if defined(WIN32) && ! defined(__CYGWIN__)
1484 char* getpass(const char* prompt);
1485 #endif
1486 
1496 inline double ibis::util::rand() {
1497  // The internal variable @c seed is always an odd number. Don't use it
1498  // directly.
1499  static uint32_t seed = 1;
1500  static const uint32_t alpha = 69069;
1501  static const double scale = ::pow(0.5, 32);
1502  seed = static_cast<uint32_t>(seed * alpha);
1503  return(scale * seed);
1504 } // ibis::util::rand
1505 
1507 inline uint32_t ibis::util::checksum(uint32_t a, uint32_t b) {
1508  uint32_t a0 = (a >> 16);
1509  uint32_t a1 = (a & 0xFFFF);
1510  uint32_t b0 = (b >> 16);
1511  uint32_t b1 = (b & 0xFFFF);
1512  return ((((a0<<2)+a1*3+(b0<<1)+b1) << 16) | ((a0+a1+b0+b1) & 0xFFFF));
1513 } // ibis::util::checksum
1514 
1522 inline double ibis::util::incrDouble(const double& in) {
1523 #if defined(HAVE_NEXTAFTER)
1524  return nextafter(in, DBL_MAX);
1525 #elif defined(_MSC_VER) && defined(_WIN32)
1526  return _nextafter(in, DBL_MAX);
1527 #else
1528  double tmp = fabs(in) * DBL_EPSILON;
1529  if (tmp > 0.0) tmp += in;
1530  else tmp = in + DBL_MIN;
1531  return tmp;
1532 #endif
1533 }
1534 
1537 inline double ibis::util::decrDouble(const double& in) {
1538 #if defined(HAVE_NEXTAFTER)
1539  return nextafter(in, -DBL_MAX);
1540 #elif defined(_MSC_VER) && defined(_WIN32)
1541  return _nextafter(in, -DBL_MAX);
1542 #else
1543  double tmp = fabs(in) * DBL_EPSILON;
1544  if (tmp > 0.0) tmp = in - tmp;
1545  else tmp = in - DBL_MIN;
1546  return tmp;
1547 #endif
1548 }
1549 
1554 inline void ibis::util::eq2range(const double& in,
1555  double& left, double& right) {
1556 #if defined(HAVE_NEXTAFTER)
1557  right = nextafter(in, DBL_MAX);
1558 #elif defined(_MSC_VER) && defined(_WIN32)
1559  right = _nextafter(in, DBL_MAX);
1560 #else
1561  double tmp = fabs(in) * DBL_EPSILON;
1562  if (tmp > 0.0) {right = in + tmp;}
1563  else {right = in + DBL_MIN;}
1564 #endif
1565  left = in;
1566 } // ibis::util::eq2range
1567 
1571 template <typename Tin>
1572 inline void ibis::util::round_up(const Tin& inval, float& outval) {
1573  // perform the initial rounding
1574  outval = static_cast<float>(inval);
1575  if (static_cast<Tin>(outval) < inval) {
1576  // if the rounded value is less than the input value, compute the
1577  // next value
1578 #if defined(HAVE_NEXTAFTER)
1579  outval = nextafterf(static_cast<float>(inval), FLT_MAX);
1580 #else
1581  float tmp = fabsf(outval) * FLT_EPSILON;
1582  if (tmp > 0.0) outval += tmp;
1583  else outval += FLT_MIN;
1584 #endif
1585  }
1586 } // ibis::util::round_up
1587 
1588 // remove all the trailing char 'tail'
1589 inline void ibis::util::removeTail(char* str, char tail) {
1590  if (str != 0 && *str != 0) {
1591  char *tmp = str;
1592  while (*tmp != 0) ++ tmp;
1593  -- tmp;
1594  while (tmp > str && *tmp == tail) {
1595  *tmp = static_cast<char>(0);
1596  -- tmp;
1597  }
1598  }
1599 } // ibis::util::removeTail
1600 
1601 // remove the leading and trailing space of the incoming string
1602 inline char* ibis::util::trim(char* str) {
1603  char* head = 0;
1604  if (str == 0) return head;
1605  if (*str == 0) return head;
1606 
1607  head = str;
1608  while (*head) {
1609  if (std::isspace(*head))
1610  ++ head;
1611  else
1612  break;
1613  }
1614  if (*head == 0)
1615  return head;
1616 
1617  for (str = head; *str != 0; ++ str);
1618  -- str;
1619  while (str >= head && std::isspace(*str)) {
1620  *str = static_cast<char>(0);
1621  -- str;
1622  }
1623  return head;
1624 } // ibis::util::trim
1625 
1633 inline double ibis::util::coarsen(const double in, unsigned prec) {
1634  double ret;
1635  if (prec > 15) {
1636  ret = in;
1637  }
1638  else if (in == 0.0) {
1639  ret = in;
1640  }
1641  else {
1642  ret = fabs(in);
1643  if (ret < DBL_MIN) { // denormalized number --> 0
1644  ret = 0.0;
1645  }
1646  else if (ret < DBL_MAX) { // normal numbers
1647  ret = log10(ret);
1648  if (prec > 0)
1649  -- prec;
1650  const int ixp = static_cast<int>(floor(ret)) -
1651  static_cast<int>(prec);
1652  ret = floor(0.5 + pow(1e1, ret-ixp));
1653  if (ixp > 0)
1654  ret *= pow(1e1, ixp);
1655  else if (ixp < 0)
1656  ret /= pow(1e1, -ixp);
1657  if (in < 0.0)
1658  ret = -ret;
1659  }
1660  else {
1661  ret = in;
1662  }
1663  }
1664  return ret;
1665 } // ibis::util::coarsen
1666 
1668 inline std::ostream& operator<<(std::ostream& out, const ibis::rid_t& rid) {
1669  out << '(' << rid.num.run << ", " << rid.num.event << ')';
1670  return out;
1671 }
1672 
1674 inline std::istream& operator>>(std::istream& is, ibis::rid_t& rid) {
1675  char c = 0;
1676  is >> c;
1677  if (c == '(') { // (runNumber, EventNumber)
1678  is >> rid.num.run >> c;
1679  if (c == ',')
1680  is >> rid.num.event >> c;
1681  else
1682  rid.num.event = 0;
1683  if (c != ')')
1684  is.clear(std::ios::badbit); // forget the erro
1685  }
1686  else { // runNumber, EventNumber
1687  is.putback(c);
1688  is >> rid.num.run >> c;
1689  if (c != ',') // assume space separator
1690  is.putback(c);
1691  is >> rid.num.event;
1692  }
1693  return is;
1694 }
1695 #endif // IBIS_UTIL_H
void round_up(const Tin &inval, Tout &outval)
Round the incoming value to the smallest output value that is no less than the input.
Definition: util.h:572
const char * charTable
charTable lists the 64 printable characters to be used for names
Definition: util.cpp:56
const ibis::bitvector64 & outerProduct(const ibis::bitvector &a, const ibis::bitvector &b, ibis::bitvector64 &c)
Compute the outer product of a and b, add the result to c.
Definition: bitvector64.cpp:3761
uint32_t checksum(const char *str, uint32_t sz)
Fletcher's arithmetic checksum with 32-bit result.
Definition: util.cpp:1486
int64_t write(int, const void *, int64_t)
A wrapper over POSIX write function.
Definition: util.cpp:999
void updateDatasets(void)
Update the metadata about the data partitions.
Definition: part.cpp:20879
void emptyCache(void)
Attempt to remove all currently unused data from memory cache.
Definition: part.cpp:20890
guardObj0(C &o, F f)
Constructor.
Definition: util.h:1441
double decrDouble(const double &)
Decrease the input value to the next smaller value.
Definition: util.h:1537
void int2string(std::string &str, unsigned val)
Pack a 32-bit integer into six base-64 alphabets.
Definition: util.cpp:1572
A simple wrapper on flock.
Definition: util.h:1458
std::map< const char *, part *, lessi > partAssoc
An associative array for data partitions.
Definition: util.h:438
std::string shortName(const std::string &longname)
Use the Fletcher's checksum to produce a short string.
Definition: util.cpp:1587
A concrete class for cleanup jobs that take a function without any argument.
Definition: util.h:1324
void removeTail(char *str, char tail)
Remove trailing character 'tail' from str.
Definition: util.h:1589
char * strnewdup(const char *s)
Duplicate string content with C++ default new operator.
Definition: util.cpp:1420
int getVersionNumber()
Return an integer designating the version of this software.
Definition: util.h:651
An wrapper class for perform pthread_mutex_trylock/unlock.
Definition: util.h:793
void setVerboseLevel(int v)
Set the verboseness level.
Definition: util.h:507
A unsigned 64-bit shared integer class.
Definition: util.h:1086
void operator+=(const uint32_t rhs)
In-place addition operator.
Definition: util.h:1013
int log2(uint32_t x)
Log_2 of a 32-bit integer.
Definition: util.h:590
An wrapper class for perform pthread_rwlock_rdlock/unlock.
Definition: util.h:818
A container for name-value pairs.
Definition: resource.h:38
guardImpl2(F f, A1 a1, A2 a2)
Construct a guard object from a function.
Definition: util.h:1404
int readUInt(uint64_t &val, const char *&str, const char *del=ibis::util::delimiters)
Attempt to convert the incoming string into a unsigned integer.
Definition: util.cpp:687
guardImpl1(F f, A a)
Construct a guard object from a function.
Definition: util.h:1370
uint64_t operator++()
Increment operator.
Definition: util.h:1122
An wrapper class for perform pthread_mutex_lock/unlock.
Definition: util.h:770
long intersect(const std::vector< ibis::bitvector > &bits1, const std::vector< ibis::bitvector > &bits2, std::vector< ibis::bitvector > &res)
Intersect two sets of bit vectors.
Definition: bitvector.cpp:4595
A template to hold a reference to an object.
Definition: util.h:1245
void clear(ibis::partList &pl)
Deallocate the list of data partitions.
Definition: part.cpp:20869
void getLocalTime(char *str)
Return the current time in string format as asctime_r.
Definition: util.cpp:2550
size_t find(const std::vector< T > &, const T &, size_t)
Find the first position where the value is no less than val.
Definition: utilidor.cpp:3795
partList datasets
!< Select clause.
Definition: util.cpp:83
~softLock()
Destructor.
Definition: util.h:802
double coarsen(const double in, unsigned prec=2)
Reduce the decimal precision of the incoming floating-point value to specified precision.
Definition: util.h:1633
STL namespace.
uint32_t serialNumber()
Compute a serial number.
Definition: util.cpp:1413
pthread_mutex_t envLock
A mutex for serialize operations FastBit wide.
Definition: util.cpp:49
void dismiss() const
Tell the guard that it does not need to invoke clean up function any more.
Definition: util.h:1266
static void cleanup(T &task)
A template to invoke the function registered.
Definition: util.h:1283
uint32_t operator()()
Return the current count and increment the count.
Definition: util.h:889
void secondsToString(const time_t, char *str)
Converts the given time in seconds (as returned by function time) into the string (as from asctime_r)...
Definition: util.cpp:2528
void closeLogFile()
Close the log file.
Definition: util.cpp:2120
char * trim(char *str)
Remove leading and trailing blank space.
Definition: util.h:1602
std::string groupby1000(uint64_t)
Produce a string version of the unsigned integer value with the decimal digits grouped into 1000s...
Definition: util.cpp:1640
The current implementation of FastBit is code named IBIS; most data structures and functions are in t...
Definition: bord.h:16
void operator-=(const uint64_t rhs)
In-place subtraction operator.
Definition: util.h:1169
const short unsigned charIndex[]
charIndex maps the characters (ASCII) back to integer [0-64]
Definition: util.cpp:60
void clearVec(std::vector< T * > &v)
A template to clean up a vector of pointers.
Definition: util.h:678
uint32_t value() const
Return the current count value.
Definition: util.h:913
A data structure to represent a sequence of bits.
Definition: bitvector64.h:54
bool strMatch(const char *str, const char *pat)
Match the string str against a simple pattern pat.
Definition: util.cpp:2244
~guardObj0()
Desutructor.
Definition: util.h:1434
Horometer – a primitive timing instrument.
Definition: horometer.h:62
~guardBase()
Destructor. No need to be virtual.
Definition: util.h:1272
off_t getFileSize(const char *name)
Return size of the file in bytes.
Definition: util.cpp:875
refHolder< T > ref(T &r)
A function template to produce refHolder.
Definition: util.h:1258
std::string randName(const std::string &longname)
Generate a short string to be used as a table/partition name.
Definition: util.cpp:1613
void getGMTime(char *str)
Return the current GMT time in string format.
Definition: util.cpp:2570
ibis::resource & gParameters()
List of in-memory data.
Definition: resource.cpp:545
~guardImpl2()
Destructor calls the cleanup function of the base class.
Definition: util.h:1397
uint32_t operator()() const
Read the current value.
Definition: util.h:967
char * getString(const char *buf)
Extract a string from the given buf.
Definition: util.cpp:166
uint32_t operator++()
Increment operator.
Definition: util.h:981
softLock(pthread_mutex_t *lk)
Constructor.
Definition: util.h:796
void setNaN(double &val)
Set a double to NaN.
Definition: util.cpp:1404
quietLock(pthread_mutex_t *lk)
Constructor.
Definition: util.h:773
void operator+=(const uint64_t rhs)
In-place addition operator.
Definition: util.h:1154
int writeLogFileHeader(FILE *fptr, const char *fname)
Write a header to the log file.
Definition: util.cpp:1993
int copy(const char *to, const char *from)
Copy file named "from" to a file named "to".
Definition: util.cpp:894
int readInt(int64_t &val, const char *&str, const char *del=ibis::util::delimiters)
Attempt to convert the incoming string into an integer.
Definition: util.cpp:619
const guardBase & guard
The type to be used by client code.
Definition: util.h:1319
~flock()
Destructor.
Definition: util.h:1467
bool isLocked() const
Has a mutex lock being acquired? Returns true if yes, otherwise false.
Definition: util.h:800
~timer()
Destructor.
Definition: util.cpp:2215
void logMessage(const char *event, const char *fmt,...)
Print a message to standard output.
Definition: util.cpp:1902
std::istream & operator>>(std::istream &is, ibis::rid_t &rid)
Read a rid_t from an input stream.
Definition: util.h:1674
~quietLock()
Destructor.
Definition: util.h:778
A concrete class for cleanup jobs that take a function with two arguments.
Definition: util.h:1390
guardImpl0(F f)
Construct a guard object from a function.
Definition: util.h:1338
const char * getLogFileName()
Return name the of the current log file.
Definition: util.cpp:2111
const int log2table[256]
log base 2 of an integer, the lookup table
Definition: util.cpp:74
void operator-=(const uint32_t rhs)
In-place subtraction operator.
Definition: util.h:1027
double compactValue2(double left, double right, double start=0.0)
Compute a compact 64-bit floating-point value with a short binary representation. ...
Definition: util.cpp:1320
const char * userName()
Return the user name.
Definition: util.cpp:1815
void round_down(const Tin &inval, Tout &outval)
Round the incoming value to the largest output value that is no more than the input.
Definition: util.h:561
std::ostringstream mybuffer
The message is stored in this buffer.
Definition: util.h:706
A simple shared counter.
Definition: util.h:869
uint64_t operator--()
Decrement operator.
Definition: util.h:1138
A global I/O lock.
Definition: util.h:715
uint64_t operator()() const
Read the current value.
Definition: util.h:1108
double incrDouble(const double &)
Functions to handle manipulation of floating-point numbers.
Definition: util.h:1522
const ibis::bitvector64 & outerProductUpper(const ibis::bitvector &a, const ibis::bitvector &b, ibis::bitvector64 &c)
Add the strict upper triangular portion of the outer production between a and b to c...
Definition: bitvector64.cpp:3858
A data structure to store a small set of names.
Definition: util.h:399
void encode64(uint64_t, std::string &)
Turn the incoming integer into a 64-bit representation.
Definition: util.cpp:1679
double rand()
A very simple pseudo-random number generator.
Definition: util.h:1496
Defines common data types, constants and macros.
int64_t read(int, void *, int64_t)
A wrapper over POSIX read function.
Definition: util.cpp:973
bool nameMatch(const char *str, const char *pat)
Match the string str against a simple pattern pat without considering cases.
Definition: util.cpp:2396
int readString(std::string &str, const char *&buf, const char *delim=0)
Copy the next string to the output variable str.
Definition: util.cpp:248
void clear(ibis::array_t< ibis::bitvector * > &bv)
Clear an array of bit vectors.
Definition: bitvector.cpp:4662
int decode16(uint64_t &, const char *)
Convert a string of hexadecimal digits back to an integer.
Definition: util.cpp:1725
A concrete class for cleanup jobs that take a function with one argument.
Definition: util.h:1356
~guardImpl1()
Destructor calls the cleanup function of the base class.
Definition: util.h:1363
flock(int fd)
Constructor.
Definition: util.h:1462
int readDouble(double &val, const char *&str, const char *del=ibis::util::delimiters)
Attempt to convert the incoming string into a double.
Definition: util.cpp:780
A data structure to represent a sequence of bits.
Definition: bitvector.h:62
void eq2range(const double &, double &, double &)
Generate a range [left, right) that contains exactly the input value in.
Definition: util.h:1554
Print simple timing information.
Definition: util.h:1230
~writeLock()
Destructor.
Definition: util.h:850
int decode64(uint64_t &, const std::string &)
Decode a number encoded using ibis::util::encode64.
Definition: util.cpp:1695
const char * delimiters
Delimiters used to separate a string of names.
Definition: util.cpp:71
void reset()
Reset count to zero.
Definition: util.h:902
A specialization of std::bad_alloc.
Definition: util.h:441
std::ostream & operator()(void)
Return an output stream for caller to build a message.
Definition: util.h:700
void removeDir(const char *name, bool leaveDir=false)
Remove the content of named directory.
Definition: util.cpp:1023
double compactValue(double left, double right, double start=0.0)
Compute a compact 64-bit floating-point value with a short decimal representation.
Definition: util.cpp:1227
std::ostream & operator<<(std::ostream &out, const ibis::rid_t &rid)
Print a rid_t to an output stream.
Definition: util.h:1668
const char * getVersionString()
Return a pointer to the string designating the version of this software.
Definition: util.h:642
void uniformFraction(const long unsigned idx, long unsigned &denominator, long unsigned &numerator)
Compute a denominator and numerator pair.
Definition: util.cpp:1448
bad_alloc(const char *m="unknown")
Constructor.
Definition: util.h:446
A shared unsigned 32-bit integer class.
Definition: util.h:945
bool isLocked() const
Was a lock acquired successfully? Returns true for yes, otherwise no.
Definition: util.h:1473
A class for logging messages.
Definition: util.h:693
int setLogFileName(const char *filename)
Change the current log file to the named file.
Definition: util.cpp:1952
const char * getToken(char *&str, const char *tok_chrs)
Return a null-terminated string from the beginning of input string str.
Definition: util.cpp:94
A class hierarchy for cleaning up after durable resources.
Definition: util.h:1262
int makeDir(const char *dir)
Recursivly create directory "dir".
Definition: util.cpp:112
Definition: const.h:299
A class to work with class member functions with no arguments.
Definition: util.h:1427
~guardImpl0()
Destructor calls the cleanup function of the base class.
Definition: util.h:1331
FILE * getLogFile()
Retrieve the pointer to the log file.
Definition: util.cpp:2070
An wrapper class for perform pthread_rwlock_wrlock/unlock.
Definition: util.h:840
An wrapper class for perform pthread_mutex_lock/unlock.
Definition: util.h:740
uint32_t operator--()
Decrement operator.
Definition: util.h:997
writeLock(pthread_rwlock_t *lk, const char *m)
Constructor.
Definition: util.h:843

Make It A Bit Faster
Contact us
Disclaimers
FastBit source code
FastBit mailing list archive