gnunet_container_lib.h 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221
  1. /*
  2. This file is part of GNUnet.
  3. (C) 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009, 2010 Christian Grothoff (and other contributing authors)
  4. GNUnet is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published
  6. by the Free Software Foundation; either version 2, or (at your
  7. option) any later version.
  8. GNUnet is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GNUnet; see the file COPYING. If not, write to the
  14. Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  15. Boston, MA 02111-1307, USA.
  16. */
  17. /**
  18. * @file include/gnunet_container_lib.h
  19. * @brief container classes for GNUnet
  20. *
  21. * @author Christian Grothoff
  22. * @author Nils Durner
  23. */
  24. #ifndef GNUNET_CONTAINER_LIB_H
  25. #define GNUNET_CONTAINER_LIB_H
  26. /* add error and config prototypes */
  27. #include "gnunet_crypto_lib.h"
  28. #include <extractor.h>
  29. #ifndef EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME
  30. /* hack for LE < 0.6.3 */
  31. #define EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME 180
  32. #endif
  33. #ifdef __cplusplus
  34. extern "C"
  35. {
  36. #if 0 /* keep Emacsens' auto-indent happy */
  37. }
  38. #endif
  39. #endif
  40. /* ******************* bloomfilter ***************** */
  41. /**
  42. * @brief bloomfilter representation (opaque)
  43. */
  44. struct GNUNET_CONTAINER_BloomFilter;
  45. /**
  46. * Iterator over HashCodes.
  47. *
  48. * @param cls closure
  49. * @param next set to the next hash code
  50. * @return GNUNET_YES if next was updated
  51. * GNUNET_NO if there are no more entries
  52. */
  53. typedef int (*GNUNET_HashCodeIterator) (void *cls, GNUNET_HashCode * next);
  54. /**
  55. * Load a bloom-filter from a file.
  56. *
  57. * @param filename the name of the file (or the prefix)
  58. * @param size the size of the bloom-filter (number of
  59. * bytes of storage space to use)
  60. * @param k the number of GNUNET_CRYPTO_hash-functions to apply per
  61. * element (number of bits set per element in the set)
  62. * @return the bloomfilter
  63. */
  64. struct GNUNET_CONTAINER_BloomFilter *
  65. GNUNET_CONTAINER_bloomfilter_load (const char *filename, size_t size,
  66. unsigned int k);
  67. /**
  68. * Create a bloom filter from raw bits.
  69. *
  70. * @param data the raw bits in memory (maybe NULL,
  71. * in which case all bits should be considered
  72. * to be zero).
  73. * @param size the size of the bloom-filter (number of
  74. * bytes of storage space to use); also size of data
  75. * -- unless data is NULL. Must be a power of 2.
  76. * @param k the number of GNUNET_CRYPTO_hash-functions to apply per
  77. * element (number of bits set per element in the set)
  78. * @return the bloomfilter
  79. */
  80. struct GNUNET_CONTAINER_BloomFilter *
  81. GNUNET_CONTAINER_bloomfilter_init (const char *data, size_t size,
  82. unsigned int k);
  83. /**
  84. * Copy the raw data of this bloomfilter into
  85. * the given data array.
  86. *
  87. * @param data where to write the data
  88. * @param size the size of the given data array
  89. * @return GNUNET_SYSERR if the data array of the wrong size
  90. */
  91. int
  92. GNUNET_CONTAINER_bloomfilter_get_raw_data (const struct
  93. GNUNET_CONTAINER_BloomFilter *bf,
  94. char *data, size_t size);
  95. /**
  96. * Test if an element is in the filter.
  97. * @param e the element
  98. * @param bf the filter
  99. * @return GNUNET_YES if the element is in the filter, GNUNET_NO if not
  100. */
  101. int
  102. GNUNET_CONTAINER_bloomfilter_test (const struct GNUNET_CONTAINER_BloomFilter
  103. *bf, const GNUNET_HashCode * e);
  104. /**
  105. * Add an element to the filter
  106. * @param bf the filter
  107. * @param e the element
  108. */
  109. void
  110. GNUNET_CONTAINER_bloomfilter_add (struct GNUNET_CONTAINER_BloomFilter *bf,
  111. const GNUNET_HashCode * e);
  112. /**
  113. * Remove an element from the filter.
  114. * @param bf the filter
  115. * @param e the element to remove
  116. */
  117. void
  118. GNUNET_CONTAINER_bloomfilter_remove (struct GNUNET_CONTAINER_BloomFilter *bf,
  119. const GNUNET_HashCode * e);
  120. /**
  121. * Create a copy of a bloomfilter.
  122. *
  123. * @param bf the filter
  124. * @return copy of bf
  125. */
  126. struct GNUNET_CONTAINER_BloomFilter *
  127. GNUNET_CONTAINER_bloomfilter_copy (const struct GNUNET_CONTAINER_BloomFilter
  128. *bf);
  129. /**
  130. * Free the space associcated with a filter
  131. * in memory, flush to drive if needed (do not
  132. * free the space on the drive)
  133. * @param bf the filter
  134. */
  135. void
  136. GNUNET_CONTAINER_bloomfilter_free (struct GNUNET_CONTAINER_BloomFilter *bf);
  137. /**
  138. * Get size of the bloom filter.
  139. *
  140. * @param bf the filter
  141. * @return number of bytes used for the data of the bloom filter
  142. */
  143. size_t
  144. GNUNET_CONTAINER_bloomfilter_get_size (const struct GNUNET_CONTAINER_BloomFilter
  145. *bf);
  146. /**
  147. * Reset a bloom filter to empty.
  148. * @param bf the filter
  149. */
  150. void
  151. GNUNET_CONTAINER_bloomfilter_clear (struct GNUNET_CONTAINER_BloomFilter *bf);
  152. /**
  153. * Or the entries of the given raw data array with the
  154. * data of the given bloom filter. Assumes that
  155. * the size of the data array and the current filter
  156. * match.
  157. *
  158. * @param bf the filter
  159. * @param data data to OR-in
  160. * @param size size of data
  161. * @return GNUNET_OK on success
  162. */
  163. int
  164. GNUNET_CONTAINER_bloomfilter_or (struct GNUNET_CONTAINER_BloomFilter *bf,
  165. const char *data, size_t size);
  166. /**
  167. * Or the entries of the given raw data array with the
  168. * data of the given bloom filter. Assumes that
  169. * the size of the data array and the current filter
  170. * match.
  171. *
  172. * @param bf the filter
  173. * @param to_or the bloomfilter to or-in
  174. * @param size number of bytes in data
  175. */
  176. int
  177. GNUNET_CONTAINER_bloomfilter_or2 (struct GNUNET_CONTAINER_BloomFilter *bf,
  178. const struct GNUNET_CONTAINER_BloomFilter
  179. *to_or, size_t size);
  180. /**
  181. * Resize a bloom filter. Note that this operation
  182. * is pretty costly. Essentially, the bloom filter
  183. * needs to be completely re-build.
  184. *
  185. * @param bf the filter
  186. * @param iterator an iterator over all elements stored in the BF
  187. * @param iterator_cls closure for iterator
  188. * @param size the new size for the filter
  189. * @param k the new number of GNUNET_CRYPTO_hash-function to apply per element
  190. */
  191. void
  192. GNUNET_CONTAINER_bloomfilter_resize (struct GNUNET_CONTAINER_BloomFilter *bf,
  193. GNUNET_HashCodeIterator iterator,
  194. void *iterator_cls, size_t size,
  195. unsigned int k);
  196. /* ****************** metadata ******************* */
  197. /**
  198. * Meta data to associate with a file, directory or namespace.
  199. */
  200. struct GNUNET_CONTAINER_MetaData;
  201. /**
  202. * Create a fresh MetaData token.
  203. *
  204. * @return empty meta-data container
  205. */
  206. struct GNUNET_CONTAINER_MetaData *
  207. GNUNET_CONTAINER_meta_data_create (void);
  208. /**
  209. * Duplicate a MetaData token.
  210. *
  211. * @param md what to duplicate
  212. * @return duplicate meta-data container
  213. */
  214. struct GNUNET_CONTAINER_MetaData *
  215. GNUNET_CONTAINER_meta_data_duplicate (const struct GNUNET_CONTAINER_MetaData
  216. *md);
  217. /**
  218. * Free meta data.
  219. *
  220. * @param md what to free
  221. */
  222. void
  223. GNUNET_CONTAINER_meta_data_destroy (struct GNUNET_CONTAINER_MetaData *md);
  224. /**
  225. * Test if two MDs are equal. We consider them equal if
  226. * the meta types, formats and content match (we do not
  227. * include the mime types and plugins names in this
  228. * consideration).
  229. *
  230. * @param md1 first value to check
  231. * @param md2 other value to check
  232. * @return GNUNET_YES if they are equal
  233. */
  234. int
  235. GNUNET_CONTAINER_meta_data_test_equal (const struct GNUNET_CONTAINER_MetaData
  236. *md1,
  237. const struct GNUNET_CONTAINER_MetaData
  238. *md2);
  239. /**
  240. * Extend metadata.
  241. *
  242. * @param md metadata to extend
  243. * @param plugin_name name of the plugin that produced this value;
  244. * special values can be used (i.e. '&lt;zlib&gt;' for zlib being
  245. * used in the main libextractor library and yielding
  246. * meta data).
  247. * @param type libextractor-type describing the meta data
  248. * @param format basic format information about data
  249. * @param data_mime_type mime-type of data (not of the original file);
  250. * can be NULL (if mime-type is not known)
  251. * @param data actual meta-data found
  252. * @param data_len number of bytes in data
  253. * @return GNUNET_OK on success, GNUNET_SYSERR if this entry already exists
  254. * data_mime_type and plugin_name are not considered for "exists" checks
  255. */
  256. int
  257. GNUNET_CONTAINER_meta_data_insert (struct GNUNET_CONTAINER_MetaData *md,
  258. const char *plugin_name,
  259. enum EXTRACTOR_MetaType type,
  260. enum EXTRACTOR_MetaFormat format,
  261. const char *data_mime_type, const char *data,
  262. size_t data_len);
  263. /**
  264. * Extend metadata. Merges the meta data from the second argument
  265. * into the first, discarding duplicate key-value pairs.
  266. *
  267. * @param md metadata to extend
  268. * @param in metadata to merge
  269. */
  270. void
  271. GNUNET_CONTAINER_meta_data_merge (struct GNUNET_CONTAINER_MetaData *md,
  272. const struct GNUNET_CONTAINER_MetaData *in);
  273. /**
  274. * Remove an item.
  275. *
  276. * @param md metadata to manipulate
  277. * @param type type of the item to remove
  278. * @param data specific value to remove, NULL to remove all
  279. * entries of the given type
  280. * @param data_len number of bytes in data
  281. * @return GNUNET_OK on success, GNUNET_SYSERR if the item does not exist in md
  282. */
  283. int
  284. GNUNET_CONTAINER_meta_data_delete (struct GNUNET_CONTAINER_MetaData *md,
  285. enum EXTRACTOR_MetaType type,
  286. const char *data, size_t data_len);
  287. /**
  288. * Remove all items in the container.
  289. *
  290. * @param md metadata to manipulate
  291. */
  292. void
  293. GNUNET_CONTAINER_meta_data_clear (struct GNUNET_CONTAINER_MetaData *md);
  294. /**
  295. * Add the current time as the publication date
  296. * to the meta-data.
  297. *
  298. * @param md metadata to modify
  299. */
  300. void
  301. GNUNET_CONTAINER_meta_data_add_publication_date (struct
  302. GNUNET_CONTAINER_MetaData *md);
  303. /**
  304. * Iterate over MD entries.
  305. *
  306. * @param md metadata to inspect
  307. * @param iter function to call on each entry
  308. * @param iter_cls closure for iterator
  309. * @return number of entries
  310. */
  311. int
  312. GNUNET_CONTAINER_meta_data_iterate (const struct GNUNET_CONTAINER_MetaData *md,
  313. EXTRACTOR_MetaDataProcessor iter,
  314. void *iter_cls);
  315. /**
  316. * Get the first MD entry of the given type. Caller
  317. * is responsible for freeing the return value.
  318. * Also, only meta data items that are strings (0-terminated)
  319. * are returned by this function.
  320. *
  321. * @param md metadata to inspect
  322. * @param type type to look for
  323. * @return NULL if no entry was found
  324. */
  325. char *
  326. GNUNET_CONTAINER_meta_data_get_by_type (const struct GNUNET_CONTAINER_MetaData
  327. *md, enum EXTRACTOR_MetaType type);
  328. /**
  329. * Get the first matching MD entry of the given types. Caller is
  330. * responsible for freeing the return value. Also, only meta data
  331. * items that are strings (0-terminated) are returned by this
  332. * function.
  333. *
  334. * @param md metadata to inspect
  335. * @param ... -1-terminated list of types
  336. * @return NULL if we do not have any such entry,
  337. * otherwise client is responsible for freeing the value!
  338. */
  339. char *
  340. GNUNET_CONTAINER_meta_data_get_first_by_types (const struct
  341. GNUNET_CONTAINER_MetaData *md,
  342. ...);
  343. /**
  344. * Get a thumbnail from the meta-data (if present). Only matches meta
  345. * data with mime type "image" and binary format.
  346. *
  347. * @param md metadata to inspect
  348. * @param thumb will be set to the thumbnail data. Must be
  349. * freed by the caller!
  350. * @return number of bytes in thumbnail, 0 if not available
  351. */
  352. size_t
  353. GNUNET_CONTAINER_meta_data_get_thumbnail (const struct GNUNET_CONTAINER_MetaData
  354. *md, unsigned char **thumb);
  355. /**
  356. * Options for metadata serialization.
  357. */
  358. enum GNUNET_CONTAINER_MetaDataSerializationOptions
  359. {
  360. /**
  361. * Serialize all of the data.
  362. */
  363. GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL = 0,
  364. /**
  365. * If not enough space is available, it is acceptable
  366. * to only serialize some of the metadata.
  367. */
  368. GNUNET_CONTAINER_META_DATA_SERIALIZE_PART = 1,
  369. /**
  370. * Speed is of the essence, do not allow compression.
  371. */
  372. GNUNET_CONTAINER_META_DATA_SERIALIZE_NO_COMPRESS = 2
  373. };
  374. /**
  375. * Serialize meta-data to target.
  376. *
  377. * @param md metadata to serialize
  378. * @param target where to write the serialized metadata;
  379. * *target can be NULL, in which case memory is allocated
  380. * @param max maximum number of bytes available
  381. * @param opt is it ok to just write SOME of the
  382. * meta-data to match the size constraint,
  383. * possibly discarding some data?
  384. * @return number of bytes written on success,
  385. * -1 on error (typically: not enough
  386. * space)
  387. */
  388. ssize_t
  389. GNUNET_CONTAINER_meta_data_serialize (const struct GNUNET_CONTAINER_MetaData
  390. *md, char **target, size_t max,
  391. enum
  392. GNUNET_CONTAINER_MetaDataSerializationOptions
  393. opt);
  394. /**
  395. * Get the size of the full meta-data in serialized form.
  396. *
  397. * @param md metadata to inspect
  398. * @return number of bytes needed for serialization, -1 on error
  399. */
  400. ssize_t
  401. GNUNET_CONTAINER_meta_data_get_serialized_size (const struct
  402. GNUNET_CONTAINER_MetaData *md);
  403. /**
  404. * Deserialize meta-data. Initializes md.
  405. *
  406. * @param input serialized meta-data.
  407. * @param size number of bytes available
  408. * @return MD on success, NULL on error (i.e.
  409. * bad format)
  410. */
  411. struct GNUNET_CONTAINER_MetaData *
  412. GNUNET_CONTAINER_meta_data_deserialize (const char *input, size_t size);
  413. /* ******************************* HashMap **************************** */
  414. /**
  415. * Opaque handle for a HashMap.
  416. */
  417. struct GNUNET_CONTAINER_MultiHashMap;
  418. /**
  419. * Options for storing values in the HashMap.
  420. */
  421. enum GNUNET_CONTAINER_MultiHashMapOption
  422. {
  423. /**
  424. * If a value with the given key exists, replace it. Note that the
  425. * old value would NOT be freed by replace (the application has to
  426. * make sure that this happens if required).
  427. */
  428. GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE,
  429. /**
  430. * Allow multiple values with the same key.
  431. */
  432. GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE,
  433. /**
  434. * There must only be one value per key; storing a value should fail
  435. * if a value under the same key already exists.
  436. */
  437. GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY,
  438. /**
  439. * There must only be one value per key, but don't bother checking
  440. * if a value already exists (faster than UNIQUE_ONLY; implemented
  441. * just like MULTIPLE but this option documents better what is
  442. * intended if UNIQUE is what is desired).
  443. */
  444. GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST
  445. };
  446. /**
  447. * Iterator over hash map entries.
  448. *
  449. * @param cls closure
  450. * @param key current key code
  451. * @param value value in the hash map
  452. * @return GNUNET_YES if we should continue to
  453. * iterate,
  454. * GNUNET_NO if not.
  455. */
  456. typedef int (*GNUNET_CONTAINER_HashMapIterator) (void *cls,
  457. const GNUNET_HashCode * key,
  458. void *value);
  459. /**
  460. * Create a multi hash map.
  461. *
  462. * @param len initial size (map will grow as needed)
  463. * @return NULL on error
  464. */
  465. struct GNUNET_CONTAINER_MultiHashMap *
  466. GNUNET_CONTAINER_multihashmap_create (unsigned int len);
  467. /**
  468. * Destroy a hash map. Will not free any values
  469. * stored in the hash map!
  470. *
  471. * @param map the map
  472. */
  473. void
  474. GNUNET_CONTAINER_multihashmap_destroy (struct GNUNET_CONTAINER_MultiHashMap
  475. *map);
  476. /**
  477. * Given a key find a value in the map matching the key.
  478. *
  479. * @param map the map
  480. * @param key what to look for
  481. * @return NULL if no value was found; note that
  482. * this is indistinguishable from values that just
  483. * happen to be NULL; use "contains" to test for
  484. * key-value pairs with value NULL
  485. */
  486. void *
  487. GNUNET_CONTAINER_multihashmap_get (const struct GNUNET_CONTAINER_MultiHashMap
  488. *map, const GNUNET_HashCode * key);
  489. /**
  490. * Remove the given key-value pair from the map. Note that if the
  491. * key-value pair is in the map multiple times, only one of the pairs
  492. * will be removed.
  493. *
  494. * @param map the map
  495. * @param key key of the key-value pair
  496. * @param value value of the key-value pair
  497. * @return GNUNET_YES on success, GNUNET_NO if the key-value pair
  498. * is not in the map
  499. */
  500. int
  501. GNUNET_CONTAINER_multihashmap_remove (struct GNUNET_CONTAINER_MultiHashMap *map,
  502. const GNUNET_HashCode * key, void *value);
  503. /**
  504. * Remove all entries for the given key from the map.
  505. * Note that the values would not be "freed".
  506. *
  507. * @param map the map
  508. * @param key identifies values to be removed
  509. * @return number of values removed
  510. */
  511. int
  512. GNUNET_CONTAINER_multihashmap_remove_all (struct GNUNET_CONTAINER_MultiHashMap
  513. *map, const GNUNET_HashCode * key);
  514. /**
  515. * Check if the map contains any value under the given
  516. * key (including values that are NULL).
  517. *
  518. * @param map the map
  519. * @param key the key to test if a value exists for it
  520. * @return GNUNET_YES if such a value exists,
  521. * GNUNET_NO if not
  522. */
  523. int
  524. GNUNET_CONTAINER_multihashmap_contains (const struct
  525. GNUNET_CONTAINER_MultiHashMap *map,
  526. const GNUNET_HashCode * key);
  527. /**
  528. * Check if the map contains the given value under the given
  529. * key.
  530. *
  531. * @param map the map
  532. * @param key the key to test if a value exists for it
  533. * @param value value to test for
  534. * @return GNUNET_YES if such a value exists,
  535. * GNUNET_NO if not
  536. */
  537. int
  538. GNUNET_CONTAINER_multihashmap_contains_value (const struct
  539. GNUNET_CONTAINER_MultiHashMap
  540. *map, const GNUNET_HashCode * key,
  541. const void *value);
  542. /**
  543. * Store a key-value pair in the map.
  544. *
  545. * @param map the map
  546. * @param key key to use
  547. * @param value value to use
  548. * @param opt options for put
  549. * @return GNUNET_OK on success,
  550. * GNUNET_NO if a value was replaced (with REPLACE)
  551. * GNUNET_SYSERR if UNIQUE_ONLY was the option and the
  552. * value already exists
  553. */
  554. int
  555. GNUNET_CONTAINER_multihashmap_put (struct GNUNET_CONTAINER_MultiHashMap *map,
  556. const GNUNET_HashCode * key, void *value,
  557. enum GNUNET_CONTAINER_MultiHashMapOption
  558. opt);
  559. /**
  560. * Get the number of key-value pairs in the map.
  561. *
  562. * @param map the map
  563. * @return the number of key value pairs
  564. */
  565. unsigned int
  566. GNUNET_CONTAINER_multihashmap_size (const struct GNUNET_CONTAINER_MultiHashMap
  567. *map);
  568. /**
  569. * Iterate over all entries in the map.
  570. *
  571. * @param map the map
  572. * @param it function to call on each entry
  573. * @param it_cls extra argument to it
  574. * @return the number of key value pairs processed,
  575. * GNUNET_SYSERR if it aborted iteration
  576. */
  577. int
  578. GNUNET_CONTAINER_multihashmap_iterate (const struct
  579. GNUNET_CONTAINER_MultiHashMap *map,
  580. GNUNET_CONTAINER_HashMapIterator it,
  581. void *it_cls);
  582. /**
  583. * Iterate over all entries in the map that match a particular key.
  584. *
  585. * @param map the map
  586. * @param key key that the entries must correspond to
  587. * @param it function to call on each entry
  588. * @param it_cls extra argument to it
  589. * @return the number of key value pairs processed,
  590. * GNUNET_SYSERR if it aborted iteration
  591. */
  592. int
  593. GNUNET_CONTAINER_multihashmap_get_multiple (const struct
  594. GNUNET_CONTAINER_MultiHashMap *map,
  595. const GNUNET_HashCode * key,
  596. GNUNET_CONTAINER_HashMapIterator it,
  597. void *it_cls);
  598. /* ******************** doubly-linked list *************** */
  599. /* To avoid mistakes: head->prev == tail->next == NULL */
  600. /**
  601. * Insert an element at the head of a DLL. Assumes that head, tail and
  602. * element are structs with prev and next fields.
  603. *
  604. * @param head pointer to the head of the DLL
  605. * @param tail pointer to the tail of the DLL
  606. * @param element element to insert
  607. */
  608. #define GNUNET_CONTAINER_DLL_insert(head,tail,element) do { \
  609. GNUNET_assert ( ( (element)->prev == NULL) && ((head) != (element))); \
  610. GNUNET_assert ( ( (element)->next == NULL) && ((tail) != (element))); \
  611. (element)->next = (head); \
  612. (element)->prev = NULL; \
  613. if ((tail) == NULL) \
  614. (tail) = element; \
  615. else \
  616. (head)->prev = element; \
  617. (head) = (element); } while (0)
  618. /**
  619. * Insert an element at the tail of a DLL. Assumes that head, tail and
  620. * element are structs with prev and next fields.
  621. *
  622. * @param head pointer to the head of the DLL
  623. * @param tail pointer to the tail of the DLL
  624. * @param element element to insert
  625. */
  626. #define GNUNET_CONTAINER_DLL_insert_tail(head,tail,element) do { \
  627. GNUNET_assert ( ( (element)->prev == NULL) && ((head) != (element))); \
  628. GNUNET_assert ( ( (element)->next == NULL) && ((tail) != (element))); \
  629. (element)->prev = (tail); \
  630. (element)->next = NULL; \
  631. if ((head) == NULL) \
  632. (head) = element; \
  633. else \
  634. (tail)->next = element; \
  635. (tail) = (element); } while (0)
  636. /**
  637. * Insert an element into a DLL after the given other element. Insert
  638. * at the head if the other element is NULL.
  639. *
  640. * @param head pointer to the head of the DLL
  641. * @param tail pointer to the tail of the DLL
  642. * @param other prior element, NULL for insertion at head of DLL
  643. * @param element element to insert
  644. */
  645. #define GNUNET_CONTAINER_DLL_insert_after(head,tail,other,element) do { \
  646. GNUNET_assert ( ( (element)->prev == NULL) && ((head) != (element))); \
  647. GNUNET_assert ( ( (element)->next == NULL) && ((tail) != (element))); \
  648. (element)->prev = (other); \
  649. if (NULL == other) \
  650. { \
  651. (element)->next = (head); \
  652. (head) = (element); \
  653. } \
  654. else \
  655. { \
  656. (element)->next = (other)->next; \
  657. (other)->next = (element); \
  658. } \
  659. if (NULL == (element)->next) \
  660. (tail) = (element); \
  661. else \
  662. (element)->next->prev = (element); } while (0)
  663. /**
  664. * Insert an element into a DLL before the given other element. Insert
  665. * at the tail if the other element is NULL.
  666. *
  667. * @param head pointer to the head of the DLL
  668. * @param tail pointer to the tail of the DLL
  669. * @param other prior element, NULL for insertion at head of DLL
  670. * @param element element to insert
  671. */
  672. #define GNUNET_CONTAINER_DLL_insert_before(head,tail,other,element) do { \
  673. GNUNET_assert ( ( (element)->prev == NULL) && ((head) != (element))); \
  674. GNUNET_assert ( ( (element)->next == NULL) && ((tail) != (element))); \
  675. (element)->next = (other); \
  676. if (NULL == other) \
  677. { \
  678. (element)->prev = (tail); \
  679. (tail) = (element); \
  680. } \
  681. else \
  682. { \
  683. (element)->prev = (other)->prev; \
  684. (other)->prev = (element); \
  685. } \
  686. if (NULL == (element)->prev) \
  687. (head) = (element); \
  688. else \
  689. (element)->prev->next = (element); } while (0)
  690. /**
  691. * Remove an element from a DLL. Assumes
  692. * that head, tail and element are structs
  693. * with prev and next fields.
  694. *
  695. * @param head pointer to the head of the DLL
  696. * @param tail pointer to the tail of the DLL
  697. * @param element element to remove
  698. */
  699. #define GNUNET_CONTAINER_DLL_remove(head,tail,element) do { \
  700. GNUNET_assert ( ( (element)->prev != NULL) || ((head) == (element))); \
  701. GNUNET_assert ( ( (element)->next != NULL) || ((tail) == (element))); \
  702. if ((element)->prev == NULL) \
  703. (head) = (element)->next; \
  704. else \
  705. (element)->prev->next = (element)->next; \
  706. if ((element)->next == NULL) \
  707. (tail) = (element)->prev; \
  708. else \
  709. (element)->next->prev = (element)->prev; \
  710. (element)->next = NULL; \
  711. (element)->prev = NULL; } while (0)
  712. /* ******************** Heap *************** */
  713. /**
  714. * Cost by which elements in a heap can be ordered.
  715. */
  716. typedef uint64_t GNUNET_CONTAINER_HeapCostType;
  717. /*
  718. * Heap type, either max or min. Hopefully makes the
  719. * implementation more useful.
  720. */
  721. enum GNUNET_CONTAINER_HeapOrder
  722. {
  723. /**
  724. * Heap with the maximum cost at the root.
  725. */
  726. GNUNET_CONTAINER_HEAP_ORDER_MAX,
  727. /**
  728. * Heap with the minimum cost at the root.
  729. */
  730. GNUNET_CONTAINER_HEAP_ORDER_MIN
  731. };
  732. /**
  733. * Handle to a Heap.
  734. */
  735. struct GNUNET_CONTAINER_Heap;
  736. /**
  737. * Handle to a node in a heap.
  738. */
  739. struct GNUNET_CONTAINER_HeapNode;
  740. /**
  741. * Create a new heap.
  742. *
  743. * @param order how should the heap be sorted?
  744. * @return handle to the heap
  745. */
  746. struct GNUNET_CONTAINER_Heap *
  747. GNUNET_CONTAINER_heap_create (enum GNUNET_CONTAINER_HeapOrder order);
  748. /**
  749. * Destroys the heap. Only call on a heap that
  750. * is already empty.
  751. *
  752. * @param heap heap to destroy
  753. */
  754. void
  755. GNUNET_CONTAINER_heap_destroy (struct GNUNET_CONTAINER_Heap *heap);
  756. /**
  757. * Get element stored at root of heap.
  758. *
  759. * @param heap heap to inspect
  760. * @return NULL if heap is empty
  761. */
  762. void *
  763. GNUNET_CONTAINER_heap_peek (const struct GNUNET_CONTAINER_Heap *heap);
  764. /**
  765. * Get the current size of the heap
  766. *
  767. * @param heap the heap to get the size of
  768. * @return number of elements stored
  769. */
  770. unsigned int
  771. GNUNET_CONTAINER_heap_get_size (const struct GNUNET_CONTAINER_Heap *heap);
  772. /**
  773. * Get the current cost of the node
  774. *
  775. * @param node the node to get the cost of
  776. * @return cost of the node
  777. */
  778. GNUNET_CONTAINER_HeapCostType
  779. GNUNET_CONTAINER_heap_node_get_cost (const struct GNUNET_CONTAINER_HeapNode
  780. *node);
  781. /**
  782. * Iterator for heap
  783. *
  784. * @param cls closure
  785. * @param node internal node of the heap
  786. * @param element value stored at the node
  787. * @param cost cost associated with the node
  788. * @return GNUNET_YES if we should continue to iterate,
  789. * GNUNET_NO if not.
  790. */
  791. typedef int (*GNUNET_CONTAINER_HeapIterator) (void *cls,
  792. struct GNUNET_CONTAINER_HeapNode *
  793. node, void *element,
  794. GNUNET_CONTAINER_HeapCostType
  795. cost);
  796. /**
  797. * Iterate over all entries in the heap.
  798. *
  799. * @param heap the heap
  800. * @param iterator function to call on each entry
  801. * @param iterator_cls closure for iterator
  802. */
  803. void
  804. GNUNET_CONTAINER_heap_iterate (const struct GNUNET_CONTAINER_Heap *heap,
  805. GNUNET_CONTAINER_HeapIterator iterator,
  806. void *iterator_cls);
  807. /**
  808. * Return a *uniform* random element from the heap. Choose a random
  809. * number between 0 and heap size and then walk directly to it.
  810. * This cost can be between 0 and n, amortized cost of logN.
  811. *
  812. * @param heap heap to choose random element from
  813. * @param max how many nodes from the heap to choose from
  814. *
  815. * @return data stored at the chosen random node,
  816. * NULL if the heap is empty.
  817. *
  818. */
  819. void *
  820. GNUNET_CONTAINER_heap_get_random (struct GNUNET_CONTAINER_Heap *heap,
  821. uint32_t max);
  822. /**
  823. * Perform a random walk of the tree. The walk is biased
  824. * towards elements closer to the root of the tree (since
  825. * each walk starts at the root and ends at a random leaf).
  826. * The heap internally tracks the current position of the
  827. * walk.
  828. *
  829. * @param heap heap to walk
  830. * @return data stored at the next random node in the walk;
  831. * NULL if the tree is empty.
  832. */
  833. void *
  834. GNUNET_CONTAINER_heap_walk_get_next (struct GNUNET_CONTAINER_Heap *heap);
  835. /**
  836. * Inserts a new element into the heap.
  837. *
  838. * @param heap heap to modify
  839. * @param element element to insert
  840. * @param cost cost for the element
  841. * @return node for the new element
  842. */
  843. struct GNUNET_CONTAINER_HeapNode *
  844. GNUNET_CONTAINER_heap_insert (struct GNUNET_CONTAINER_Heap *heap, void *element,
  845. GNUNET_CONTAINER_HeapCostType cost);
  846. /**
  847. * Remove root of the heap.
  848. *
  849. * @param heap heap to modify
  850. * @return element data stored at the root node
  851. */
  852. void *
  853. GNUNET_CONTAINER_heap_remove_root (struct GNUNET_CONTAINER_Heap *heap);
  854. /**
  855. * Removes a node from the heap.
  856. *
  857. * @param node node to remove
  858. * @return element data stored at the node, NULL if heap is empty
  859. */
  860. void *
  861. GNUNET_CONTAINER_heap_remove_node (struct GNUNET_CONTAINER_HeapNode *node);
  862. /**
  863. * Updates the cost of any node in the tree
  864. *
  865. * @param heap heap to modify
  866. * @param node node for which the cost is to be changed
  867. * @param new_cost new cost for the node
  868. */
  869. void
  870. GNUNET_CONTAINER_heap_update_cost (struct GNUNET_CONTAINER_Heap *heap,
  871. struct GNUNET_CONTAINER_HeapNode *node,
  872. GNUNET_CONTAINER_HeapCostType new_cost);
  873. /* ******************** Singly linked list *************** */
  874. /**
  875. * Possible ways for how data stored in the linked list
  876. * might be allocated.
  877. */
  878. enum GNUNET_CONTAINER_SListDisposition
  879. {
  880. /**
  881. * Single-linked list must copy the buffer.
  882. */
  883. GNUNET_CONTAINER_SLIST_DISPOSITION_TRANSIENT = 0,
  884. /**
  885. * Data is static, no need to copy or free.
  886. */
  887. GNUNET_CONTAINER_SLIST_DISPOSITION_STATIC = 2,
  888. /**
  889. * Data is dynamic, do not copy but free when done.
  890. */
  891. GNUNET_CONTAINER_SLIST_DISPOSITION_DYNAMIC = 4
  892. };
  893. /**
  894. * Handle to a singly linked list
  895. */
  896. struct GNUNET_CONTAINER_SList;
  897. /**
  898. * Handle to a singly linked list iterator
  899. */
  900. struct GNUNET_CONTAINER_SList_Iterator;
  901. /**
  902. * Add a new element to the list
  903. * @param l list
  904. * @param disp memory disposition
  905. * @param buf payload buffer
  906. * @param len length of the buffer
  907. */
  908. void
  909. GNUNET_CONTAINER_slist_add (struct GNUNET_CONTAINER_SList *l,
  910. enum GNUNET_CONTAINER_SListDisposition disp,
  911. const void *buf, size_t len);
  912. /**
  913. * Add a new element to the end of the list
  914. * @param l list
  915. * @param disp memory disposition
  916. * @param buf payload buffer
  917. * @param len length of the buffer
  918. */
  919. void
  920. GNUNET_CONTAINER_slist_add_end (struct GNUNET_CONTAINER_SList *l,
  921. enum GNUNET_CONTAINER_SListDisposition disp,
  922. const void *buf, size_t len);
  923. /**
  924. * Append a singly linked list to another
  925. * @param dst list to append to
  926. * @param src source
  927. */
  928. void
  929. GNUNET_CONTAINER_slist_append (struct GNUNET_CONTAINER_SList *dst,
  930. struct GNUNET_CONTAINER_SList *src);
  931. /**
  932. * Create a new singly linked list
  933. * @return the new list
  934. */
  935. struct GNUNET_CONTAINER_SList *
  936. GNUNET_CONTAINER_slist_create (void);
  937. /**
  938. * Destroy a singly linked list
  939. * @param l the list to be destroyed
  940. */
  941. void
  942. GNUNET_CONTAINER_slist_destroy (struct GNUNET_CONTAINER_SList *l);
  943. /**
  944. * Return the beginning of a list
  945. *
  946. * @param l list
  947. * @return iterator pointing to the beginning, free using "GNUNET_free"
  948. */
  949. struct GNUNET_CONTAINER_SList_Iterator *
  950. GNUNET_CONTAINER_slist_begin (struct GNUNET_CONTAINER_SList *l);
  951. /**
  952. * Clear a list
  953. *
  954. * @param l list
  955. */
  956. void
  957. GNUNET_CONTAINER_slist_clear (struct GNUNET_CONTAINER_SList *l);
  958. /**
  959. * Check if a list contains a certain element
  960. * @param l list
  961. * @param buf payload buffer to find
  962. * @param len length of the payload (number of bytes in buf)
  963. */
  964. int
  965. GNUNET_CONTAINER_slist_contains (const struct GNUNET_CONTAINER_SList *l,
  966. const void *buf, size_t len);
  967. /**
  968. * Count the elements of a list
  969. * @param l list
  970. * @return number of elements in the list
  971. */
  972. int
  973. GNUNET_CONTAINER_slist_count (const struct GNUNET_CONTAINER_SList *l);
  974. /**
  975. * Remove an element from the list
  976. * @param i iterator that points to the element to be removed
  977. */
  978. void
  979. GNUNET_CONTAINER_slist_erase (struct GNUNET_CONTAINER_SList_Iterator *i);
  980. /**
  981. * Insert an element into a list at a specific position
  982. * @param before where to insert the new element
  983. * @param disp memory disposition
  984. * @param buf payload buffer
  985. * @param len length of the payload
  986. */
  987. void
  988. GNUNET_CONTAINER_slist_insert (struct GNUNET_CONTAINER_SList_Iterator *before,
  989. enum GNUNET_CONTAINER_SListDisposition disp,
  990. const void *buf, size_t len);
  991. /**
  992. * Advance an iterator to the next element
  993. * @param i iterator
  994. * @return GNUNET_YES on success, GNUNET_NO if the end has been reached
  995. */
  996. int
  997. GNUNET_CONTAINER_slist_next (struct GNUNET_CONTAINER_SList_Iterator *i);
  998. /**
  999. * Check if an iterator points beyond the end of a list
  1000. * @param i iterator
  1001. * @return GNUNET_YES if the end has been reached, GNUNET_NO if the iterator
  1002. * points to a valid element
  1003. */
  1004. int
  1005. GNUNET_CONTAINER_slist_end (struct GNUNET_CONTAINER_SList_Iterator *i);
  1006. /**
  1007. * Retrieve the element at a specific position in a list
  1008. *
  1009. * @param i iterator
  1010. * @param len set to the payload length
  1011. * @return payload
  1012. */
  1013. void *
  1014. GNUNET_CONTAINER_slist_get (const struct GNUNET_CONTAINER_SList_Iterator *i,
  1015. size_t * len);
  1016. /**
  1017. * Release an iterator
  1018. * @param i iterator
  1019. */
  1020. void
  1021. GNUNET_CONTAINER_slist_iter_destroy (struct GNUNET_CONTAINER_SList_Iterator *i);
  1022. #if 0 /* keep Emacsens' auto-indent happy */
  1023. {
  1024. #endif
  1025. #ifdef __cplusplus
  1026. }
  1027. #endif
  1028. /* ifndef GNUNET_CONTAINER_LIB_H */
  1029. #endif
  1030. /* end of gnunet_container_lib.h */