00001 
00002 
00003 
00004 
00005 
00006 #ifndef _TOR_CONTAINER_H
00007 #define _TOR_CONTAINER_H
00008 
00009 #include "util.h"
00010 
00017 typedef struct smartlist_t {
00022   void **list;
00023   int num_used;
00024   int capacity;
00025 } smartlist_t;
00026 
00027 smartlist_t *smartlist_create(void);
00028 void smartlist_free(smartlist_t *sl);
00029 void smartlist_clear(smartlist_t *sl);
00030 void smartlist_add(smartlist_t *sl, void *element);
00031 void smartlist_add_all(smartlist_t *sl, const smartlist_t *s2);
00032 void smartlist_remove(smartlist_t *sl, const void *element);
00033 void *smartlist_pop_last(smartlist_t *sl);
00034 void smartlist_reverse(smartlist_t *sl);
00035 void smartlist_string_remove(smartlist_t *sl, const char *element);
00036 int smartlist_isin(const smartlist_t *sl, const void *element) ATTR_PURE;
00037 int smartlist_string_isin(const smartlist_t *sl, const char *element)
00038   ATTR_PURE;
00039 int smartlist_string_pos(const smartlist_t *, const char *elt) ATTR_PURE;
00040 int smartlist_string_isin_case(const smartlist_t *sl, const char *element)
00041   ATTR_PURE;
00042 int smartlist_string_num_isin(const smartlist_t *sl, int num) ATTR_PURE;
00043 int smartlist_digest_isin(const smartlist_t *sl, const char *element)
00044   ATTR_PURE;
00045 int smartlist_overlap(const smartlist_t *sl1, const smartlist_t *sl2)
00046   ATTR_PURE;
00047 void smartlist_intersect(smartlist_t *sl1, const smartlist_t *sl2);
00048 void smartlist_subtract(smartlist_t *sl1, const smartlist_t *sl2);
00049 
00050 
00051 #ifdef DEBUG_SMARTLIST
00052 
00054 static INLINE int smartlist_len(const smartlist_t *sl) ATTR_PURE;
00055 static INLINE int smartlist_len(const smartlist_t *sl) {
00056   tor_assert(sl);
00057   return (sl)->num_used;
00058 }
00061 static INLINE void *smartlist_get(const smartlist_t *sl, int idx) ATTR_PURE;
00062 static INLINE void *smartlist_get(const smartlist_t *sl, int idx) {
00063   tor_assert(sl);
00064   tor_assert(idx>=0);
00065   tor_assert(sl->num_used > idx);
00066   return sl->list[idx];
00067 }
00068 static INLINE void smartlist_set(smartlist_t *sl, int idx, void *val) {
00069   tor_assert(sl);
00070   tor_assert(idx>=0);
00071   tor_assert(sl->num_used > idx);
00072   sl->list[idx] = val;
00073 }
00074 #else
00075 #define smartlist_len(sl) ((sl)->num_used)
00076 #define smartlist_get(sl, idx) ((sl)->list[idx])
00077 #define smartlist_set(sl, idx, val) ((sl)->list[idx] = (val))
00078 #endif
00079 
00082 static INLINE void smartlist_swap(smartlist_t *sl, int idx1, int idx2)
00083 {
00084   if (idx1 != idx2) {
00085     void *elt = smartlist_get(sl, idx1);
00086     smartlist_set(sl, idx1, smartlist_get(sl, idx2));
00087     smartlist_set(sl, idx2, elt);
00088   }
00089 }
00090 
00091 void smartlist_del(smartlist_t *sl, int idx);
00092 void smartlist_del_keeporder(smartlist_t *sl, int idx);
00093 void smartlist_insert(smartlist_t *sl, int idx, void *val);
00094 void smartlist_sort(smartlist_t *sl,
00095                     int (*compare)(const void **a, const void **b));
00096 void *smartlist_get_most_frequent(const smartlist_t *sl,
00097                     int (*compare)(const void **a, const void **b));
00098 void smartlist_uniq(smartlist_t *sl,
00099                     int (*compare)(const void **a, const void **b),
00100                     void (*free_fn)(void *elt));
00101 
00102 void smartlist_sort_strings(smartlist_t *sl);
00103 void smartlist_sort_digests(smartlist_t *sl);
00104 void smartlist_sort_digests256(smartlist_t *sl);
00105 
00106 char *smartlist_get_most_frequent_string(smartlist_t *sl);
00107 char *smartlist_get_most_frequent_digest256(smartlist_t *sl);
00108 
00109 void smartlist_uniq_strings(smartlist_t *sl);
00110 void smartlist_uniq_digests(smartlist_t *sl);
00111 void smartlist_uniq_digests256(smartlist_t *sl);
00112 void *smartlist_bsearch(smartlist_t *sl, const void *key,
00113                         int (*compare)(const void *key, const void **member))
00114   ATTR_PURE;
00115 int smartlist_bsearch_idx(const smartlist_t *sl, const void *key,
00116                           int (*compare)(const void *key, const void **member),
00117                           int *found_out);
00118 
00119 void smartlist_pqueue_add(smartlist_t *sl,
00120                           int (*compare)(const void *a, const void *b),
00121                           int idx_field_offset,
00122                           void *item);
00123 void *smartlist_pqueue_pop(smartlist_t *sl,
00124                            int (*compare)(const void *a, const void *b),
00125                            int idx_field_offset);
00126 void smartlist_pqueue_remove(smartlist_t *sl,
00127                              int (*compare)(const void *a, const void *b),
00128                              int idx_field_offset,
00129                              void *item);
00130 void smartlist_pqueue_assert_ok(smartlist_t *sl,
00131                                 int (*compare)(const void *a, const void *b),
00132                                 int idx_field_offset);
00133 
00134 #define SPLIT_SKIP_SPACE   0x01
00135 #define SPLIT_IGNORE_BLANK 0x02
00136 #define SPLIT_STRIP_SPACE  0x04
00137 int smartlist_split_string(smartlist_t *sl, const char *str, const char *sep,
00138                            int flags, int max);
00139 char *smartlist_join_strings(smartlist_t *sl, const char *join, int terminate,
00140                              size_t *len_out) ATTR_MALLOC;
00141 char *smartlist_join_strings2(smartlist_t *sl, const char *join,
00142                               size_t join_len, int terminate, size_t *len_out)
00143   ATTR_MALLOC;
00144 
00177 
00178 
00179 
00180 
00181 
00182 
00183 
00184 
00185 
00186 
00187 
00188 
00189 
00190 
00191 
00192 
00193 
00194 
00195 
00196 
00197 
00198 
00199 
00200 
00201 
00202 
00203 
00204 
00205 
00206 
00207 
00208 
00209 
00210 
00211 #define SMARTLIST_FOREACH_BEGIN(sl, type, var)  \
00212   STMT_BEGIN                                                    \
00213     int var ## _sl_idx, var ## _sl_len=(sl)->num_used;          \
00214     type var;                                                   \
00215     for (var ## _sl_idx = 0; var ## _sl_idx < var ## _sl_len;   \
00216          ++var ## _sl_idx) {                                    \
00217       var = (sl)->list[var ## _sl_idx];
00218 
00219 #define SMARTLIST_FOREACH_END(var)              \
00220     var = NULL;                                 \
00221   } STMT_END
00222 
00223 #define SMARTLIST_FOREACH(sl, type, var, cmd)                   \
00224   SMARTLIST_FOREACH_BEGIN(sl,type,var) {                        \
00225     cmd;                                                        \
00226   } SMARTLIST_FOREACH_END(var)
00227 
00231 #define SMARTLIST_DEL_CURRENT(sl, var)          \
00232   STMT_BEGIN                                    \
00233     smartlist_del(sl, var ## _sl_idx);          \
00234     --var ## _sl_idx;                           \
00235     --var ## _sl_len;                           \
00236   STMT_END
00237 
00242 #define SMARTLIST_REPLACE_CURRENT(sl, var, val) \
00243   STMT_BEGIN                                    \
00244     smartlist_set(sl, var ## _sl_idx, val);     \
00245   STMT_END
00246 
00247 
00248 
00249 
00250 
00251 
00252 
00253 
00254 
00255 
00256 
00257 
00258 
00259 
00260 
00261 
00262 
00263 
00264 
00265 
00266 
00267 
00268 
00269 
00270 
00271 
00272 
00273 
00274 
00275 
00276 
00277 
00278 
00279 
00280 
00281 
00282 
00283 
00284 
00285 
00286 
00287 
00288 
00289 
00290 
00291 #define SMARTLIST_FOREACH_JOIN(sl1, type1, var1, sl2, type2, var2,      \
00292                                 cmpexpr, unmatched_var2)                \
00293   STMT_BEGIN                                                            \
00294   int var1 ## _sl_idx = 0, var1 ## _sl_len=(sl1)->num_used;             \
00295   int var2 ## _sl_idx = 0, var2 ## _sl_len=(sl2)->num_used;             \
00296   int var1 ## _ ## var2 ## _cmp;                                        \
00297   type1 var1;                                                           \
00298   type2 var2;                                                           \
00299   for (; var2##_sl_idx < var2##_sl_len; ++var2##_sl_idx) {              \
00300     var2 = (sl2)->list[var2##_sl_idx];                                  \
00301     while (var1##_sl_idx < var1##_sl_len) {                             \
00302       var1 = (sl1)->list[var1##_sl_idx];                                \
00303       var1##_##var2##_cmp = (cmpexpr);                                  \
00304       if (var1##_##var2##_cmp > 0) {                                    \
00305         break;                                                          \
00306       } else if (var1##_##var2##_cmp == 0) {                            \
00307         goto matched_##var2;                                            \
00308       } else {                                                          \
00309         ++var1##_sl_idx;                                                \
00310       }                                                                 \
00311     }                                                                   \
00312                               \
00313     unmatched_var2;                                                     \
00314     continue;                                                           \
00315     matched_##var2: ;                                                   \
00316 
00317 #define SMARTLIST_FOREACH_JOIN_END(var1, var2)  \
00318   }                                             \
00319   STMT_END
00320 
00321 #define DECLARE_MAP_FNS(maptype, keytype, prefix)                       \
00322   typedef struct maptype maptype;                                       \
00323   typedef struct prefix##entry_t *prefix##iter_t;                       \
00324   maptype* prefix##new(void);                                           \
00325   void* prefix##set(maptype *map, keytype key, void *val);              \
00326   void* prefix##get(const maptype *map, keytype key);                   \
00327   void* prefix##remove(maptype *map, keytype key);                      \
00328   void prefix##free(maptype *map, void (*free_val)(void*));             \
00329   int prefix##isempty(const maptype *map);                              \
00330   int prefix##size(const maptype *map);                                 \
00331   prefix##iter_t *prefix##iter_init(maptype *map);                      \
00332   prefix##iter_t *prefix##iter_next(maptype *map, prefix##iter_t *iter); \
00333   prefix##iter_t *prefix##iter_next_rmv(maptype *map, prefix##iter_t *iter); \
00334   void prefix##iter_get(prefix##iter_t *iter, keytype *keyp, void **valp); \
00335   int prefix##iter_done(prefix##iter_t *iter);                          \
00336   void prefix##assert_ok(const maptype *map)
00337 
00338 
00339 DECLARE_MAP_FNS(strmap_t, const char *, strmap_);
00340 
00341 DECLARE_MAP_FNS(digestmap_t, const char *, digestmap_);
00342 
00343 #undef DECLARE_MAP_FNS
00344 
00355 
00356 
00357 
00358 
00359 
00360 
00361 
00362 
00363 
00364 
00365 
00366 
00367 
00368 
00369 #define MAP_FOREACH(prefix, map, keytype, keyvar, valtype, valvar)      \
00370   STMT_BEGIN                                                            \
00371     prefix##iter_t *keyvar##_iter;                                      \
00372     for (keyvar##_iter = prefix##iter_init(map);                        \
00373          !prefix##iter_done(keyvar##_iter);                             \
00374          keyvar##_iter = prefix##iter_next(map, keyvar##_iter)) {       \
00375       keytype keyvar;                                                   \
00376       void *valvar##_voidp;                                             \
00377       valtype valvar;                                                   \
00378       prefix##iter_get(keyvar##_iter, &keyvar, &valvar##_voidp);        \
00379       valvar = valvar##_voidp;
00380 
00390 
00391 
00392 
00393 
00394 
00395 
00396 
00397 
00398 
00399 
00400 
00401 
00402 
00403 
00404 
00405 
00406 
00407 
00408 
00409 #define MAP_FOREACH_MODIFY(prefix, map, keytype, keyvar, valtype, valvar) \
00410   STMT_BEGIN                                                            \
00411     prefix##iter_t *keyvar##_iter;                                      \
00412     int keyvar##_del=0;                                                 \
00413     for (keyvar##_iter = prefix##iter_init(map);                        \
00414          !prefix##iter_done(keyvar##_iter);                             \
00415          keyvar##_iter = keyvar##_del ?                                 \
00416            prefix##iter_next_rmv(map, keyvar##_iter) :                  \
00417            prefix##iter_next(map, keyvar##_iter)) {                     \
00418       keytype keyvar;                                                   \
00419       void *valvar##_voidp;                                             \
00420       valtype valvar;                                                   \
00421       keyvar##_del=0;                                                   \
00422       prefix##iter_get(keyvar##_iter, &keyvar, &valvar##_voidp);        \
00423       valvar = valvar##_voidp;
00424 
00427 #define MAP_DEL_CURRENT(keyvar)                   \
00428   STMT_BEGIN                                      \
00429     keyvar##_del = 1;                             \
00430   STMT_END
00431 
00433 #define MAP_FOREACH_END } STMT_END ;
00434 
00441 #define DIGESTMAP_FOREACH(map, keyvar, valtype, valvar)                 \
00442   MAP_FOREACH(digestmap_, map, const char *, keyvar, valtype, valvar)
00443 
00452 #define DIGESTMAP_FOREACH_MODIFY(map, keyvar, valtype, valvar)          \
00453   MAP_FOREACH_MODIFY(digestmap_, map, const char *, keyvar, valtype, valvar)
00454 
00455 #define DIGESTMAP_FOREACH_END MAP_FOREACH_END
00456 
00457 #define STRMAP_FOREACH(map, keyvar, valtype, valvar)                 \
00458   MAP_FOREACH(strmap_, map, const char *, keyvar, valtype, valvar)
00459 #define STRMAP_FOREACH_MODIFY(map, keyvar, valtype, valvar)          \
00460   MAP_FOREACH_MODIFY(strmap_, map, const char *, keyvar, valtype, valvar)
00461 #define STRMAP_FOREACH_END MAP_FOREACH_END
00462 
00463 void* strmap_set_lc(strmap_t *map, const char *key, void *val);
00464 void* strmap_get_lc(const strmap_t *map, const char *key);
00465 void* strmap_remove_lc(strmap_t *map, const char *key);
00466 
00467 #define DECLARE_TYPED_DIGESTMAP_FNS(prefix, maptype, valtype)           \
00468   typedef struct maptype maptype;                                       \
00469   typedef struct prefix##iter_t prefix##iter_t;                         \
00470   static INLINE maptype* prefix##new(void)                              \
00471   {                                                                     \
00472     return (maptype*)digestmap_new();                                   \
00473   }                                                                     \
00474   static INLINE digestmap_t* prefix##to_digestmap(maptype *map)         \
00475   {                                                                     \
00476     return (digestmap_t*)map;                                           \
00477   }                                                                     \
00478   static INLINE valtype* prefix##get(maptype *map, const char *key)     \
00479   {                                                                     \
00480     return (valtype*)digestmap_get((digestmap_t*)map, key);             \
00481   }                                                                     \
00482   static INLINE valtype* prefix##set(maptype *map, const char *key,     \
00483                                      valtype *val)                      \
00484   {                                                                     \
00485     return (valtype*)digestmap_set((digestmap_t*)map, key, val);        \
00486   }                                                                     \
00487   static INLINE valtype* prefix##remove(maptype *map, const char *key)  \
00488   {                                                                     \
00489     return (valtype*)digestmap_remove((digestmap_t*)map, key);          \
00490   }                                                                     \
00491   static INLINE void prefix##free(maptype *map, void (*free_val)(void*)) \
00492   {                                                                     \
00493     digestmap_free((digestmap_t*)map, free_val);                        \
00494   }                                                                     \
00495   static INLINE int prefix##isempty(maptype *map)                       \
00496   {                                                                     \
00497     return digestmap_isempty((digestmap_t*)map);                        \
00498   }                                                                     \
00499   static INLINE int prefix##size(maptype *map)                          \
00500   {                                                                     \
00501     return digestmap_size((digestmap_t*)map);                           \
00502   }                                                                     \
00503   static INLINE prefix##iter_t *prefix##iter_init(maptype *map)         \
00504   {                                                                     \
00505     return (prefix##iter_t*) digestmap_iter_init((digestmap_t*)map);    \
00506   }                                                                     \
00507   static INLINE prefix##iter_t *prefix##iter_next(maptype *map,         \
00508                                                   prefix##iter_t *iter) \
00509   {                                                                     \
00510     return (prefix##iter_t*) digestmap_iter_next(                       \
00511                        (digestmap_t*)map, (digestmap_iter_t*)iter);     \
00512   }                                                                     \
00513   static INLINE prefix##iter_t *prefix##iter_next_rmv(maptype *map,     \
00514                                                   prefix##iter_t *iter) \
00515   {                                                                     \
00516     return (prefix##iter_t*) digestmap_iter_next_rmv(                   \
00517                        (digestmap_t*)map, (digestmap_iter_t*)iter);     \
00518   }                                                                     \
00519   static INLINE void prefix##iter_get(prefix##iter_t *iter,             \
00520                                       const char **keyp,                \
00521                                       valtype **valp)                   \
00522   {                                                                     \
00523     void *v;                                                            \
00524     digestmap_iter_get((digestmap_iter_t*) iter, keyp, &v);             \
00525     *valp = v;                                                          \
00526   }                                                                     \
00527   static INLINE int prefix##iter_done(prefix##iter_t *iter)             \
00528   {                                                                     \
00529     return digestmap_iter_done((digestmap_iter_t*)iter);                \
00530   }
00531 
00532 #if SIZEOF_INT == 4
00533 #define BITARRAY_SHIFT 5
00534 #elif SIZEOF_INT == 8
00535 #define BITARRAY_SHIFT 6
00536 #else
00537 #error "int is neither 4 nor 8 bytes. I can't deal with that."
00538 #endif
00539 #define BITARRAY_MASK ((1u<<BITARRAY_SHIFT)-1)
00540 
00542 typedef unsigned int bitarray_t;
00544 static INLINE bitarray_t *
00545 bitarray_init_zero(unsigned int n_bits)
00546 {
00547   
00548   size_t sz = (n_bits+BITARRAY_MASK) >> BITARRAY_SHIFT;
00549   return tor_malloc_zero(sz*sizeof(unsigned int));
00550 }
00554 static INLINE bitarray_t *
00555 bitarray_expand(bitarray_t *ba,
00556                 unsigned int n_bits_old, unsigned int n_bits_new)
00557 {
00558   size_t sz_old = (n_bits_old+BITARRAY_MASK) >> BITARRAY_SHIFT;
00559   size_t sz_new = (n_bits_new+BITARRAY_MASK) >> BITARRAY_SHIFT;
00560   char *ptr;
00561   if (sz_new <= sz_old)
00562     return ba;
00563   ptr = tor_realloc(ba, sz_new*sizeof(unsigned int));
00564   
00565 
00566   memset(ptr+sz_old*sizeof(unsigned int), 0,
00567          (sz_new-sz_old)*sizeof(unsigned int));
00568   return (bitarray_t*) ptr;
00569 }
00571 static INLINE void
00572 bitarray_free(bitarray_t *ba)
00573 {
00574   tor_free(ba);
00575 }
00577 static INLINE void
00578 bitarray_set(bitarray_t *b, int bit)
00579 {
00580   b[bit >> BITARRAY_SHIFT] |= (1u << (bit & BITARRAY_MASK));
00581 }
00583 static INLINE void
00584 bitarray_clear(bitarray_t *b, int bit)
00585 {
00586   b[bit >> BITARRAY_SHIFT] &= ~ (1u << (bit & BITARRAY_MASK));
00587 }
00590 static INLINE unsigned int
00591 bitarray_is_set(bitarray_t *b, int bit)
00592 {
00593   return b[bit >> BITARRAY_SHIFT] & (1u << (bit & BITARRAY_MASK));
00594 }
00595 
00597 typedef struct {
00598   int mask; 
00599 
00600   bitarray_t *ba; 
00601 } digestset_t;
00602 
00603 #define BIT(n) ((n) & set->mask)
00604 
00605 static INLINE void
00606 digestset_add(digestset_t *set, const char *digest)
00607 {
00608   const uint32_t *p = (const uint32_t *)digest;
00609   const uint32_t d1 = p[0] + (p[1]>>16);
00610   const uint32_t d2 = p[1] + (p[2]>>16);
00611   const uint32_t d3 = p[2] + (p[3]>>16);
00612   const uint32_t d4 = p[3] + (p[0]>>16);
00613   bitarray_set(set->ba, BIT(d1));
00614   bitarray_set(set->ba, BIT(d2));
00615   bitarray_set(set->ba, BIT(d3));
00616   bitarray_set(set->ba, BIT(d4));
00617 }
00618 
00621 static INLINE int
00622 digestset_isin(const digestset_t *set, const char *digest)
00623 {
00624   const uint32_t *p = (const uint32_t *)digest;
00625   const uint32_t d1 = p[0] + (p[1]>>16);
00626   const uint32_t d2 = p[1] + (p[2]>>16);
00627   const uint32_t d3 = p[2] + (p[3]>>16);
00628   const uint32_t d4 = p[3] + (p[0]>>16);
00629   return bitarray_is_set(set->ba, BIT(d1)) &&
00630          bitarray_is_set(set->ba, BIT(d2)) &&
00631          bitarray_is_set(set->ba, BIT(d3)) &&
00632          bitarray_is_set(set->ba, BIT(d4));
00633 }
00634 #undef BIT
00635 
00636 digestset_t *digestset_new(int max_elements);
00637 void digestset_free(digestset_t* set);
00638 
00639 
00640 
00641 
00642 
00643 int find_nth_int(int *array, int n_elements, int nth);
00644 time_t find_nth_time(time_t *array, int n_elements, int nth);
00645 double find_nth_double(double *array, int n_elements, int nth);
00646 int32_t find_nth_int32(int32_t *array, int n_elements, int nth);
00647 uint32_t find_nth_uint32(uint32_t *array, int n_elements, int nth);
00648 long find_nth_long(long *array, int n_elements, int nth);
00649 static INLINE int
00650 median_int(int *array, int n_elements)
00651 {
00652   return find_nth_int(array, n_elements, (n_elements-1)/2);
00653 }
00654 static INLINE time_t
00655 median_time(time_t *array, int n_elements)
00656 {
00657   return find_nth_time(array, n_elements, (n_elements-1)/2);
00658 }
00659 static INLINE double
00660 median_double(double *array, int n_elements)
00661 {
00662   return find_nth_double(array, n_elements, (n_elements-1)/2);
00663 }
00664 static INLINE uint32_t
00665 median_uint32(uint32_t *array, int n_elements)
00666 {
00667   return find_nth_uint32(array, n_elements, (n_elements-1)/2);
00668 }
00669 static INLINE int32_t
00670 median_int32(int32_t *array, int n_elements)
00671 {
00672   return find_nth_int32(array, n_elements, (n_elements-1)/2);
00673 }
00674 static INLINE long
00675 median_long(long *array, int n_elements)
00676 {
00677   return find_nth_long(array, n_elements, (n_elements-1)/2);
00678 }
00679 
00680 #endif
00681