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 CP_HAS_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 
00040 #define COLLECTION_MODE_PLAIN             0
00041 
00042 #define COLLECTION_MODE_DEEP              1
00043 
00044 #define COLLECTION_MODE_MULTIPLE_VALUES   2
00045 
00046 #define COLLECTION_MODE_COPY              4
00047 
00049 #define COLLECTION_MODE_NOSYNC            8
00050 
00057 #define COLLECTION_MODE_NORESIZE         16
00058 
00062 #define COLLECTION_MODE_LIST_ORDER       32
00063 
00066 #define COLLECTION_MODE_IN_TRANSACTION   64
00067 
00069 #define COLLECTION_LOCK_NONE   0
00070 
00071 #define COLLECTION_LOCK_READ   1
00072 
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 
00092 typedef void *(*cp_copy_fn)(void *);
00093 
00097 typedef void (*cp_destructor_fn)(void *);
00098 
00103 typedef int (*cp_compare_fn)(void *, void *);
00104 
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 
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 
00162 #ifdef CP_HAS_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 #ifdef CP_HAS___BUILTIN_CLZ
00302 #define CP_CLZ_CHAR(x) (__builtin_clz(x) - 24)
00303 #define CP_CLZ_LONG_LONG(x) __builtin_clzll(x)
00304 #else
00305 #error NOT HAS CLZ
00306 #ifdef _MSC_VER
00307 #include <intrin.h>
00308 unsigned int __inline msc_clz( unsigned int x );
00309 #define CP_CLZ_CHAR(x) (msc_clz(x) - 24)
00310 unsigned int __inline msc_clz64( unsigned long long x );
00311 #define CP_CLZ_LONG_LONG(x) msc_clz64(x)
00312 #else
00313 static int cp_clz_char_slow(unsigned int x)
00314 {
00315     int bit, lz;
00316     for (lz = 0, bit = 0x80; bit > 0 && ((bit & x) == 0); lz++, bit >>= 1);
00317     return lz;
00318 }
00319 #define CP_CLZ_CHAR(x) cp_clz_char_slow(x)
00320 static int cp_clz_long_long_slow(unsigned long long x)
00321 {
00322     int count;
00323     for (count = 0; x != 0; x >>= 1, count++);
00324     return sizeof(long long) * 8 - count;
00325 }
00326 #define CP_CLZ_LONG_LONG(x) cp_clz_long_long_slow(x)
00327 #endif /* _MSC_VER */
00328 #endif /* CP_HAS___BUILTIN_CLZ */
00329 
00330 __END_DECLS
00331 
00334 #endif
00335 

Generated on Mon Dec 5 23:00:21 2011 for cprops by  doxygen 1.4.7