MACSio  0.9
Multi-purpose, Application-Centric, Scalable I/O Proxy App
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
macsio_utils.c
Go to the documentation of this file.
1 /*
2 Copyright (c) 2015, Lawrence Livermore National Security, LLC.
3 Produced at the Lawrence Livermore National Laboratory.
4 Written by Mark C. Miller
5 
6 LLNL-CODE-676051. All rights reserved.
7 
8 This file is part of MACSio
9 
10 Please also read the LICENSE file at the top of the source code directory or
11 folder hierarchy.
12 
13 This program is free software; you can redistribute it and/or modify it under
14 the terms of the GNU General Public License (as published by the Free Software
15 Foundation) version 2, dated June 1991.
16 
17 This program is distributed in the hope that it will be useful, but WITHOUT
18 ANY WARRANTY; without even the IMPLIED WARRANTY OF MERCHANTABILITY or FITNESS
19 FOR A PARTICULAR PURPOSE. See the terms and conditions of the GNU General
20 Public License for more details.
21 
22 You should have received a copy of the GNU General Public License along with
23 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
24 Place, Suite 330, Boston, MA 02111-1307 USA
25 */
26 
27 #include <float.h>
28 #include <math.h>
29 #include <stdio.h>
30 #include <strings.h>
31 
32 #include <macsio_utils.h>
33 
35 
36 /*-------------------------------------------------------------------------
37  Function: bjhash
38 
39  Purpose: Hash a variable length stream of bytes into a 32-bit value.
40 
41  Programmer: By Bob Jenkins, 1996. bob_jenkins@burtleburtle.net.
42 
43  You may use this code any way you wish, private, educational, or
44  commercial. It's free. However, do NOT use for cryptographic purposes.
45 
46  See http://burtleburtle.net/bob/hash/evahash.html
47  *-------------------------------------------------------------------------*/
48 
49 #define bjhash_mix(a,b,c) \
50 { \
51  a -= b; a -= c; a ^= (c>>13); \
52  b -= c; b -= a; b ^= (a<<8); \
53  c -= a; c -= b; c ^= (b>>13); \
54  a -= b; a -= c; a ^= (c>>12); \
55  b -= c; b -= a; b ^= (a<<16); \
56  c -= a; c -= b; c ^= (b>>5); \
57  a -= b; a -= c; a ^= (c>>3); \
58  b -= c; b -= a; b ^= (a<<10); \
59  c -= a; c -= b; c ^= (b>>15); \
60 }
61 
62 unsigned int MACSIO_UTILS_BJHash(const unsigned char *k, unsigned int length, unsigned int initval)
63 {
64  unsigned int a,b,c,len;
65 
66  len = length;
67  a = b = 0x9e3779b9;
68  c = initval;
69 
70  while (len >= 12)
71  {
72  a += (k[0] +((unsigned int)k[1]<<8) +((unsigned int)k[2]<<16) +((unsigned int)k[3]<<24));
73  b += (k[4] +((unsigned int)k[5]<<8) +((unsigned int)k[6]<<16) +((unsigned int)k[7]<<24));
74  c += (k[8] +((unsigned int)k[9]<<8) +((unsigned int)k[10]<<16)+((unsigned int)k[11]<<24));
75  bjhash_mix(a,b,c);
76  k += 12; len -= 12;
77  }
78 
79  c += length;
80 
81  switch(len)
82  {
83  case 11: c+=((unsigned int)k[10]<<24);
84  case 10: c+=((unsigned int)k[9]<<16);
85  case 9 : c+=((unsigned int)k[8]<<8);
86  case 8 : b+=((unsigned int)k[7]<<24);
87  case 7 : b+=((unsigned int)k[6]<<16);
88  case 6 : b+=((unsigned int)k[5]<<8);
89  case 5 : b+=k[4];
90  case 4 : a+=((unsigned int)k[3]<<24);
91  case 3 : a+=((unsigned int)k[2]<<16);
92  case 2 : a+=((unsigned int)k[1]<<8);
93  case 1 : a+=k[0];
94  }
95 
96  bjhash_mix(a,b,c);
97 
98  return c;
99 }
100 
102  int val,
103  int *x,
104  int *y
105 )
106 {
107  int root = (int) sqrt((double)val);
108  while (root)
109  {
110  if (!(val % root))
111  {
112  *x = root;
113  *y = val / root;
114  return 0;
115  }
116  root--;
117  }
118  return 1;
119 }
120 
121 int MACSIO_UTILS_Best3DFactors(int val, int *x, int *y, int *z)
122 {
123  int root = (int) cbrt((double)val);
124  int root2;
125  int xb, yb, zb, mb=-1, mf=-1;
126 
127  /* first, walk backwards from the cube root */
128  while (root)
129  {
130  if (!(val % root))
131  {
132  int val2d = val / root;
133  if (!MACSIO_UTILS_Best2DFactors(val2d, x, y))
134  {
135  *z = val / val2d;
136  xb = *x;
137  yb = *y;
138  zb = *z;
139  mb = xb<yb?xb:yb;
140  mb = mb<zb?mb:zb;
141  break;
142  }
143  }
144  root--;
145  }
146 
147  /* next, walk forwards from the cube root to the square root */
148  root = (int) cbrt((double)val);
149  root2 = (int) sqrt((double)val);
150  while (root < root2)
151  {
152  if (!(val % root))
153  {
154  int val2d = val / root;
155  if (!MACSIO_UTILS_Best2DFactors(val2d, x, y))
156  {
157  *z = val / val2d;
158  mf = *x<*y?*x:*y;
159  mf = mf<*z?mf:*z;
160  break;
161  }
162  }
163  root++;
164  }
165 
166  if (mb != -1)
167  {
168  if (mb > mf)
169  {
170  *x = xb;
171  *y = yb;
172  *z = zb;
173  }
174  return 0;
175  }
176 
177  return 1;
178 }
179 
180 int MACSIO_UTILS_LogicalIJKIndexToSequentialIndex(int i,int j,int k,int Ni,int Nj) { return k*Ni*Nj + j*Ni + i; }
181 int MACSIO_UTILS_LogicalIJIndexToSequentialIndex (int i,int j, int Ni ) { return j*Ni + i; }
183 
184 void MACSIO_UTILS_SequentialIndexToLogicalIJKIndex(int s,int Ni,int Nj,int *i,int *j,int *k)
185 {
186  *k = (s / (Ni*Nj));
187  *j = (s % (Ni*Nj)) / Ni;
188  *i = (s % (Ni*Nj)) % Ni;
189 }
190 void MACSIO_UTILS_SequentialIndexToLogicalIJIndex(int s,int Ni,int *i,int *j)
191 {
192  *j = (s / Ni);
193  *i = (s % Ni);
194 }
196 {
197  *i = s;
198 }
199 
200 void MACSIO_UTILS_SetDims(int *dims, int nx, int ny, int nz)
201 {
202  dims[0] = nx;
203  dims[1] = ny;
204  dims[2] = nz;
205 }
206 int MACSIO_UTILS_XDim(int const *dims) { return dims[0]; }
207 int MACSIO_UTILS_YDim(int const *dims) { return dims[1]; }
208 int MACSIO_UTILS_ZDim(int const *dims) { return dims[2]; }
209 
210 void MACSIO_UTILS_SetBounds(double *bounds,
211  double xmin, double ymin, double zmin,
212  double xmax, double ymax, double zmax)
213 {
214  bounds[0] = xmin;
215  bounds[1] = ymin;
216  bounds[2] = zmin;
217  bounds[3] = xmax;
218  bounds[4] = ymax;
219  bounds[5] = zmax;
220 }
221 
222 double MACSIO_UTILS_XRange(double const *bounds) { return bounds[3] - bounds[0]; }
223 double MACSIO_UTILS_YRange(double const *bounds) { return bounds[4] - bounds[1]; }
224 double MACSIO_UTILS_ZRange(double const *bounds) { return bounds[5] - bounds[2]; }
225 double MACSIO_UTILS_XMin(double const *bounds) { return bounds[0]; }
226 double MACSIO_UTILS_YMin(double const *bounds) { return bounds[1]; }
227 double MACSIO_UTILS_ZMin(double const *bounds) { return bounds[2]; }
228 double MACSIO_UTILS_XMax(double const *bounds) { return bounds[3]; }
229 double MACSIO_UTILS_YMax(double const *bounds) { return bounds[4]; }
230 double MACSIO_UTILS_ZMax(double const *bounds) { return bounds[5]; }
231 double MACSIO_UTILS_XDelta(int const *dims, double const *bounds)
232 {
233  if (MACSIO_UTILS_XDim(dims) < 2) return -1;
234  return MACSIO_UTILS_XRange(bounds) / (MACSIO_UTILS_XDim(dims) - 1);
235 }
236 double MACSIO_UTILS_YDelta(int const *dims, double const *bounds)
237 {
238  if (MACSIO_UTILS_YDim(dims) < 2) return -1;
239  return MACSIO_UTILS_YRange(bounds) / (MACSIO_UTILS_YDim(dims) - 1);
240 }
241 double MACSIO_UTILS_ZDelta(int const *dims, double const *bounds)
242 {
243  if (MACSIO_UTILS_ZDim(dims) < 2) return -1;
244  return MACSIO_UTILS_ZRange(bounds) / (MACSIO_UTILS_ZDim(dims) - 1);
245 }
246 
247 json_object *
248 MACSIO_UTILS_MakeDimsJsonArray(int ndims, const int *dims)
249 {
250  json_object *dims_array = json_object_new_array();
251  json_object_array_add(dims_array, json_object_new_int(dims[0]));
252  if (ndims > 1)
253  json_object_array_add(dims_array, json_object_new_int(dims[1]));
254  if (ndims > 2)
255  json_object_array_add(dims_array, json_object_new_int(dims[2]));
256  return dims_array;
257 }
258 
259 #warning WOULD BE MORE CONSISTENT TO STORE AS MIN/MAX PAIRS RATHER THAN ALL MINS FOLLOWED BY ALL MAXS
260 json_object *
261 MACSIO_UTILS_MakeBoundsJsonArray(double const * bounds)
262 {
263  json_object *bounds_array = json_object_new_array();
264  json_object_array_add(bounds_array, json_object_new_double(bounds[0]));
265  json_object_array_add(bounds_array, json_object_new_double(bounds[1]));
266  json_object_array_add(bounds_array, json_object_new_double(bounds[2]));
267  json_object_array_add(bounds_array, json_object_new_double(bounds[3]));
268  json_object_array_add(bounds_array, json_object_new_double(bounds[4]));
269  json_object_array_add(bounds_array, json_object_new_double(bounds[5]));
270  return bounds_array;
271 }
272 
273 static char const *print_bytes(double val, char const *_fmt, char *str, int n, char const *_persec)
274 {
275  char const *persec = _persec ? _persec : "";
276  char const *fmt = _fmt ? _fmt : "%8.4f";
277 
278  static double const ki = 1024.0;
279  static double const mi = 1024.0 * 1024.0;
280  static double const gi = 1024.0 * 1024.0 * 1024.0;
281  static double const ti = 1024.0 * 1024.0 * 1024.0 * 1024.0;
282  static double const pi = 1024.0 * 1024.0 * 1024.0 * 1024.0 * 1024.0;
283 
284  static char const *kistr = "Ki";
285  static char const *mistr = "Mi";
286  static char const *gistr = "Gi";
287  static char const *tistr = "Ti";
288  static char const *pistr = "Pi";
289 
290  static double const kb = 1000.0;
291  static double const mb = 1000.0 * 1000.0;
292  static double const gb = 1000.0 * 1000.0 * 1000.0;
293  static double const tb = 1000.0 * 1000.0 * 1000.0 * 1000.0;
294  static double const pb = 1000.0 * 1000.0 * 1000.0 * 1000.0 * 1000.0;
295 
296  static char const *kbstr = "Kb";
297  static char const *mbstr = "Mb";
298  static char const *gbstr = "Gb";
299  static char const *tbstr = "Tb";
300  static char const *pbstr = "Pb";
301 
302  char fmt2[32];
303 
304  double kv = ki;
305  double mv = mi;
306  double gv = gi;
307  double tv = ti;
308  double pv = pi;
309 
310  char const *kvstr = kistr;
311  char const *mvstr = mistr;
312  char const *gvstr = gistr;
313  char const *tvstr = tistr;
314  char const *pvstr = pistr;
315 
316  if (!strncasecmp(MACSIO_UTILS_UnitsPrefixSystem, "decimal",
318  {
319  kv = kb;
320  mv = mb;
321  gv = gb;
322  tv = tb;
323  pv = pb;
324  kvstr = kbstr;
325  mvstr = mbstr;
326  gvstr = gbstr;
327  tvstr = tbstr;
328  pvstr = pbstr;
329  }
330 
331  if (val >= pv)
332  {
333  snprintf(fmt2, sizeof(fmt2), "%s %s%s", fmt, pvstr, persec);
334  snprintf(str, n, fmt2, val / pv);
335  }
336  else if (val >= tv)
337  {
338  snprintf(fmt2, sizeof(fmt2), "%s %s%s", fmt, tvstr, persec);
339  snprintf(str, n, fmt2, val / tv);
340  }
341  else if (val >= gv)
342  {
343  snprintf(fmt2, sizeof(fmt2), "%s %s%s", fmt, gvstr, persec);
344  snprintf(str, n, fmt2, val / gv);
345  }
346  else if (val >= mv)
347  {
348  snprintf(fmt2, sizeof(fmt2), "%s %s%s", fmt, mvstr, persec);
349  snprintf(str, n, fmt2, val / mv);
350  }
351  else if (val >= kv)
352  {
353  snprintf(fmt2, sizeof(fmt2), "%s %s%s", fmt, kvstr, persec);
354  snprintf(str, n, fmt2, val / kv);
355  }
356  else
357  {
358  snprintf(fmt2, sizeof(fmt2), "%s b%s", fmt, persec);
359  snprintf(str, n, fmt2, val);
360  }
361 
362  return str;
363 }
364 
365 char const *MACSIO_UTILS_PrintBytes(unsigned long long bytes, char const *fmt, char *str, int n)
366 {
367  return print_bytes((double)bytes, fmt, str, n, 0);
368 }
369 
370 char const *MACSIO_UTILS_PrintBandwidth(unsigned long long bytes, double seconds,
371  char const *fmt, char *str, int n)
372 {
373  return print_bytes((double)bytes/seconds, fmt, str, n, "/sec");
374 }
375 
376 char const *MACSIO_UTILS_PrintSeconds(double seconds, char const *fmt, char *str, int n)
377 {
378  static double const min = 60.0;
379  static double const hour = 60.0 * 60.0;
380  static double const day = 60.0 * 60.0 * 24.0;
381  static double const week = 60.0 * 60.0 * 24.0 * 7.0;
382  char fmt2[32];
383 
384  if (seconds >= week)
385  {
386  snprintf(fmt2, sizeof(fmt2), "%s wks", fmt?fmt:"%8.4f");
387  snprintf(str, n, fmt2, seconds/week);
388  }
389  else if (seconds >= day)
390  {
391  snprintf(fmt2, sizeof(fmt2), "%s days", fmt?fmt:"%8.4f");
392  snprintf(str, n, fmt2, seconds/day);
393  }
394  else if (seconds >= hour)
395  {
396  snprintf(fmt2, sizeof(fmt2), "%s hrs", fmt?fmt:"%8.4f");
397  snprintf(str, n, fmt2, seconds/hour);
398  }
399  else if (seconds >= min)
400  {
401  snprintf(fmt2, sizeof(fmt2), "%s mins", fmt?fmt:"%8.4f");
402  snprintf(str, n, fmt2, seconds/min);
403  }
404  else if (seconds >= 1)
405  {
406  snprintf(fmt2, sizeof(fmt2), "%s secs", fmt?fmt:"%8.4f");
407  snprintf(str, n, fmt2, seconds);
408  }
409  else if (seconds >= 1e-3)
410  {
411  snprintf(fmt2, sizeof(fmt2), "%s msecs", fmt?fmt:"%8.4f");
412  snprintf(str, n, fmt2, seconds/1e-3);
413  }
414  else if (seconds >= 1e-6)
415  {
416  snprintf(fmt2, sizeof(fmt2), "%s usecs", fmt?fmt:"%8.4f");
417  snprintf(str, n, fmt2, seconds/1e-6);
418  }
419  else if (seconds >= 1e-9)
420  {
421  snprintf(fmt2, sizeof(fmt2), "%s nsecs", fmt?fmt:"%8.4f");
422  snprintf(str, n, fmt2, seconds/1e-9);
423  }
424 
425  return str;
426 }
double MACSIO_UTILS_XMax(double const *bounds)
Definition: macsio_utils.c:228
double MACSIO_UTILS_ZMax(double const *bounds)
Definition: macsio_utils.c:230
int MACSIO_UTILS_LogicalIJKIndexToSequentialIndex(int i, int j, int k, int Ni, int Nj)
Definition: macsio_utils.c:180
json_object * MACSIO_UTILS_MakeDimsJsonArray(int ndims, const int *dims)
Definition: macsio_utils.c:248
char const * MACSIO_UTILS_PrintSeconds(double seconds, char const *fmt, char *str, int n)
Definition: macsio_utils.c:376
double MACSIO_UTILS_XMin(double const *bounds)
Definition: macsio_utils.c:225
double MACSIO_UTILS_ZRange(double const *bounds)
Definition: macsio_utils.c:224
void MACSIO_UTILS_SetDims(int *dims, int nx, int ny, int nz)
Definition: macsio_utils.c:200
int MACSIO_UTILS_Best2DFactors(int val, int *x, int *y)
Definition: macsio_utils.c:101
int MACSIO_UTILS_XDim(int const *dims)
Definition: macsio_utils.c:206
int MACSIO_UTILS_LogicalIJIndexToSequentialIndex(int i, int j, int Ni)
Definition: macsio_utils.c:181
static char const * print_bytes(double val, char const *_fmt, char *str, int n, char const *_persec)
Definition: macsio_utils.c:273
double MACSIO_UTILS_YRange(double const *bounds)
Definition: macsio_utils.c:223
void MACSIO_UTILS_SequentialIndexToLogicalIIndex(int s, int *i)
Definition: macsio_utils.c:195
char const * MACSIO_UTILS_PrintBandwidth(unsigned long long bytes, double seconds, char const *fmt, char *str, int n)
Definition: macsio_utils.c:370
void MACSIO_UTILS_SequentialIndexToLogicalIJKIndex(int s, int Ni, int Nj, int *i, int *j, int *k)
Definition: macsio_utils.c:184
double MACSIO_UTILS_YMin(double const *bounds)
Definition: macsio_utils.c:226
struct json_object * json_object_new_int(int32_t i)
Definition: json_object.c:495
int json_object_array_add(struct json_object *obj, struct json_object *val)
Definition: json_object.c:859
int MACSIO_UTILS_Best3DFactors(int val, int *x, int *y, int *z)
Definition: macsio_utils.c:121
double MACSIO_UTILS_YDelta(int const *dims, double const *bounds)
Definition: macsio_utils.c:236
double MACSIO_UTILS_YMax(double const *bounds)
Definition: macsio_utils.c:229
struct json_object * json_object_new_array(void)
Definition: json_object.c:828
double MACSIO_UTILS_ZDelta(int const *dims, double const *bounds)
Definition: macsio_utils.c:241
char const * MACSIO_UTILS_PrintBytes(unsigned long long bytes, char const *fmt, char *str, int n)
Definition: macsio_utils.c:365
struct json_object * json_object_new_double(double d)
Definition: json_object.c:622
int MACSIO_UTILS_YDim(int const *dims)
Definition: macsio_utils.c:207
void MACSIO_UTILS_SequentialIndexToLogicalIJIndex(int s, int Ni, int *i, int *j)
Definition: macsio_utils.c:190
unsigned int MACSIO_UTILS_BJHash(const unsigned char *k, unsigned int length, unsigned int initval)
Definition: macsio_utils.c:62
char MACSIO_UTILS_UnitsPrefixSystem[32]
Definition: macsio_utils.c:34
json_object * MACSIO_UTILS_MakeBoundsJsonArray(double const *bounds)
Definition: macsio_utils.c:261
int MACSIO_UTILS_LogicalIIndexToSequentialIndex(int i)
Definition: macsio_utils.c:182
void MACSIO_UTILS_SetBounds(double *bounds, double xmin, double ymin, double zmin, double xmax, double ymax, double zmax)
Definition: macsio_utils.c:210
double MACSIO_UTILS_XRange(double const *bounds)
Definition: macsio_utils.c:222
#define bjhash_mix(a, b, c)
Definition: macsio_utils.c:49
double MACSIO_UTILS_XDelta(int const *dims, double const *bounds)
Definition: macsio_utils.c:231
int MACSIO_UTILS_ZDim(int const *dims)
Definition: macsio_utils.c:208
double MACSIO_UTILS_ZMin(double const *bounds)
Definition: macsio_utils.c:227