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