1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 2 * Copyright by The HDF Group. * 3 * Copyright by the Board of Trustees of the University of Illinois. * 4 * All rights reserved. * 5 * * 6 * This file is part of HDF. The full HDF copyright notice, including * 7 * terms governing use, modification, and redistribution, is contained in * 8 * the COPYING file, which can be found at the root of the source code * 9 * distribution tree, or in https://support.hdfgroup.org/ftp/HDF/releases/. * 10 * If you do not have access to either file, you may request a copy from * 11 * help@hdfgroup.org. * 12 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 13 14 /* $Id$ */ 15 16 /*----------------------------------------------------------------------------- 17 * File: atom.h 18 * Purpose: header file for atom API 19 * Dependencies: 20 * Invokes: 21 * Contents: 22 * Structure definitions: 23 * Constant definitions: 24 *---------------------------------------------------------------------------*/ 25 26 /* avoid re-inclusion */ 27 #ifndef __ATOM_H 28 #define __ATOM_H 29 30 #include "H4api_adpt.h" 31 32 /* Atom Features control */ 33 /* Define the following macro for fast hash calculations (but limited hash sizes) */ 34 #define HASH_SIZE_POWER_2 35 36 /* Define the following macro for atom caching over all the atoms */ 37 #define ATOMS_ARE_CACHED 38 39 /* Define the following macro for "inline" atom lookups from the cache */ 40 #ifdef ATOMS_ARE_CACHED /* required for this to work */ 41 #define ATOMS_CACHE_INLINE 42 #endif /* ATOMS_ARE_CACHED */ 43 44 #ifdef ATOMS_CACHE_INLINE 45 /* Do swap using XOR operator. Ugly but fast... -QAK */ 46 #define HAIswap_cache(i,j) \ 47 atom_id_cache[i]^=atom_id_cache[j], \ 48 atom_obj_cache[i]=(void *)((hdf_pint_t)atom_obj_cache[j]^(hdf_pint_t)atom_obj_cache[i]), \ 49 atom_id_cache[j]^=atom_id_cache[i], \ 50 atom_obj_cache[j]=(void *)((hdf_pint_t)atom_obj_cache[i]^(hdf_pint_t)atom_obj_cache[j]), \ 51 atom_id_cache[i]^=atom_id_cache[j], \ 52 atom_obj_cache[i]=(void *)((hdf_pint_t)atom_obj_cache[i]^(hdf_pint_t)atom_obj_cache[j]) 53 54 /* Note! This is hardwired to the atom cache value being 4 */ 55 #define HAatom_object(atm) \ 56 (atom_id_cache[0]==atm ? atom_obj_cache[0] : \ 57 atom_id_cache[1]==atm ? (HAIswap_cache(0,1),atom_obj_cache[0]) : \ 58 atom_id_cache[2]==atm ? (HAIswap_cache(1,2),atom_obj_cache[1]) : \ 59 atom_id_cache[3]==atm ? (HAIswap_cache(2,3),atom_obj_cache[2]) : \ 60 HAPatom_object(atm)) 61 #endif /* ATOMS_CACHE_INLINE */ 62 63 #include "hdf.h" 64 65 /* Group values allowed */ 66 typedef enum {BADGROUP=(-1), /* Invalid Group */ 67 DDGROUP=0, /* Group ID for DD objects */ 68 AIDGROUP=1, /* Group ID for access ID objects */ 69 FIDGROUP=2, /* Group ID for file ID objects */ 70 VGIDGROUP=3, /* Group ID for Vgroup ID objects */ 71 VSIDGROUP=4, /* Group ID for Vdata ID objects */ 72 GRIDGROUP=5, /* Group ID for GR ID objects */ 73 RIIDGROUP=6, /* Group ID for RI ID objects */ 74 BITIDGROUP=7, /* Group ID for Bitfile ID objects */ 75 ANIDGROUP=8, /* Group ID for Annotation ID objects */ 76 MAXGROUP /* Highest group in group_t (Invalid as true group) */ 77 } group_t; 78 79 /* Type of atoms to return to users */ 80 typedef int32 atom_t; 81 82 /* Type of the function to compare objects & keys */ 83 typedef intn (*HAsearch_func_t)(const void * obj, const void * key); 84 85 #if defined ATOM_MASTER | defined ATOM_TESTER 86 87 /* # of bits to use for Group ID in each atom (change if MAXGROUP>16) */ 88 #define GROUP_BITS 4 89 #define GROUP_MASK 0x0F 90 91 /* # of bits to use for the Atom index in each atom (change if MAXGROUP>16) */ 92 #define ATOM_BITS 28 93 #define ATOM_MASK 0x0FFFFFFF 94 95 #ifdef ATOMS_ARE_CACHED 96 /* # of previous atoms cached, change inline caching macros (HAatom_object & HAIswap_cache) if this changes */ 97 #define ATOM_CACHE_SIZE 4 98 #endif /* ATOMS_ARE_CACHED */ 99 100 /* Map an atom to a Group number */ 101 #define ATOM_TO_GROUP(a) ((group_t)((((atom_t)(a))>>((sizeof(atom_t)*8)-GROUP_BITS))&GROUP_MASK)) 102 103 #ifdef HASH_SIZE_POWER_2 104 /* Map an atom to a hash location (assumes s is a power of 2 and smaller than the ATOM_MASK constant) */ 105 #define ATOM_TO_LOC(a,s) ((atom_t)(a)&((s)-1)) 106 #else /* HASH_SIZE_POWER_2 */ 107 /* Map an atom to a hash location */ 108 #define ATOM_TO_LOC(a,s) (((atom_t)(a)&ATOM_MASK)%(s)) 109 #endif /* HASH_SIZE_POWER_2 */ 110 111 /* Combine a Group number and an atom index into an atom */ 112 #define MAKE_ATOM(g,i) ((((atom_t)(g)&GROUP_MASK)<<((sizeof(atom_t)*8)-GROUP_BITS))|((atom_t)(i)&ATOM_MASK)) 113 114 /* Atom information structure used */ 115 typedef struct atom_info_struct_tag { 116 atom_t id; /* atom ID for this info */ 117 VOIDP *obj_ptr; /* pointer associated with the atom */ 118 struct atom_info_struct_tag *next; /* link to next atom (in case of hash-clash) */ 119 }atom_info_t; 120 121 /* Atom group structure used */ 122 typedef struct atom_group_struct_tag { 123 uintn count; /* # of times this group has been initialized */ 124 intn hash_size; /* size of the hash table to store the atoms in */ 125 uintn atoms; /* current number of atoms held */ 126 uintn nextid; /* atom ID to use for the next atom */ 127 atom_info_t **atom_list;/* pointer to an array of ptrs to atoms */ 128 }atom_group_t; 129 130 /* Define this in only one place */ 131 #ifdef ATOM_MASTER 132 133 /* Array of pointers to atomic groups */ 134 static atom_group_t *atom_group_list[MAXGROUP]={NULL}; 135 136 /* Pointer to the atom node free list */ 137 static atom_info_t *atom_free_list=NULL; 138 139 #ifdef ATOMS_ARE_CACHED 140 /* Array of pointers to atomic groups */ 141 #ifdef OLD_WAY 142 static atom_t atom_id_cache[ATOM_CACHE_SIZE]={-1,-1,-1,-1}; 143 static VOIDP atom_obj_cache[ATOM_CACHE_SIZE]={NULL}; 144 #else /* OLD_WAY */ 145 HDFPUBLIC atom_t atom_id_cache[ATOM_CACHE_SIZE]={-1,-1,-1,-1}; 146 HDFPUBLIC VOIDP atom_obj_cache[ATOM_CACHE_SIZE]={NULL}; 147 #endif /* OLD_WAY */ 148 #endif /* ATOMS_ARE_CACHED */ 149 #endif /* ATOM_MASTER */ 150 151 /* Useful routines for generally private use */ 152 153 #endif /* ATOM_MASTER | ATOM_TESTER */ 154 155 #ifndef ATOM_MASTER 156 HDFLIBAPI atom_t atom_id_cache[]; 157 HDFLIBAPI VOIDP atom_obj_cache[]; 158 #endif /* ATOM_MASTER */ 159 160 #if defined c_plusplus || defined __cplusplus 161 extern "C" 162 { 163 #endif /* c_plusplus || __cplusplus */ 164 165 /****************************************************************************** 166 NAME 167 HAinit_group - Initialize an atomic group 168 169 DESCRIPTION 170 Creates an atomic group to store atoms in. If the group has already been 171 initialized, this routine just increments the count of # of initializations 172 and returns without trying to change the size of the hash table. 173 174 RETURNS 175 Returns SUCCEED if successful and FAIL otherwise 176 177 *******************************************************************************/ 178 HDFLIBAPI intn HAinit_group(group_t grp, /* IN: Group to initialize */ 179 intn hash_size /* IN: Minimum hash table size to use for group */ 180 ); 181 182 /****************************************************************************** 183 NAME 184 HAdestroy_group - Destroy an atomic group 185 186 DESCRIPTION 187 Destroys an atomic group which atoms are stored in. If the group still 188 has atoms which are registered, this routine fails. If there have been 189 multiple initializations of the group, this routine just decrements the 190 count of initializations and does not check the atoms out-standing. 191 192 RETURNS 193 Returns SUCCEED if successful and FAIL otherwise 194 195 *******************************************************************************/ 196 HDFLIBAPI intn HAdestroy_group(group_t grp /* IN: Group to destroy */ 197 ); 198 199 /****************************************************************************** 200 NAME 201 HAregister_atom - Register an object in a group and get an atom for it. 202 203 DESCRIPTION 204 Registers an object in a group and returns an atom for it. This routine 205 does _not_ check for unique-ness of the objects, if you register an object 206 twice, you will get two different atoms for it. This routine does make 207 certain that each atom in a group is unique. Atoms are created by getting 208 a unique number for the group the atom is in and incorporating the group 209 into the atom which is returned to the user. 210 211 RETURNS 212 Returns atom if successful and FAIL otherwise 213 214 *******************************************************************************/ 215 HDFLIBAPI atom_t HAregister_atom(group_t grp, /* IN: Group to register the object in */ 216 VOIDP object /* IN: Object to attach to atom */ 217 ); 218 219 /****************************************************************************** 220 NAME 221 HAatom_object - Returns to the object ptr for the atom 222 223 DESCRIPTION 224 Retrieves the object ptr which is associated with the atom. 225 226 RETURNS 227 Returns object ptr if successful and NULL otherwise 228 229 *******************************************************************************/ 230 #ifdef ATOMS_CACHE_INLINE 231 HDFLIBAPI VOIDP HAPatom_object(atom_t atm /* IN: Atom to retrieve object for */ 232 ); 233 #else /* ATOMS_CACHE_INLINE */ 234 HDFLIBAPI VOIDP HAatom_object(atom_t atm /* IN: Atom to retrieve object for */ 235 ); 236 #endif /* ATOMS_CACHE_INLINE */ 237 238 /****************************************************************************** 239 NAME 240 HAatom_group - Returns to the group for the atom 241 242 DESCRIPTION 243 Retrieves the group which is associated with the atom. 244 245 RETURNS 246 Returns group if successful and FAIL otherwise 247 248 *******************************************************************************/ 249 HDFLIBAPI group_t HAatom_group(atom_t atm /* IN: Atom to retrieve group for */ 250 ); 251 252 /****************************************************************************** 253 NAME 254 HAremove_atom - Removes an atom from a group 255 256 DESCRIPTION 257 Removes an atom from a group. 258 259 RETURNS 260 Returns atom's object if successful and FAIL otherwise 261 262 *******************************************************************************/ 263 HDFLIBAPI VOIDP HAremove_atom(atom_t atm /* IN: Atom to remove */ 264 ); 265 266 /****************************************************************************** 267 NAME 268 HAsearch_atom - Search for an object in a group and get it's pointer. 269 270 DESCRIPTION 271 Searchs for an object in a group and returns the pointer to it. 272 This routine calls the function pointer passed in for each object in the 273 group until it finds a match. Currently there is no way to resume a 274 search. 275 276 RETURNS 277 Returns pointer an atom's object if successful and NULL otherwise 278 279 *******************************************************************************/ 280 HDFLIBAPI VOIDP HAsearch_atom(group_t grp, /* IN: Group to search for the object in */ 281 HAsearch_func_t func, /* IN: Ptr to the comparison function */ 282 const void * key /* IN: pointer to key to compare against */ 283 ); 284 285 /****************************************************************************** 286 NAME 287 HAshutdown - Terminate various static buffers. 288 289 DESCRIPTION 290 Free various buffers allocated in the HA routines. 291 292 RETURNS 293 Returns SUCCEED/FAIL 294 295 *******************************************************************************/ 296 HDFLIBAPI intn HAshutdown(void); 297 298 #if defined c_plusplus || defined __cplusplus 299 } 300 #endif /* c_plusplus || __cplusplus */ 301 302 #endif /* __ATOM_H */ 303 304