Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
00001 /*----------------------------------------------------------------------------- 00002 00003 Tuple list definition and utilities 00004 00005 Conceptually, a tuple list is a list of n records or tuples, 00006 each with mi integers, ml longs, mul Ulongs, and mr reals 00007 (these types are defined in "types.h" as sint, slong, moab::EntityHandle, real; 00008 it may be that sint==slong) 00009 00010 There are four arrays, one for each type (vi,vl,vul,vr), 00011 with records layed out contiguously within each array 00012 00013 -----------------------------------------------------------------------------*/ 00014 00015 #ifndef TUPLE_LIST_HPP 00016 #define TUPLE_LIST_HPP 00017 00018 #include <climits> 00019 #include <cstdlib> 00020 00021 #include "moab/Types.hpp" 00022 #include <string> 00023 00024 /* Integral types defined here to ensure variable type sizes are consistent */ 00025 /* integer type to use for everything */ 00026 #if defined( USE_LONG ) 00027 #define INTEGER long 00028 #elif defined( USE_LONG_LONG ) 00029 #define INTEGER long long 00030 #elif defined( USE_SHORT ) 00031 #define INTEGER short 00032 #else 00033 #define INTEGER int 00034 #endif 00035 00036 /* when defined, use the given type for global indices instead of INTEGER */ 00037 #if defined( USE_GLOBAL_LONG_LONG ) 00038 #define GLOBAL_INT long long 00039 #elif defined( USE_GLOBAL_LONG ) 00040 #define GLOBAL_INT long 00041 #else 00042 #define GLOBAL_INT long 00043 #endif 00044 00045 /* floating point type to use for everything */ 00046 #if defined( USE_FLOAT ) 00047 typedef float realType; 00048 #elif defined( USE_LONG_DOUBLE ) 00049 typedef long double realType; 00050 #else 00051 typedef double realType; 00052 #endif 00053 00054 /* apparently uint and ulong can be defined already in standard headers */ 00055 #define uint uint_ 00056 //#define ulong ulong_ 00057 #define sint sint_ 00058 #define slong slong_ 00059 00060 typedef signed INTEGER sint; 00061 typedef unsigned INTEGER uint; 00062 #undef INTEGER 00063 00064 #ifdef GLOBAL_INT 00065 typedef signed GLOBAL_INT slong; 00066 // typedef unsigned GLOBAL_INT ulong; 00067 #else 00068 typedef sint slong; 00069 // typedef uint ulong; 00070 #endif 00071 00072 typedef moab::EntityHandle Ulong; 00073 00074 namespace moab 00075 { 00076 void fail( const char* fmt, ... ); 00077 00078 class TupleList 00079 { 00080 public: 00081 /*--------------------------------------------------------------------------- 00082 00083 buffer: a simple class which can be used to store data 00084 00085 The ptr points to the chunk of memory allocated for the buffer's use. The 00086 size denotes the size of the allocated memory; the user must take care to 00087 note how much of the buffer they are using. 00088 00089 ---------------------------------------------------------------------------*/ 00090 class buffer 00091 { 00092 public: 00093 size_t buffSize; 00094 char* ptr; 00095 00096 /**Constructor which sets an initial capacity of the buffer 00097 */ 00098 buffer( size_t sz ); 00099 00100 /**Default constructor (Note: buffer must be initialized before use!) 00101 */ 00102 buffer(); 00103 00104 ~buffer() 00105 { 00106 this->reset(); 00107 }; 00108 00109 /**Initializes the buffer to have a capacity of size 00110 */ 00111 void buffer_init_( size_t sz, const char* file ); 00112 00113 /**Ensures that the buffer has at least a capacity of min 00114 */ 00115 void buffer_reserve_( size_t min, const char* file ); 00116 00117 /**Frees any allocated memory used by the buffer 00118 */ 00119 void reset(); 00120 00121 // Aliases for using the buffer methods 00122 #define buffer_init( sz ) buffer_init_( sz, __FILE__ ) 00123 #define buffer_reserve( min ) buffer_reserve_( min, __FILE__ ) 00124 }; 00125 00126 public: 00127 /**Constructor that takes all parameters and initializes the TupleList 00128 */ 00129 TupleList( uint mi, uint ml, uint mul, uint mr, uint max ); 00130 00131 /**Default constructor (Note: TupleList must be initialized before use!) 00132 */ 00133 TupleList(); 00134 00135 ~TupleList() 00136 { 00137 reset(); 00138 }; 00139 00140 /**Initializes the starting memory to be used by the TupleList 00141 * Note: TupleLists must be initialized before they can be used 00142 * 00143 * param mi number of signed ints in each tuple 00144 * param ml number of long ints in each tuple 00145 * param mul number of unsigned long ints in each tuple 00146 * param mr number of reals in each tuple 00147 * param max starting capacity of max tuples in the TupleList 00148 */ 00149 void initialize( uint mi, uint ml, uint mul, uint mr, uint max ); 00150 00151 /**Resizes the TupleList to a new max 00152 * 00153 * param max the new max capacity of the TupleList 00154 */ 00155 ErrorCode resize( uint max ); 00156 00157 /**Sorts the TupleList by 'key' 00158 * if key<mi: key represents the key'th index in vi 00159 * if mi<key<ml: key represents the (key-mi)'th index in vl 00160 * if ml<key<mul: key represents the (key-mi-ml)'th index in vul 00161 * 00162 * param key index to be sorted by 00163 * param *buf buffer space used for sorting 00164 */ 00165 /*------------------------------------------------------------------------------ 00166 00167 Hybrid Stable Sort 00168 00169 low-overhead merge sort when n is small, 00170 otherwise asymptotically superior radix sort 00171 00172 result = O(n) sort with good performance for all n 00173 00174 A, n, stride : specifices the input 00175 00176 sort: 00177 uint out[n] : the sorted values (output) 00178 uint work[n]: scratch area 00179 00180 index_sort: 00181 uint idx[n] : the sorted indices (output) 00182 sort_data work[2*n]: scratch area 00183 00184 ----------------------------------------------------------------------------*/ 00185 ErrorCode sort( uint key, TupleList::buffer* buf ); 00186 00187 /**Frees all allocated memory in use by the TupleList 00188 */ 00189 void reset(); 00190 00191 /**Adds one to the total number of in-use tuples and resizes if necessary 00192 */ 00193 void reserve(); 00194 00195 /**Finds index of the tuple containing 'value' at the key_numth index of 00196 * said tuple; return -1 if key_num is out of bounds or if 'value' not found 00197 * Uses binary search if TupleList is sorted by the key_numth field, seqential 00198 * otherwise (very slow for large TupleLists; please sort before you search) 00199 * 00200 * param key_num index of the tuple where to search for value 00201 * param value value to search for at the given key_num 00202 * return the index of the tuple that contains value 00203 */ 00204 int find( unsigned int key_num, sint value ); 00205 int find( unsigned int key_num, slong value ); 00206 int find( unsigned int key_num, Ulong value ); 00207 int find( unsigned int key_num, realType value ); 00208 00209 /**get the mth number of return type in the index'th tuple 00210 * returns 0 if m or index is out of bounds 00211 * 00212 * param index index of the tuple within the TupleList 00213 * param m index of the value within the tuple 00214 * return the value at the given position 00215 */ 00216 sint get_sint( unsigned int index, unsigned int m ); 00217 slong get_int( unsigned int index, unsigned int m ); 00218 Ulong get_ulong( unsigned int index, unsigned int m ); 00219 realType get_double( unsigned int index, unsigned int m ); 00220 00221 /**get pointers to the data for the index'th tuple; ptr is 00222 * NULL if that type is not part of this tuple 00223 * 00224 * param index index of the tuple needed 00225 * param *&sp, *&ip, *&lp, *&dp pointers to each piece of the tuple 00226 */ 00227 ErrorCode get( unsigned int index, const sint*& sp, const slong*& ip, const Ulong*& lp, const realType*& dp ); 00228 00229 /**push back a new tuple on the TupleList; 00230 * 00231 * param *sp pointer to a list of signed ints 00232 * param *ip pointer to a list of signed longs 00233 * param *lp pointer to a list of unsigned longs 00234 * param *dp pointer to a list of reals 00235 * return index of that tuple 00236 */ 00237 unsigned int push_back( sint* sp, slong* ip, Ulong* lp, realType* dp ); 00238 00239 /*Enable or disable direct write access to arrays 00240 This is important so that we know whether or not 00241 the user of this class can directly modify data 00242 which can affect operations such as 00243 whether or not we know the tuple list is sorted 00244 (for a binary search)*/ 00245 void enableWriteAccess(); 00246 void disableWriteAccess(); 00247 00248 /*Get information on the Tuple Sizes 00249 * param &mi_out Count of uints in a tuple 00250 * param &ml_out Count of uints in a tuple 00251 * param &mul_out Count of uints in a tuple 00252 * param &mr_out Count of uints in a tuple 00253 */ 00254 void getTupleSize( uint& mi_out, uint& ml_out, uint& mul_out, uint& mr_out ) const; 00255 00256 /*Set the count of Tuples in the Tuple List 00257 * Warning, automatically calls enableWriteAccess() 00258 * param n_in New count of Tuples 00259 */ 00260 void set_n( uint n_in ); 00261 00262 /* Get the count of Tuples in the Tuple List */ 00263 uint get_n() const; 00264 00265 /*Get the maximum number of Tuples currently allocated for*/ 00266 uint get_max() const; 00267 00268 bool get_writeEnabled() const; 00269 00270 /*Increment n by 1 00271 * Warning, automatically calls enableWriteAccess() 00272 * returns current TupleList.n after the increment */ 00273 uint inc_n(); 00274 00275 void print( const char* ) const; 00276 void print_to_file( const char* ) const; 00277 00278 // Variables to allow for direct write access 00279 sint* vi_wr; 00280 slong* vl_wr; 00281 Ulong* vul_wr; 00282 realType* vr_wr; 00283 00284 // Variables to allow for direct read access 00285 const sint* vi_rd; 00286 slong* vl_rd; 00287 Ulong* vul_rd; 00288 realType* vr_rd; 00289 00290 private: 00291 /* storage layed out as: vi[max][mi], vl[max][ml], vul[max][mul], 00292 * vr[max][mr] where "tuple" i is given by 00293 * (vi[i][0:mi-1],vl[i][0:ml-1],vul[i][0:mul-1],vr[i][0:mr-1]). 00294 * only the first n tuples are in use */ 00295 uint mi, ml, mul, mr; 00296 uint n, max; 00297 sint* vi; 00298 slong* vl; 00299 Ulong* vul; 00300 realType* vr; 00301 00302 // Used by sort: see .cpp for more details 00303 // void sort_bits(uint *work, uint key); 00304 void permute( uint* perm, void* work ); 00305 00306 /* last_sorted = the last sorted position in the tuple (if the 00307 * TupleList has not been sorted, or has become unsorted--i.e. 00308 * by adding a tuple--last_sorted = -1) */ 00309 int last_sorted; 00310 // Whether or not the object is currently allowing direct 00311 // write access to the arrays 00312 bool writeEnabled; 00313 00314 typedef uint Index; 00315 00316 template < typename Value > 00317 struct SortData 00318 { 00319 Value v; 00320 Index i; 00321 }; 00322 00323 #define DIGIT_BITS 8 00324 #define DIGIT_VALUES ( 1 << DIGIT_BITS ) 00325 #define DIGIT_MASK ( (Value)( DIGIT_VALUES - 1 ) ) 00326 #define CEILDIV( a, b ) ( ( ( a ) + (b)-1 ) / ( b ) ) 00327 #define DIGITS CEILDIV( CHAR_BIT * sizeof( Value ), DIGIT_BITS ) 00328 #define VALUE_BITS ( DIGIT_BITS * DIGITS ) 00329 #define COUNT_SIZE ( DIGITS * DIGIT_VALUES ) 00330 00331 template < class Value > 00332 static Value radix_count( const Value* A, const Value* end, Index stride, Index count[DIGITS][DIGIT_VALUES] ); 00333 00334 static void radix_offsets( Index* c ); 00335 00336 template < class Value > 00337 static unsigned radix_zeros( Value bitorkey, Index count[DIGITS][DIGIT_VALUES], unsigned* shift, Index** offsets ); 00338 00339 template < class Value > 00340 static void radix_index_pass_b( const Value* A, 00341 Index n, 00342 Index stride, 00343 unsigned sh, 00344 Index* off, 00345 SortData< Value >* out ); 00346 00347 template < class Value > 00348 static void radix_index_pass_m( const SortData< Value >* src, 00349 const SortData< Value >* end, 00350 unsigned sh, 00351 Index* off, 00352 SortData< Value >* out ); 00353 00354 template < class Value > 00355 static void radix_index_pass_e( const SortData< Value >* src, 00356 const SortData< Value >* end, 00357 unsigned sh, 00358 Index* off, 00359 Index* out ); 00360 00361 template < class Value > 00362 static void radix_index_pass_be( const Value* A, Index n, Index stride, unsigned sh, Index* off, Index* out ); 00363 00364 /*------------------------------------------------------------------------------ 00365 00366 00367 Radix Sort 00368 00369 stable; O(n) time 00370 00371 ----------------------------------------------------------------------------*/ 00372 template < class Value > 00373 static void radix_index_sort( const Value* A, Index n, Index stride, Index* idx, SortData< Value >* work ); 00374 00375 /*------------------------------------------------------------------------------ 00376 00377 00378 Merge Sort 00379 00380 stable; O(n log n) time 00381 00382 ----------------------------------------------------------------------------*/ 00383 template < class Value > 00384 static void merge_index_sort( const Value* A, const Index An, Index stride, Index* idx, SortData< Value >* work ); 00385 00386 template < class Value > 00387 static void index_sort( const Value* A, Index n, Index stride, Index* idx, SortData< Value >* work ); 00388 00389 #undef DIGIT_BITS 00390 #undef DIGIT_VALUES 00391 #undef DIGIT_MASK 00392 #undef CEILDIV 00393 #undef DIGITS 00394 #undef VALUE_BITS 00395 #undef COUNT_SIZE 00396 }; 00397 00398 inline uint TupleList::get_max() const 00399 { 00400 return max; 00401 } 00402 inline uint TupleList::get_n() const 00403 { 00404 return n; 00405 } 00406 inline bool TupleList::get_writeEnabled() const 00407 { 00408 return writeEnabled; 00409 } 00410 00411 } // namespace moab 00412 #endif 00413 #include <cstdlib>