GNUnet  0.10.x
container_bloomfilter.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2001, 2002, 2003, 2004, 2006, 2008, 2011, 2012, 2018 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19  */
42 #include "platform.h"
43 #include "gnunet_util_lib.h"
44 
45 #define LOG(kind, ...) \
46  GNUNET_log_from(kind, "util-container-bloomfilter", __VA_ARGS__)
47 
48 #define LOG_STRERROR(kind, syscall) \
49  GNUNET_log_from_strerror(kind, "util-container-bloomfilter", syscall)
50 
51 #define LOG_STRERROR_FILE(kind, syscall, filename) \
52  GNUNET_log_from_strerror_file(kind, \
53  "util-container-bloomfilter", \
54  syscall, \
55  filename)
56 
61  char *bitArray;
62 
66  char *filename;
67 
72 
76  unsigned int addressesPerElement;
77 
81  size_t bitArraySize;
82 };
83 
84 
91 size_t
93  const struct GNUNET_CONTAINER_BloomFilter *bf)
94 {
95  if (bf == NULL)
96  return 0;
97  return bf->addressesPerElement;
98 }
99 
100 
107 size_t
109  const struct GNUNET_CONTAINER_BloomFilter *bf)
110 {
111  if (bf == NULL)
112  return 0;
113  return bf->bitArraySize;
114 }
115 
116 
125  const struct GNUNET_CONTAINER_BloomFilter *bf)
126 {
128  bf->bitArraySize,
129  bf->addressesPerElement);
130 }
131 
132 
140 static void
141 setBit(char *bitArray, unsigned int bitIdx)
142 {
143  size_t arraySlot;
144  unsigned int targetBit;
145 
146  arraySlot = bitIdx / 8;
147  targetBit = (1L << (bitIdx % 8));
148  bitArray[arraySlot] |= targetBit;
149 }
150 
158 static void
159 clearBit(char *bitArray, unsigned int bitIdx)
160 {
161  size_t slot;
162  unsigned int targetBit;
163 
164  slot = bitIdx / 8;
165  targetBit = (1L << (bitIdx % 8));
166  bitArray[slot] = bitArray[slot] & (~targetBit);
167 }
168 
176 static int
177 testBit(char *bitArray, unsigned int bitIdx)
178 {
179  size_t slot;
180  unsigned int targetBit;
181 
182  slot = bitIdx / 8;
183  targetBit = (1L << (bitIdx % 8));
184  if (bitArray[slot] & targetBit)
185  return GNUNET_YES;
186  else
187  return GNUNET_NO;
188 }
189 
199 static void
201  unsigned int bitIdx,
202  const struct GNUNET_DISK_FileHandle *fh)
203 {
204  off_t fileSlot;
205  unsigned char value;
206  unsigned int high;
207  unsigned int low;
208  unsigned int targetLoc;
209 
210  setBit(bitArray, bitIdx);
212  return;
213  /* Update the counter file on disk */
214  fileSlot = bitIdx / 2;
215  targetLoc = bitIdx % 2;
216 
217  GNUNET_assert(fileSlot ==
219  if (1 != GNUNET_DISK_file_read(fh, &value, 1))
220  value = 0;
221  low = value & 0xF;
222  high = (value & (~0xF)) >> 4;
223 
224  if (targetLoc == 0)
225  {
226  if (low < 0xF)
227  low++;
228  }
229  else
230  {
231  if (high < 0xF)
232  high++;
233  }
234  value = ((high << 4) | low);
235  GNUNET_assert(fileSlot ==
237  GNUNET_assert(1 == GNUNET_DISK_file_write(fh, &value, 1));
238 }
239 
248 static void
250  unsigned int bitIdx,
251  const struct GNUNET_DISK_FileHandle *fh)
252 {
253  off_t fileslot;
254  unsigned char value;
255  unsigned int high;
256  unsigned int low;
257  unsigned int targetLoc;
258 
260  return; /* cannot decrement! */
261  /* Each char slot in the counter file holds two 4 bit counters */
262  fileslot = bitIdx / 2;
263  targetLoc = bitIdx % 2;
264  if (GNUNET_SYSERR ==
266  {
268  return;
269  }
270  if (1 != GNUNET_DISK_file_read(fh, &value, 1))
271  value = 0;
272  low = value & 0xF;
273  high = (value & 0xF0) >> 4;
274 
275  /* decrement, but once we have reached the max, never go back! */
276  if (targetLoc == 0)
277  {
278  if ((low > 0) && (low < 0xF))
279  low--;
280  if (low == 0)
281  {
282  clearBit(bitArray, bitIdx);
283  }
284  }
285  else
286  {
287  if ((high > 0) && (high < 0xF))
288  high--;
289  if (high == 0)
290  {
291  clearBit(bitArray, bitIdx);
292  }
293  }
294  value = ((high << 4) | low);
295  if (GNUNET_SYSERR ==
297  {
299  return;
300  }
301  GNUNET_assert(1 == GNUNET_DISK_file_write(fh, &value, 1));
302 }
303 
304 #define BUFFSIZE 65536
305 
313 static int
315 {
316  char buffer[BUFFSIZE];
317  size_t bytesleft = size;
318  int res = 0;
319 
321  return GNUNET_SYSERR;
322  memset(buffer, 0, sizeof(buffer));
324  while (bytesleft > 0)
325  {
326  if (bytesleft > sizeof(buffer))
327  {
328  res = GNUNET_DISK_file_write(fh, buffer, sizeof(buffer));
329  if (res >= 0)
330  bytesleft -= res;
331  }
332  else
333  {
334  res = GNUNET_DISK_file_write(fh, buffer, bytesleft);
335  if (res >= 0)
336  bytesleft -= res;
337  }
338  if (GNUNET_SYSERR == res)
339  return GNUNET_SYSERR;
340  }
341  return GNUNET_OK;
342 }
343 
344 /* ************** GNUNET_CONTAINER_BloomFilter iterator ********* */
345 
356 typedef int (*BitIterator) (void *cls,
357  const struct GNUNET_CONTAINER_BloomFilter *bf,
358  unsigned int bit);
359 
360 
370 static void
372  BitIterator callback,
373  void *arg,
374  const struct GNUNET_HashCode *key)
375 {
376  struct GNUNET_HashCode tmp[2];
377  int bitCount;
378  unsigned int round;
379  unsigned int slot = 0;
380 
381  bitCount = bf->addressesPerElement;
382  tmp[0] = *key;
383  round = 0;
384  GNUNET_assert(bf->bitArraySize > 0);
385  GNUNET_assert(bf->bitArraySize * 8LL > bf->bitArraySize);
386  while (bitCount > 0)
387  {
388  while (slot < (sizeof(struct GNUNET_HashCode) / sizeof(uint32_t)))
389  {
390  if (GNUNET_YES !=
391  callback(arg,
392  bf,
393  ntohl((((uint32_t *)&tmp[round & 1])[slot])) %
394  ((bf->bitArraySize * 8LL))))
395  return;
396  slot++;
397  bitCount--;
398  if (bitCount == 0)
399  break;
400  }
401  if (bitCount > 0)
402  {
403  GNUNET_CRYPTO_hash(&tmp[round & 1],
404  sizeof(struct GNUNET_HashCode),
405  &tmp[(round + 1) & 1]);
406  round++;
407  slot = 0;
408  }
409  }
410 }
411 
412 
421 static int
423  const struct GNUNET_CONTAINER_BloomFilter *bf,
424  unsigned int bit)
425 {
426  struct GNUNET_CONTAINER_BloomFilter *b = cls;
427 
428  incrementBit(b->bitArray, bit, bf->fh);
429  return GNUNET_YES;
430 }
431 
432 
441 static int
443  const struct GNUNET_CONTAINER_BloomFilter *bf,
444  unsigned int bit)
445 {
446  struct GNUNET_CONTAINER_BloomFilter *b = cls;
447 
448  decrementBit(b->bitArray, bit, bf->fh);
449  return GNUNET_YES;
450 }
451 
452 
461 static int
462 testBitCallback(void *cls,
463  const struct GNUNET_CONTAINER_BloomFilter *bf,
464  unsigned int bit)
465 {
466  int *arg = cls;
467 
468  if (GNUNET_NO == testBit(bf->bitArray, bit))
469  {
470  *arg = GNUNET_NO;
471  return GNUNET_NO;
472  }
473  return GNUNET_YES;
474 }
475 
476 /* *********************** INTERFACE **************** */
477 
491  size_t size,
492  unsigned int k)
493 {
494  struct GNUNET_CONTAINER_BloomFilter *bf;
495  char *rbuff;
496  off_t pos;
497  int i;
498  size_t ui;
499  off_t fsize;
500  int must_read;
501 
502  GNUNET_assert(NULL != filename);
503  if ((k == 0) || (size == 0))
504  return NULL;
505  if (size < BUFFSIZE)
506  size = BUFFSIZE;
507  ui = 1;
508  while ((ui < size) && (ui * 2 > ui))
509  ui *= 2;
510  size = ui; /* make sure it's a power of 2 */
511 
513  /* Try to open a bloomfilter file */
514  if (GNUNET_YES == GNUNET_DISK_file_test(filename))
515  bf->fh = GNUNET_DISK_file_open(filename,
519  if (NULL != bf->fh)
520  {
521  /* file existed, try to read it! */
522  must_read = GNUNET_YES;
523  if (GNUNET_OK != GNUNET_DISK_file_handle_size(bf->fh, &fsize))
524  {
526  GNUNET_free(bf);
527  return NULL;
528  }
529  if (0 == fsize)
530  {
531  /* found existing empty file, just overwrite */
532  if (GNUNET_OK != make_empty_file(bf->fh, size * 4LL))
533  {
536  GNUNET_free(bf);
537  return NULL;
538  }
539  }
540  else if (fsize != ((off_t)size) * 4LL)
541  {
542  GNUNET_log(
544  _(
545  "Size of file on disk is incorrect for this Bloom filter (want %llu, have %llu)\n"),
546  (unsigned long long)(size * 4LL),
547  (unsigned long long)fsize);
549  GNUNET_free(bf);
550  return NULL;
551  }
552  }
553  else
554  {
555  /* file did not exist, don't read, just create */
556  must_read = GNUNET_NO;
557  bf->fh = GNUNET_DISK_file_open(filename,
562  if (NULL == bf->fh)
563  {
564  GNUNET_free(bf);
565  return NULL;
566  }
567  if (GNUNET_OK != make_empty_file(bf->fh, size * 4LL))
568  {
571  GNUNET_free(bf);
572  return NULL;
573  }
574  }
575  bf->filename = GNUNET_strdup(filename);
576  /* Alloc block */
577  bf->bitArray = GNUNET_malloc_large(size);
578  if (NULL == bf->bitArray)
579  {
580  if (NULL != bf->fh)
582  GNUNET_free(bf->filename);
583  GNUNET_free(bf);
584  return NULL;
585  }
586  bf->bitArraySize = size;
587  bf->addressesPerElement = k;
588  if (GNUNET_YES != must_read)
589  return bf; /* already done! */
590  /* Read from the file what bits we can */
591  rbuff = GNUNET_malloc(BUFFSIZE);
592  pos = 0;
593  while (pos < ((off_t)size) * 8LL)
594  {
595  int res;
596 
597  res = GNUNET_DISK_file_read(bf->fh, rbuff, BUFFSIZE);
598  if (res == -1)
599  {
601  GNUNET_free(rbuff);
602  GNUNET_free(bf->filename);
604  GNUNET_free(bf);
605  return NULL;
606  }
607  if (res == 0)
608  break; /* is ok! we just did not use that many bits yet */
609  for (i = 0; i < res; i++)
610  {
611  if ((rbuff[i] & 0x0F) != 0)
612  setBit(bf->bitArray, pos + i * 2);
613  if ((rbuff[i] & 0xF0) != 0)
614  setBit(bf->bitArray, pos + i * 2 + 1);
615  }
616  if (res < BUFFSIZE)
617  break;
618  pos += BUFFSIZE * 2; /* 2 bits per byte in the buffer */
619  }
620  GNUNET_free(rbuff);
621  return bf;
622 }
623 
624 
640  size_t size,
641  unsigned int k)
642 {
643  struct GNUNET_CONTAINER_BloomFilter *bf;
644 
645  if ((0 == k) || (0 == size))
646  return NULL;
648  bf->filename = NULL;
649  bf->fh = NULL;
650  bf->bitArray = GNUNET_malloc_large(size);
651  if (NULL == bf->bitArray)
652  {
653  GNUNET_free(bf);
654  return NULL;
655  }
656  bf->bitArraySize = size;
657  bf->addressesPerElement = k;
658  if (NULL != data)
659  GNUNET_memcpy(bf->bitArray, data, size);
660  return bf;
661 }
662 
663 
673 int
675  const struct GNUNET_CONTAINER_BloomFilter *bf,
676  char *data,
677  size_t size)
678 {
679  if (NULL == bf)
680  return GNUNET_SYSERR;
681  if (bf->bitArraySize != size)
682  return GNUNET_SYSERR;
683  GNUNET_memcpy(data, bf->bitArray, size);
684  return GNUNET_OK;
685 }
686 
687 
695 void
697 {
698  if (NULL == bf)
699  return;
700  if (bf->fh != NULL)
703  GNUNET_free(bf->bitArray);
704  GNUNET_free(bf);
705 }
706 
707 
713 void
715 {
716  if (NULL == bf)
717  return;
718 
719  memset(bf->bitArray, 0, bf->bitArraySize);
720  if (bf->filename != NULL)
721  make_empty_file(bf->fh, bf->bitArraySize * 4LL);
722 }
723 
724 
732 int
734  const struct GNUNET_CONTAINER_BloomFilter *bf,
735  const struct GNUNET_HashCode *e)
736 {
737  int res;
738 
739  if (NULL == bf)
740  return GNUNET_YES;
741  res = GNUNET_YES;
742  iterateBits(bf, &testBitCallback, &res, e);
743  return res;
744 }
745 
746 
753 void
755  const struct GNUNET_HashCode *e)
756 {
757  if (NULL == bf)
758  return;
759  iterateBits(bf, &incrementBitCallback, bf, e);
760 }
761 
762 
773 int
775  const char *data,
776  size_t size)
777 {
778  unsigned int i;
779  unsigned int n;
780  unsigned long long *fc;
781  const unsigned long long *dc;
782 
783  if (NULL == bf)
784  return GNUNET_YES;
785  if (bf->bitArraySize != size)
786  return GNUNET_SYSERR;
787  fc = (unsigned long long *)bf->bitArray;
788  dc = (const unsigned long long *)data;
789  n = size / sizeof(unsigned long long);
790 
791  for (i = 0; i < n; i++)
792  fc[i] |= dc[i];
793  for (i = n * sizeof(unsigned long long); i < size; i++)
794  bf->bitArray[i] |= data[i];
795  return GNUNET_OK;
796 }
797 
808 int
810  struct GNUNET_CONTAINER_BloomFilter *bf,
811  const struct GNUNET_CONTAINER_BloomFilter *to_or)
812 {
813  unsigned int i;
814  unsigned int n;
815  unsigned long long *fc;
816  const unsigned long long *dc;
817  size_t size;
818 
819  if (NULL == bf)
820  return GNUNET_OK;
821  if (bf->bitArraySize != to_or->bitArraySize)
822  {
823  GNUNET_break(0);
824  return GNUNET_SYSERR;
825  }
826  size = bf->bitArraySize;
827  fc = (unsigned long long *)bf->bitArray;
828  dc = (const unsigned long long *)to_or->bitArray;
829  n = size / sizeof(unsigned long long);
830 
831  for (i = 0; i < n; i++)
832  fc[i] |= dc[i];
833  for (i = n * sizeof(unsigned long long); i < size; i++)
834  bf->bitArray[i] |= to_or->bitArray[i];
835  return GNUNET_OK;
836 }
837 
838 
845 void
847  const struct GNUNET_HashCode *e)
848 {
849  if (NULL == bf)
850  return;
851  if (NULL == bf->filename)
852  return;
853  iterateBits(bf, &decrementBitCallback, bf, e);
854 }
855 
867 void
870  void *iterator_cls,
871  size_t size,
872  unsigned int k)
873 {
874  struct GNUNET_HashCode hc;
875  unsigned int i;
876 
877  GNUNET_free(bf->bitArray);
878  i = 1;
879  while (i < size)
880  i *= 2;
881  size = i; /* make sure it's a power of 2 */
882  bf->addressesPerElement = k;
883  bf->bitArraySize = size;
884  bf->bitArray = GNUNET_malloc(size);
885  if (NULL != bf->filename)
886  make_empty_file(bf->fh, bf->bitArraySize * 4LL);
887  while (GNUNET_YES == iterator(iterator_cls, &hc))
889 }
890 
891 /* end of container_bloomfilter.c */
static int testBitCallback(void *cls, const struct GNUNET_CONTAINER_BloomFilter *bf, unsigned int bit)
Callback: test if all bits are set.
static int iterator(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
Iterator over hash map entries.
int GNUNET_DISK_file_test(const char *fil)
Check that fil corresponds to a filename (of a file that exists and that is not a directory)...
Definition: disk.c:541
struct GNUNET_CONTAINER_BloomFilter * GNUNET_CONTAINER_bloomfilter_init(const char *data, size_t size, unsigned int k)
Create a bloom filter from raw bits.
Create file if it doesn&#39;t exist.
void GNUNET_CONTAINER_bloomfilter_add(struct GNUNET_CONTAINER_BloomFilter *bf, const struct GNUNET_HashCode *e)
Add an element to the filter.
int GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
Definition: disk.c:1339
ssize_t GNUNET_DISK_file_read(const struct GNUNET_DISK_FileHandle *h, void *result, size_t len)
Read the contents of a binary file into a buffer.
Definition: disk.c:729
static void decrementBit(char *bitArray, unsigned int bitIdx, const struct GNUNET_DISK_FileHandle *fh)
Clears a bit from bitArray if the respective usage counter on the disk hits/is zero.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static int make_empty_file(const struct GNUNET_DISK_FileHandle *fh, size_t size)
Creates a file filled with zeroes.
unsigned int addressesPerElement
How many bits we set for each stored element.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define LOG_STRERROR_FILE(kind, syscall, filename)
size_t GNUNET_CONTAINER_bloomfilter_get_size(const struct GNUNET_CONTAINER_BloomFilter *bf)
Get size of the bloom filter.
static struct Experiment * e
#define GNUNET_NO
Definition: gnunet_common.h:78
char * filename
Filename of the filter.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
static int incrementBitCallback(void *cls, const struct GNUNET_CONTAINER_BloomFilter *bf, unsigned int bit)
Callback: increment bit.
off_t GNUNET_DISK_file_seek(const struct GNUNET_DISK_FileHandle *h, off_t offset, enum GNUNET_DISK_Seek whence)
Move the read/write pointer in a file.
Definition: disk.c:223
#define GNUNET_malloc_large(size)
Wrapper around malloc.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
int GNUNET_DISK_handle_invalid(const struct GNUNET_DISK_FileHandle *h)
Checks whether a handle is invalid.
Definition: disk.c:190
int GNUNET_CONTAINER_bloomfilter_or2(struct GNUNET_CONTAINER_BloomFilter *bf, const struct GNUNET_CONTAINER_BloomFilter *to_or)
Or the entries of the given raw data array with the data of the given bloom filter.
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
#define GNUNET_log_strerror(level, cmd)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
static void clearBit(char *bitArray, unsigned int bitIdx)
Clears a bit from bitArray.
void GNUNET_CONTAINER_bloomfilter_remove(struct GNUNET_CONTAINER_BloomFilter *bf, const struct GNUNET_HashCode *e)
Remove an element from the filter.
static char * value
Value of the record to add/remove.
int GNUNET_CONTAINER_bloomfilter_test(const struct GNUNET_CONTAINER_BloomFilter *bf, const struct GNUNET_HashCode *e)
Test if an element is in the filter.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:44
ssize_t GNUNET_DISK_file_write(const struct GNUNET_DISK_FileHandle *h, const void *buffer, size_t n)
Write a buffer to a file.
Definition: disk.c:817
size_t bitArraySize
Size of bitArray in bytes.
static void iterateBits(const struct GNUNET_CONTAINER_BloomFilter *bf, BitIterator callback, void *arg, const struct GNUNET_HashCode *key)
Call an iterator for each bit that the bloomfilter must test or set for this element.
struct GNUNET_CONTAINER_BloomFilter * GNUNET_CONTAINER_bloomfilter_load(const char *filename, size_t size, unsigned int k)
Load a bloom-filter from a file.
A 512-bit hashcode.
static int decrementBitCallback(void *cls, const struct GNUNET_CONTAINER_BloomFilter *bf, unsigned int bit)
Callback: decrement bit.
size_t GNUNET_CONTAINER_bloomfilter_get_element_addresses(const struct GNUNET_CONTAINER_BloomFilter *bf)
Get the number of the addresses set per element in the bloom filter.
static int res
void GNUNET_CONTAINER_bloomfilter_clear(struct GNUNET_CONTAINER_BloomFilter *bf)
Reset a bloom filter to empty.
struct GNUNET_HashCode key
The key used in the DHT.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
static unsigned int size
Size of the "table".
Definition: peer.c:66
int GNUNET_CONTAINER_bloomfilter_or(struct GNUNET_CONTAINER_BloomFilter *bf, const char *data, size_t size)
Or the entries of the given raw data array with the data of the given bloom filter.
int GNUNET_CONTAINER_bloomfilter_get_raw_data(const struct GNUNET_CONTAINER_BloomFilter *bf, char *data, size_t size)
Copy the raw data of this bloomfilter into the given data array.
char * bitArray
The actual bloomfilter bit array.
struct GNUNET_DISK_FileHandle * fh
The bit counter file on disk.
static void setBit(char *bitArray, unsigned int bitIdx)
Sets a bit active in the bitArray.
Seek an absolute position (from the start of the file).
int GNUNET_DISK_file_handle_size(struct GNUNET_DISK_FileHandle *fh, off_t *size)
Get the size of an open file.
Definition: disk.c:203
#define GNUNET_log(kind,...)
Open the file for both reading and writing.
static void incrementBit(char *bitArray, unsigned int bitIdx, const struct GNUNET_DISK_FileHandle *fh)
Sets a bit active in the bitArray and increments bit-specific usage counter on disk (but only if the ...
static int testBit(char *bitArray, unsigned int bitIdx)
Checks if a bit is active in the bitArray.
#define GNUNET_YES
Definition: gnunet_common.h:77
struct GNUNET_CONTAINER_BloomFilter * GNUNET_CONTAINER_bloomfilter_copy(const struct GNUNET_CONTAINER_BloomFilter *bf)
Copy an existing memory.
int(* GNUNET_CONTAINER_HashCodeIterator)(void *cls, struct GNUNET_HashCode *next)
Iterator over struct GNUNET_HashCode.
#define BUFFSIZE
uint32_t data
The data value.
struct GNUNET_DISK_FileHandle * GNUNET_DISK_file_open(const char *fn, enum GNUNET_DISK_OpenFlags flags, enum GNUNET_DISK_AccessPermissions perm)
Open a file.
Definition: disk.c:1262
Handle used to access files (and pipes).
void GNUNET_CONTAINER_bloomfilter_resize(struct GNUNET_CONTAINER_BloomFilter *bf, GNUNET_CONTAINER_HashCodeIterator iterator, void *iterator_cls, size_t size, unsigned int k)
Resize a bloom filter.
void GNUNET_CONTAINER_bloomfilter_free(struct GNUNET_CONTAINER_BloomFilter *bf)
Free the space associated with a filter in memory, flush to drive if needed (do not free the space on...
#define GNUNET_malloc(size)
Wrapper around malloc.
static struct GNUNET_FS_DownloadContext * dc
#define GNUNET_free(ptr)
Wrapper around free.
int(* BitIterator)(void *cls, const struct GNUNET_CONTAINER_BloomFilter *bf, unsigned int bit)
Iterator (callback) method to be called by the bloomfilter iterator on each bit that is to be set or ...