H5Vprivate.h

00001 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00002  * Copyright by The HDF Group.                                               *
00003  * Copyright by the Board of Trustees of the University of Illinois.         *
00004  * All rights reserved.                                                      *
00005  *                                                                           *
00006  * This file is part of HDF5.  The full HDF5 copyright notice, including     *
00007  * terms governing use, modification, and redistribution, is contained in    *
00008  * the files COPYING and Copyright.html.  COPYING can be found at the root   *
00009  * of the source code distribution tree; Copyright.html can be found at the  *
00010  * root level of an installed copy of the electronic HDF5 document set and   *
00011  * is linked from the top-level documents page.  It can also be found at     *
00012  * http://hdfgroup.org/HDF5/doc/Copyright.html.  If you do not have          *
00013  * access to either file, you may request a copy from help@hdfgroup.org.     *
00014  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00015 
00016 /*
00017  * Programmer: Robb Matzke <matzke@llnl.gov>
00018  *             Friday, October 10, 1997
00019  */
00020 #ifndef H5Vprivate_H
00021 #define H5Vprivate_H
00022 
00023 /* Private headers needed by this file */
00024 #include "H5private.h"          /* Generic Functions                    */
00025 #include "H5Eprivate.h"         /* Error handling                       */
00026 
00027 /* Vector comparison functions like Fortran66 comparison operators */
00028 #define H5V_vector_eq_s(N,V1,V2) (H5V_vector_cmp_s (N, V1, V2)==0)
00029 #define H5V_vector_lt_s(N,V1,V2) (H5V_vector_cmp_s (N, V1, V2)<0)
00030 #define H5V_vector_gt_s(N,V1,V2) (H5V_vector_cmp_s (N, V1, V2)>0)
00031 #define H5V_vector_le_s(N,V1,V2) (H5V_vector_cmp_s (N, V1, V2)<=0)
00032 #define H5V_vector_ge_s(N,V1,V2) (H5V_vector_cmp_s (N, V1, V2)>=0)
00033 #define H5V_vector_eq_u(N,V1,V2) (H5V_vector_cmp_u (N, V1, V2)==0)
00034 #define H5V_vector_lt_u(N,V1,V2) (H5V_vector_cmp_u (N, V1, V2)<0)
00035 #define H5V_vector_gt_u(N,V1,V2) (H5V_vector_cmp_u (N, V1, V2)>0)
00036 #define H5V_vector_le_u(N,V1,V2) (H5V_vector_cmp_u (N, V1, V2)<=0)
00037 #define H5V_vector_ge_u(N,V1,V2) (H5V_vector_cmp_u (N, V1, V2)>=0)
00038 
00039 /* Other functions */
00040 #define H5V_vector_cpy(N,DST,SRC) {                                           \
00041     assert (sizeof(*(DST))==sizeof(*(SRC)));                                              \
00042     if (SRC) HDmemcpy (DST, SRC, (N)*sizeof(*(DST)));                         \
00043     else HDmemset (DST, 0, (N)*sizeof(*(DST)));                               \
00044 }
00045 
00046 #define H5V_vector_zero(N,DST) HDmemset(DST,0,(N)*sizeof(*(DST)))
00047 
00048 /* A null pointer is equivalent to a zero vector */
00049 #define H5V_ZERO        NULL
00050 
00051 H5_DLL hsize_t H5V_hyper_stride(unsigned n, const hsize_t *size,
00052                                  const hsize_t *total_size,
00053                                  const hsize_t *offset,
00054                                  hsize_t *stride);
00055 H5_DLL htri_t H5V_hyper_disjointp(unsigned n, const hsize_t *offset1,
00056     const uint32_t *size1, const hsize_t *offset2, const uint32_t *size2);
00057 H5_DLL htri_t H5V_hyper_eq(unsigned n, const hsize_t *offset1,
00058                             const hsize_t *size1, const hsize_t *offset2,
00059                             const hsize_t *size2);
00060 H5_DLL herr_t H5V_hyper_fill(unsigned n, const hsize_t *_size,
00061                               const hsize_t *total_size,
00062                               const hsize_t *offset, void *_dst,
00063                               unsigned fill_value);
00064 H5_DLL herr_t H5V_hyper_copy(unsigned n, const hsize_t *size,
00065                               const hsize_t *dst_total_size,
00066                               const hsize_t *dst_offset, void *_dst,
00067                               const hsize_t *src_total_size,
00068                               const hsize_t *src_offset, const void *_src);
00069 H5_DLL herr_t H5V_stride_fill(unsigned n, hsize_t elmt_size, const hsize_t *size,
00070                                const hsize_t *stride, void *_dst,
00071                                unsigned fill_value);
00072 H5_DLL herr_t H5V_stride_copy(unsigned n, hsize_t elmt_size, const hsize_t *_size,
00073                                const hsize_t *dst_stride, void *_dst,
00074                                const hsize_t *src_stride, const void *_src);
00075 H5_DLL herr_t H5V_stride_copy_s(unsigned n, hsize_t elmt_size, const hsize_t *_size,
00076                                const hssize_t *dst_stride, void *_dst,
00077                                const hssize_t *src_stride, const void *_src);
00078 H5_DLL herr_t H5V_array_fill(void *_dst, const void *src, size_t size,
00079                               size_t count);
00080 H5_DLL herr_t H5V_array_down(unsigned n, const hsize_t *total_size,
00081     hsize_t *down);
00082 H5_DLL hsize_t H5V_array_offset_pre(unsigned n,
00083     const hsize_t *acc, const hsize_t *offset);
00084 H5_DLL hsize_t H5V_array_offset(unsigned n, const hsize_t *total_size,
00085     const hsize_t *offset);
00086 H5_DLL herr_t H5V_array_calc(hsize_t offset, unsigned n,
00087     const hsize_t *total_size, hsize_t *coords);
00088 H5_DLL herr_t H5V_chunk_index(unsigned ndims, const hsize_t *coord,
00089     const uint32_t *chunk, const hsize_t *down_nchunks, hsize_t *chunk_idx);
00090 H5_DLL ssize_t H5V_memcpyvv(void *_dst,
00091     size_t dst_max_nseq, size_t *dst_curr_seq, size_t dst_len_arr[], hsize_t dst_off_arr[],
00092     const void *_src,
00093     size_t src_max_nseq, size_t *src_curr_seq, size_t src_len_arr[], hsize_t src_off_arr[]);
00094 
00095 
00096 /*-------------------------------------------------------------------------
00097  * Function:    H5V_vector_reduce_product
00098  *
00099  * Purpose:     Product reduction of a vector.  Vector elements and return
00100  *              value are size_t because we usually want the number of
00101  *              elements in an array and array dimensions are always of type
00102  *              size_t.
00103  *
00104  * Return:      Success:        Product of elements
00105  *
00106  *              Failure:        1 if N is zero
00107  *
00108  * Programmer:  Robb Matzke
00109  *              Friday, October 10, 1997
00110  *
00111  * Modifications:
00112  *
00113  *-------------------------------------------------------------------------
00114  */
00115 static H5_inline hsize_t UNUSED
00116 H5V_vector_reduce_product(unsigned n, const hsize_t *v)
00117 {
00118     hsize_t                  ret_value = 1;
00119 
00120     /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
00121     FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5V_vector_reduce_product)
00122 
00123     if (n && !v) HGOTO_DONE(0)
00124     while (n--) ret_value *= *v++;
00125 
00126 done:
00127     FUNC_LEAVE_NOAPI(ret_value)
00128 }
00129 
00130 /*-------------------------------------------------------------------------
00131  * Function:    H5V_vector_zerop_u
00132  *
00133  * Purpose:     Determines if all elements of a vector are zero.
00134  *
00135  * Return:      Success:        TRUE if all elements are zero,
00136  *                              FALSE otherwise
00137  *
00138  *              Failure:        TRUE if N is zero
00139  *
00140  * Programmer:  Robb Matzke
00141  *              Friday, October 10, 1997
00142  *
00143  * Modifications:
00144  *
00145  *-------------------------------------------------------------------------
00146  */
00147 static H5_inline htri_t UNUSED
00148 H5V_vector_zerop_u(int n, const hsize_t *v)
00149 {
00150     htri_t      ret_value=TRUE;       /* Return value */
00151 
00152     /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
00153     FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5V_vector_zerop_u)
00154 
00155     if (!v)
00156         HGOTO_DONE(TRUE)
00157     while (n--)
00158         if (*v++)
00159             HGOTO_DONE(FALSE)
00160 
00161 done:
00162     FUNC_LEAVE_NOAPI(ret_value)
00163 }
00164 
00165 /*-------------------------------------------------------------------------
00166  * Function:    H5V_vector_zerop_s
00167  *
00168  * Purpose:     Determines if all elements of a vector are zero.
00169  *
00170  * Return:      Success:        TRUE if all elements are zero,
00171  *                              FALSE otherwise
00172  *
00173  *              Failure:        TRUE if N is zero
00174  *
00175  * Programmer:  Robb Matzke
00176  *              Friday, October 10, 1997
00177  *
00178  * Modifications:
00179  *
00180  *-------------------------------------------------------------------------
00181  */
00182 static H5_inline htri_t UNUSED
00183 H5V_vector_zerop_s(int n, const hssize_t *v)
00184 {
00185     htri_t      ret_value=TRUE;       /* Return value */
00186 
00187     /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
00188     FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5V_vector_zerop_s)
00189 
00190     if (!v)
00191         HGOTO_DONE(TRUE)
00192     while (n--)
00193         if (*v++)
00194             HGOTO_DONE(FALSE)
00195 
00196 done:
00197     FUNC_LEAVE_NOAPI(ret_value)
00198 }
00199 
00200 /*-------------------------------------------------------------------------
00201  * Function:    H5V_vector_cmp_u
00202  *
00203  * Purpose:     Compares two vectors of the same size and determines if V1 is
00204  *              lexicographically less than, equal, or greater than V2.
00205  *
00206  * Return:      Success:        -1 if V1 is less than V2
00207  *                              0 if they are equal
00208  *                              1 if V1 is greater than V2
00209  *
00210  *              Failure:        0 if N is zero
00211  *
00212  * Programmer:  Robb Matzke
00213  *              Friday, October 10, 1997
00214  *
00215  * Modifications:
00216  *
00217  *-------------------------------------------------------------------------
00218  */
00219 static H5_inline int UNUSED
00220 H5V_vector_cmp_u (unsigned n, const hsize_t *v1, const hsize_t *v2)
00221 {
00222     int ret_value=0;    /* Return value */
00223 
00224     /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
00225     FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5V_vector_cmp_u)
00226 
00227     if (v1 == v2) HGOTO_DONE(0)
00228     if (v1 == NULL) HGOTO_DONE(-1)
00229     if (v2 == NULL) HGOTO_DONE(1)
00230     while (n--) {
00231         if (*v1 < *v2) HGOTO_DONE(-1)
00232         if (*v1 > *v2) HGOTO_DONE(1)
00233         v1++;
00234         v2++;
00235     }
00236 
00237 done:
00238     FUNC_LEAVE_NOAPI(ret_value)
00239 }
00240 
00241 
00242 /*-------------------------------------------------------------------------
00243  * Function:    H5V_vector_cmp_s
00244  *
00245  * Purpose:     Compares two vectors of the same size and determines if V1 is
00246  *              lexicographically less than, equal, or greater than V2.
00247  *
00248  * Return:      Success:        -1 if V1 is less than V2
00249  *                              0 if they are equal
00250  *                              1 if V1 is greater than V2
00251  *
00252  *              Failure:        0 if N is zero
00253  *
00254  * Programmer:  Robb Matzke
00255  *              Wednesday, April  8, 1998
00256  *
00257  * Modifications:
00258  *
00259  *-------------------------------------------------------------------------
00260  */
00261 static H5_inline int UNUSED
00262 H5V_vector_cmp_s (unsigned n, const hssize_t *v1, const hssize_t *v2)
00263 {
00264     int ret_value=0;    /* Return value */
00265 
00266     /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
00267     FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5V_vector_cmp_s)
00268 
00269     if (v1 == v2) HGOTO_DONE(0)
00270     if (v1 == NULL) HGOTO_DONE(-1)
00271     if (v2 == NULL) HGOTO_DONE(1)
00272     while (n--) {
00273         if (*v1 < *v2) HGOTO_DONE(-1)
00274         if (*v1 > *v2) HGOTO_DONE(1)
00275         v1++;
00276         v2++;
00277     }
00278 
00279 done:
00280     FUNC_LEAVE_NOAPI(ret_value)
00281 }
00282 
00283 
00284 /*-------------------------------------------------------------------------
00285  * Function:    H5V_vector_inc
00286  *
00287  * Purpose:     Increments V1 by V2
00288  *
00289  * Return:      void
00290  *
00291  * Programmer:  Robb Matzke
00292  *              Monday, October 13, 1997
00293  *
00294  * Modifications:
00295  *
00296  *-------------------------------------------------------------------------
00297  */
00298 static H5_inline void UNUSED
00299 H5V_vector_inc(int n, hsize_t *v1, const hsize_t *v2)
00300 {
00301     while (n--) *v1++ += *v2++;
00302 }
00303 
00304 /* Lookup table for general log2(n) routine */
00305 static const unsigned char LogTable256[] =
00306 {
00307     0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
00308     4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
00309     5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
00310     5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
00311     6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
00312     6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
00313     6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
00314     6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
00315     7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
00316     7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
00317     7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
00318     7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
00319     7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
00320     7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
00321     7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
00322     7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
00323 };
00324 
00325 
00326 /*-------------------------------------------------------------------------
00327  * Function:    H5V_log2_gen
00328  *
00329  * Purpose:     Determines the log base two of a number (i.e. log2(n)).
00330  *              (i.e. the highest bit set in a number)
00331  *
00332  * Note:        This is from the "Bit Twiddling Hacks" at:
00333  *                  http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogLookup
00334  *
00335  *              The version on the web-site is for 32-bit quantities and this
00336  *              version has been extended for 64-bit quantities.
00337  *
00338  * Return:      log2(n) (always - no failure condition)
00339  *
00340  * Programmer:  Quincey Koziol
00341  *              Monday, March  6, 2006
00342  *
00343  *-------------------------------------------------------------------------
00344  */
00345 static H5_inline unsigned UNUSED
00346 H5V_log2_gen(uint64_t n)
00347 {
00348     unsigned r;                         /* r will be log2(n) */
00349     register unsigned int t, tt, ttt;   /* temporaries */
00350 
00351 #ifdef H5_BAD_LOG2_CODE_GENERATED
00352     if(n > (uint64_t)0x7fffffffffffffff)
00353         r = 63;
00354     else {
00355         n &= (uint64_t)0x7fffffffffffffff;
00356 #endif /* H5_BAD_LOG2_CODE_GENERATED */
00357         if((ttt = (unsigned)(n >> 32)))
00358             if((tt = (unsigned)(n >> 48)))
00359                 r = (t = (unsigned)(n >> 56)) ? 56 + (unsigned)LogTable256[t] : 48 + (unsigned)LogTable256[tt & 0xFF];
00360             else
00361                 r = (t = (unsigned)(n >> 40)) ? 40 + (unsigned)LogTable256[t] : 32 + (unsigned)LogTable256[ttt & 0xFF];
00362         else
00363             if((tt = (unsigned)(n >> 16)))
00364                 r = (t = (unsigned)(n >> 24)) ? 24 + (unsigned)LogTable256[t] : 16 + (unsigned)LogTable256[tt & 0xFF];
00365             else
00366                 /* Added 'uint8_t' cast to pacify PGCC compiler */
00367                 r = (t = (unsigned)(n >> 8)) ? 8 + (unsigned)LogTable256[t] : (unsigned)LogTable256[(uint8_t)n];
00368 #ifdef H5_BAD_LOG2_CODE_GENERATED
00369     } /* end else */
00370 #endif /* H5_BAD_LOG2_CODE_GENERATED  */
00371 
00372     return(r);
00373 } /* H5V_log2_gen() */
00374 
00375 
00376 /* Lookup table for specialized log2(n) of power of two routine */
00377 static const unsigned MultiplyDeBruijnBitPosition[32] =
00378 {
00379       0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
00380         31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
00381 };
00382 
00383 
00384 /*-------------------------------------------------------------------------
00385  * Function:    H5V_log2_of2
00386  *
00387  * Purpose:     Determines the log base two of a number (i.e. log2(n)).
00388  *              (i.e. the highest bit set in a number)
00389  *
00390  * Note:        **N must be a power of two** and is limited to 32-bit quantities.
00391  *
00392  *              This is from the "Bit Twiddling Hacks" at:
00393  *                  http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogDeBruijn
00394  *
00395  * Return:      log2(n) (always - no failure condition)
00396  *
00397  * Programmer:  Quincey Koziol
00398  *              Monday, Febraury 27, 2006
00399  *
00400  *-------------------------------------------------------------------------
00401  */
00402 static H5_inline unsigned UNUSED
00403 H5V_log2_of2(uint32_t n)
00404 {
00405 #ifndef NDEBUG
00406     HDassert(POWER_OF_TWO(n));
00407 #endif /* NDEBUG */
00408     return(MultiplyDeBruijnBitPosition[(n * (uint32_t)0x077CB531UL) >> 27]);
00409 } /* H5V_log2_of2() */
00410 
00411 
00412 /*-------------------------------------------------------------------------
00413  * Function:    H5V_limit_enc_size
00414  *
00415  * Purpose:     Determine the # of bytes needed to encode values within a
00416  *              range from 0 to a given limit
00417  *
00418  * Return:      Number of bytes needed
00419  *
00420  * Programmer:  Quincey Koziol
00421  *              Thursday, March 13, 2008
00422  *
00423  *-------------------------------------------------------------------------
00424  */
00425 static H5_inline unsigned UNUSED
00426 H5V_limit_enc_size(uint64_t limit)
00427 {
00428     return (H5V_log2_gen(limit) / 8) + 1;
00429 } /* end H5V_limit_enc_size() */
00430 
00431 #endif /* H5Vprivate_H */
00432