• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

sst/elements/genericProc/programs/libcprops/collection.h

Go to the documentation of this file.
00001 #ifndef _CP_COLLECTION_H
00002 #define _CP_COLLECTION_H
00003 
00004 #include "common.h"
00005 
00006 __BEGIN_DECLS
00007 
00008 #include "log.h"
00009 
00010 #ifdef HAVE_PTHREAD_H
00011 #include <pthread.h>
00012 #endif
00013 
00014 #ifdef _WINDOWS
00015 #define _WIN32_WINNT 0x0400 /* for SignalObjectAndWait */
00016 #include <Windows.h>
00017 #endif
00018 
00019 /** @{ */
00020 /**
00021  * @file
00022  *
00023  * The c collection classes provide plain c implementations of famous data
00024  * structures and algorithms such as linked lists, hash tables, hash lists and
00025  * an extensible tree implementation (see graph.h). Behavior in terms of
00026  * synchronization and member uniqueness may be set on initialization using the
00027  * appropriate constructor function with the required flags. The default 
00028  * implementations are synchronized, and mostly allow mutliple values with the
00029  * notable exception of the cp_hashtable and cp_hashlist collections which do 
00030  * not by default. Other subtle differences deriving from data structure 
00031  * characteristics or implementation inconsistencies would suggest reading the 
00032  * inline documentation in the header files for the specific collection you 
00033  * intend to use. 
00034  *
00035  * This header file defines macros and function types used commonly throughout 
00036  * the package.
00037  */
00038 
00039 /** use collection defaults */
00040 #define COLLECTION_MODE_PLAIN             0
00041 /** collection copies and deletes elements (keys, values) */
00042 #define COLLECTION_MODE_DEEP              1
00043 /** collection allows non-unique keys */
00044 #define COLLECTION_MODE_MULTIPLE_VALUES   2
00045 /** collection stores copies of elements (keys, values) */
00046 #define COLLECTION_MODE_COPY              4
00047 /** no synchronization - suitable for the single threaded situation or if you 
00048   * want to do the synchronization yourself. */
00049 #define COLLECTION_MODE_NOSYNC            8
00050 /** 
00051  * The collection does not resize underlying hashtables. It might make sense 
00052  * to set this temporarily in code sections that shouldn't be unexpectedly 
00053  * slowed down by a resize operation, but resize should be allowed if the 
00054  * table fill factor is expected to go over ~70%, which is the point at which
00055  * hashtable performace is rumored to start degrading. 
00056  */
00057 #define COLLECTION_MODE_NORESIZE         16
00058 /**
00059  * hashlist multiple values are returned in list order (O(N)) rather than 
00060  * insertion order (O(1))
00061  */
00062 #define COLLECTION_MODE_LIST_ORDER               32
00063 /**
00064  * indicates a transaction is in progress
00065  */
00066 #define COLLECTION_MODE_IN_TRANSACTION   64
00067 
00068 /** no lock */
00069 #define COLLECTION_LOCK_NONE   0
00070 /** lock for reading */
00071 #define COLLECTION_LOCK_READ   1
00072 /** lock for writing */
00073 #define COLLECTION_LOCK_WRITE  2
00074 
00075 typedef enum 
00076 {
00077   CP_OP_LT = 1, 
00078   CP_OP_LE = 2, 
00079   CP_OP_EQ = 3, 
00080   CP_OP_NE = 4, 
00081   CP_OP_GE = 5, 
00082   CP_OP_GT = 6
00083 } cp_op;
00084 
00085 /**
00086  * copy function.
00087  *
00088  * In cases where the collection holds copies rather than references to the
00089  * original objects. To do this you need to provide a copy function for
00090  * the items.
00091  */
00092 typedef void *(*cp_copy_fn)(void *);
00093 
00094 /**
00095  * destructor function.
00096  */
00097 typedef void (*cp_destructor_fn)(void *);
00098 
00099 /**
00100  * comparator functions implement strcmp semantics - 0 for identical keys, 
00101  * non-zero otherwise.
00102  */
00103 typedef int (*cp_compare_fn)(void *, void *);
00104 
00105 /**
00106  * callback function for iterator callback etc
00107  */
00108 typedef int (*cp_callback_fn)(void *entry, void *client_prm);
00109 
00110 typedef CPROPS_DLL struct _cp_mapping
00111 {
00112         void *key;
00113         void *value;
00114 } cp_mapping;
00115 
00116 #define cp_mapping_key(m)       ((m)->key)
00117 #define cp_mapping_value(m)     ((m)->value)
00118 
00119 CPROPS_DLL
00120 cp_mapping *cp_mapping_create(void *key, void *value);
00121 
00122 typedef int (*cp_mapping_cmp_fn)(cp_mapping *a, cp_mapping *b);
00123 
00124 /**
00125  * extract an alternate key from a record for indexing 
00126  */
00127 typedef void *(*cp_key_fn)(void *record);
00128 
00129 typedef enum { CP_UNIQUE, CP_MULTIPLE } cp_index_type;
00130 
00131 typedef CPROPS_DLL struct _cp_index
00132 {
00133         cp_index_type type; /* indices can be either unique or non-unique */
00134         cp_key_fn key;
00135         cp_compare_fn cmp;
00136 } cp_index;
00137 
00138 CPROPS_DLL
00139 cp_index *cp_index_create(cp_index_type type, cp_key_fn key, cp_compare_fn cmp);
00140 
00141 CPROPS_DLL
00142 cp_index *cp_index_copy(cp_index *src);
00143 
00144 /* cp_index_compare requires cp_vector definitions for non-unique indices. The
00145  * implementation is in vector.c
00146  */
00147 CPROPS_DLL
00148 int cp_index_compare(cp_index *index, void *a, void *b);
00149 
00150 struct _cp_string;
00151 
00152 typedef struct _cp_string *(*cp_serialize_fn)(void *object);
00153 typedef void *(*cp_deserialize_fn)(void *buf, size_t *used); 
00154 
00155 /**
00156  * lock for collection types - current implementation uses pthread_rwlock_t
00157  *
00158  * _WINDOWS implementation for cp_cond is based on "Strategies for Implementing 
00159  * POSIX Condition Variables on _WINDOWS" by Douglas C. Schmidt and Irfan Pyarali
00160  * see http://www.cs.wustl.edu/~schmidt/_WINDOWS-cv-1.html
00161  */
00162 #ifdef HAVE_PTHREAD_H
00163 typedef pthread_t cp_thread;
00164 typedef pthread_rwlock_t cp_lock;
00165 typedef pthread_mutex_t cp_mutex;
00166 typedef pthread_cond_t cp_cond;
00167 #define cp_thread_create(thread, attr, fn, prm) pthread_create(&(thread), attr, fn, prm)
00168 #define cp_thread_join pthread_join
00169 #define cp_thread_detach pthread_detach
00170 #define cp_thread_self pthread_self
00171 #define cp_mutex_init pthread_mutex_init
00172 #define cp_mutex_lock pthread_mutex_lock
00173 #define cp_mutex_unlock pthread_mutex_unlock
00174 #define cp_mutex_destroy pthread_mutex_destroy
00175 #define cp_cond_init pthread_cond_init
00176 #define cp_cond_wait pthread_cond_wait
00177 #define cp_cond_signal pthread_cond_signal
00178 #define cp_cond_broadcast pthread_cond_broadcast
00179 #define cp_cond_destroy pthread_cond_destroy
00180 #define cp_lock_init pthread_rwlock_init
00181 #define cp_lock_rdlock pthread_rwlock_rdlock
00182 #define cp_lock_wrlock pthread_rwlock_wrlock
00183 #define cp_lock_unlock pthread_rwlock_unlock
00184 #define cp_lock_destroy pthread_rwlock_destroy
00185 #define cp_thread_equal pthread_equal
00186 #ifndef CP_HAS_PTHREAD_MUTEX_RECURSIVE
00187 #ifdef CP_HAS_PTHREAD_MUTEX_RECURSIVE_NP
00188 #define CP_HAS_PTHREAD_MUTEX_RECURSIVE CP_HAS_PTHREAD_MUTEX_RECURSIVE_NP
00189 #endif /* CP_HAS_PTHREAD_MUTEX_RECURSIVE_NP */
00190 #endif /* CP_HAS_PTHREAD_MUTEX_RECURSIVE */
00191 #else 
00192 #ifdef _WINDOWS
00193 typedef HANDLE cp_thread;
00194 typedef HANDLE *cp_mutex;
00195 #define cp_thread_create(thread, attr, fn, prm) \
00196         (((thread) = CreateThread(attr, 0, (LPTHREAD_START_ROUTINE) fn, prm, 0, NULL)) == NULL)
00197 #define cp_thread_join(thread, exp) \
00198         { \
00199                 cp_thread p = thread; \
00200                 WaitForSingleObject(p, INFINITE); \
00201         }
00202 #define cp_thread_detach 
00203 #define cp_thread_self GetCurrentThread
00204 CPROPS_DLL
00205 int cp_mutex_init(cp_mutex *mutex, void *attr);
00206 #define cp_mutex_lock(mutex) (WaitForSingleObject((*(mutex)), INFINITE))
00207 #define cp_mutex_unlock(mutex) (ReleaseMutex(*(mutex)))
00208 #define cp_mutex_destroy(mutex) (CloseHandle(*(mutex)))
00209 
00210 /* WIN32 implementation of a basic POSIX-condition-variable-like API
00211  * 
00212  * based on "Strategies for Implementing POSIX Condition Variables on WIN32"
00213  * by Douglas C. Schmidt and Irfan Pyarali - 
00214  * see http://www.cs.wustl.edu/~schmidt/WIN32-cv-1.html
00215  */
00216 typedef CPROPS_DLL struct
00217 {
00218   int waiters_count_;
00219   // Number of waiting threads.
00220 
00221   CRITICAL_SECTION waiters_count_lock_;
00222   // Serialize access to <waiters_count_>.
00223 
00224   HANDLE sema_;
00225   // Semaphore used to queue up threads waiting for the condition to
00226   // become signaled. 
00227 
00228   HANDLE waiters_done_;
00229   // An auto-reset event used by the broadcast/signal thread to wait
00230   // for all the waiting thread(s) to wake up and be released from the
00231   // semaphore. 
00232 
00233   size_t was_broadcast_;
00234   // Keeps track of whether we were broadcasting or signaling.  This
00235   // allows us to optimize the code if we're just signaling.
00236 } cp_cond;
00237 
00238 CPROPS_DLL int cp_cond_init(cp_cond *cv, const void *attr); // pthread_condattr_t *)
00239 CPROPS_DLL int cp_cond_wait(cp_cond *cv, cp_mutex *mutex);
00240 CPROPS_DLL int cp_cond_signal(cp_cond *cv);
00241 CPROPS_DLL int cp_cond_broadcast(cp_cond *cv);
00242 CPROPS_DLL int cp_cond_destroy(cp_cond *cv);
00243 
00244 /* WIN32 implementation of a basic POSIX-read-write-lock-like API. cp_lock
00245  * is not upgradeable, ie attempting to obtain the lock if the current
00246  * thread already owns it causes deadlock.
00247  */
00248 typedef CPROPS_DLL struct _cp_lock
00249 {
00250         HANDLE access_mutex;
00251 //      HANDLE write_mutex;
00252 
00253         DWORD writer;
00254 
00255         int readers;
00256         int writer_waiting;
00257 
00258 } cp_lock;
00259 
00260 CPROPS_DLL int cp_lock_init(cp_lock *lock, void *attr);
00261 CPROPS_DLL int cp_lock_rdlock(cp_lock *lock);
00262 CPROPS_DLL int cp_lock_wrlock(cp_lock *lock);
00263 CPROPS_DLL int cp_lock_unlock(cp_lock *lock);
00264 CPROPS_DLL int cp_lock_destroy(cp_lock *lock);
00265 
00266 #define cp_thread_equal(p, q) ((p) == (q))
00267 #endif
00268 #endif
00269 
00270 typedef CPROPS_DLL struct _cp_wrap
00271 {
00272         void *item;
00273         cp_destructor_fn dtr;
00274 } cp_wrap;
00275 
00276 CPROPS_DLL cp_wrap *cp_wrap_new(void *item, cp_destructor_fn dtr);
00277 CPROPS_DLL void cp_wrap_delete(cp_wrap *wrap);
00278         
00279 /* free an allocation made by a cprops api function. On Windows you can't just
00280  * call free on memory allocated in a call to a DLL function.
00281  */
00282 #ifdef _WINDOWS
00283 CPROPS_DLL
00284 void *cp_malloc(size_t size);
00285 CPROPS_DLL
00286 void *cp_calloc(size_t count, size_t size);
00287 CPROPS_DLL 
00288 void *cp_realloc(void *p, size_t size);
00289 CPROPS_DLL
00290 void cp_free(void *p);
00291 #else
00292 #define cp_malloc malloc
00293 #define cp_calloc calloc
00294 #define cp_realloc realloc
00295 #define cp_free free
00296 #endif /* _WINDOWS */
00297 
00298 struct _cp_mempool;
00299 struct _cp_shared_mempool;
00300 
00301 __END_DECLS
00302 
00303 /** @} */
00304 
00305 #endif
00306 

Generated on Fri Oct 22 2010 11:02:22 for SST by  doxygen 1.7.1