X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Futil%2Fcontainer_bloomfilter.c;h=6e8fc78377f4db6ec600e423222752072bc60c3d;hb=8226d9807819dbbc4b05751f4cdd09603832367d;hp=e5a0955c40fb39d8dd802176377e07f90da4ffab;hpb=dc6e9887c24209d0e3dfb6cfb30fbde6ae3b47e9;p=oweals%2Fgnunet.git diff --git a/src/util/container_bloomfilter.c b/src/util/container_bloomfilter.c index e5a0955c4..6e8fc7837 100644 --- a/src/util/container_bloomfilter.c +++ b/src/util/container_bloomfilter.c @@ -60,7 +60,7 @@ struct GNUNET_CONTAINER_BloomFilter /** * The bit counter file on disk */ - struct GNUNET_IO_Handle *fh; + struct GNUNET_DISK_FileHandle *fh; /** * How many bits we set for each stored element @@ -70,7 +70,7 @@ struct GNUNET_CONTAINER_BloomFilter /** * Size of bitArray in bytes */ - unsigned int bitArraySize; + size_t bitArraySize; }; @@ -85,7 +85,7 @@ struct GNUNET_CONTAINER_BloomFilter static void setBit (char *bitArray, unsigned int bitIdx) { - unsigned int arraySlot; + size_t arraySlot; unsigned int targetBit; arraySlot = bitIdx / 8; @@ -103,7 +103,7 @@ setBit (char *bitArray, unsigned int bitIdx) static void clearBit (char *bitArray, unsigned int bitIdx) { - unsigned int slot; + size_t slot; unsigned int targetBit; slot = bitIdx / 8; @@ -121,7 +121,7 @@ clearBit (char *bitArray, unsigned int bitIdx) static int testBit (char *bitArray, unsigned int bitIdx) { - unsigned int slot; + size_t slot; unsigned int targetBit; slot = bitIdx / 8; @@ -142,9 +142,10 @@ testBit (char *bitArray, unsigned int bitIdx) * @param fh A file to keep the 4 bit address usage counters in */ static void -incrementBit (char *bitArray, unsigned int bitIdx, const struct GNUNET_IO_Handle *fh) +incrementBit (char *bitArray, unsigned int bitIdx, + const struct GNUNET_DISK_FileHandle *fh) { - unsigned int fileSlot; + off_t fileSlot; unsigned char value; unsigned int high; unsigned int low; @@ -157,7 +158,8 @@ incrementBit (char *bitArray, unsigned int bitIdx, const struct GNUNET_IO_Handle fileSlot = bitIdx / 2; targetLoc = bitIdx % 2; - GNUNET_assert (fileSlot == (unsigned int) GNUNET_DISK_file_seek (fh, fileSlot, GNUNET_SEEK_SET)); + GNUNET_assert (fileSlot == + GNUNET_DISK_file_seek (fh, fileSlot, GNUNET_DISK_SEEK_SET)); if (1 != GNUNET_DISK_file_read (fh, &value, 1)) value = 0; low = value & 0xF; @@ -174,7 +176,9 @@ incrementBit (char *bitArray, unsigned int bitIdx, const struct GNUNET_IO_Handle high++; } value = ((high << 4) | low); - GNUNET_assert (fileSlot == (unsigned int) GNUNET_DISK_file_seek (fh, fileSlot, GNUNET_SEEK_SET)); + GNUNET_assert (fileSlot == GNUNET_DISK_file_seek (fh, + fileSlot, + GNUNET_DISK_SEEK_SET)); GNUNET_assert (1 == GNUNET_DISK_file_write (fh, &value, 1)); } @@ -187,9 +191,10 @@ incrementBit (char *bitArray, unsigned int bitIdx, const struct GNUNET_IO_Handle * @param fh A file to keep the 4bit address usage counters in */ static void -decrementBit (char *bitArray, unsigned int bitIdx, const struct GNUNET_IO_Handle *fh) +decrementBit (char *bitArray, unsigned int bitIdx, + const struct GNUNET_DISK_FileHandle *fh) { - unsigned int fileSlot; + off_t fileSlot; unsigned char value; unsigned int high; unsigned int low; @@ -200,7 +205,7 @@ decrementBit (char *bitArray, unsigned int bitIdx, const struct GNUNET_IO_Handle /* Each char slot in the counter file holds two 4 bit counters */ fileSlot = bitIdx / 2; targetLoc = bitIdx % 2; - GNUNET_DISK_file_seek (fh, fileSlot, GNUNET_SEEK_SET); + GNUNET_DISK_file_seek (fh, fileSlot, GNUNET_DISK_SEEK_SET); if (1 != GNUNET_DISK_file_read (fh, &value, 1)) value = 0; low = value & 0xF; @@ -226,7 +231,7 @@ decrementBit (char *bitArray, unsigned int bitIdx, const struct GNUNET_IO_Handle } } value = ((high << 4) | low); - GNUNET_DISK_file_seek (fh, fileSlot, GNUNET_SEEK_SET); + GNUNET_DISK_file_seek (fh, fileSlot, GNUNET_DISK_SEEK_SET); GNUNET_assert (1 == GNUNET_DISK_file_write (fh, &value, 1)); } @@ -240,17 +245,17 @@ decrementBit (char *bitArray, unsigned int bitIdx, const struct GNUNET_IO_Handle * @return GNUNET_OK if created ok, GNUNET_SYSERR otherwise */ static int -makeEmptyFile (const struct GNUNET_IO_Handle *fh, unsigned int size) +makeEmptyFile (const struct GNUNET_DISK_FileHandle *fh, size_t size) { char *buffer; - unsigned int bytesleft = size; + size_t bytesleft = size; int res = 0; if (GNUNET_DISK_handle_invalid (fh)) return GNUNET_SYSERR; buffer = GNUNET_malloc (BUFFSIZE); memset (buffer, 0, BUFFSIZE); - GNUNET_DISK_file_seek (fh, 0, GNUNET_SEEK_SET); + GNUNET_DISK_file_seek (fh, 0, GNUNET_DISK_SEEK_SET); while (bytesleft > 0) { @@ -270,19 +275,20 @@ makeEmptyFile (const struct GNUNET_IO_Handle *fh, unsigned int size) return GNUNET_OK; } -/* ************** GNUNET_CONTAINER_BloomFilter GNUNET_CRYPTO_hash iterator ********* */ +/* ************** GNUNET_CONTAINER_BloomFilter iterator ********* */ /** * Iterator (callback) method to be called by the * bloomfilter iterator on each bit that is to be * set or tested for the key. * + * @param cls closure * @param bf the filter to manipulate * @param bit the current bit - * @param additional context specific argument */ -typedef void (*BitIterator) (struct GNUNET_CONTAINER_BloomFilter * bf, - unsigned int bit, void *arg); +typedef void (*BitIterator) (void *cls, + struct GNUNET_CONTAINER_BloomFilter * bf, + unsigned int bit); /** * Call an iterator for each bit that the bloomfilter @@ -307,11 +313,12 @@ iterateBits (struct GNUNET_CONTAINER_BloomFilter *bf, round = 0; while (bitCount > 0) { - while (slot < (sizeof (GNUNET_HashCode) / sizeof (unsigned int))) + while (slot < (sizeof (GNUNET_HashCode) / sizeof (uint32_t))) { - callback (bf, - (((unsigned int *) &tmp[round & 1])[slot]) & - ((bf->bitArraySize * 8) - 1), arg); + callback (arg, + bf, + (((uint32_t *) & tmp[round & 1])[slot]) & + ((bf->bitArraySize * 8) - 1)); slot++; bitCount--; if (bitCount == 0) @@ -330,13 +337,14 @@ iterateBits (struct GNUNET_CONTAINER_BloomFilter *bf, /** * Callback: increment bit * + * @param cls not used * @param bf the filter to manipulate * @param bit the bit to increment - * @param arg not used */ static void -incrementBitCallback (struct GNUNET_CONTAINER_BloomFilter *bf, - unsigned int bit, void *arg) +incrementBitCallback (void *cls, + struct GNUNET_CONTAINER_BloomFilter *bf, + unsigned int bit) { incrementBit (bf->bitArray, bit, bf->fh); } @@ -344,13 +352,14 @@ incrementBitCallback (struct GNUNET_CONTAINER_BloomFilter *bf, /** * Callback: decrement bit * + * @param cls not used * @param bf the filter to manipulate * @param bit the bit to decrement - * @param arg not used */ static void -decrementBitCallback (struct GNUNET_CONTAINER_BloomFilter *bf, - unsigned int bit, void *arg) +decrementBitCallback (void *cls, + struct GNUNET_CONTAINER_BloomFilter *bf, + unsigned int bit) { decrementBit (bf->bitArray, bit, bf->fh); } @@ -358,13 +367,13 @@ decrementBitCallback (struct GNUNET_CONTAINER_BloomFilter *bf, /** * Callback: test if all bits are set * + * @param cls pointer set to GNUNET_NO if bit is not set * @param bf the filter * @param bit the bit to test - * @param arg pointer set to GNUNET_NO if bit is not set */ static void -testBitCallback (struct GNUNET_CONTAINER_BloomFilter *bf, unsigned int bit, - void *cls) +testBitCallback (void *cls, + struct GNUNET_CONTAINER_BloomFilter *bf, unsigned int bit) { int *arg = cls; if (GNUNET_NO == testBit (bf->bitArray, bit)) @@ -384,14 +393,14 @@ testBitCallback (struct GNUNET_CONTAINER_BloomFilter *bf, unsigned int bit, * @return the bloomfilter */ struct GNUNET_CONTAINER_BloomFilter * -GNUNET_CONTAINER_bloomfilter_load (const char *filename, unsigned int size, - unsigned int k) +GNUNET_CONTAINER_bloomfilter_load (const char *filename, + size_t size, unsigned int k) { struct GNUNET_CONTAINER_BloomFilter *bf; char *rbuff; - unsigned int pos; + off_t pos; int i; - unsigned int ui; + size_t ui; if ((k == 0) || (size == 0)) return NULL; @@ -406,10 +415,11 @@ GNUNET_CONTAINER_bloomfilter_load (const char *filename, unsigned int size, /* Try to open a bloomfilter file */ if (filename != NULL) { - bf->fh = GNUNET_DISK_file_open (filename, - GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE, - GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); - if (!bf->fh) + bf->fh = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_READWRITE + | GNUNET_DISK_OPEN_CREATE, + GNUNET_DISK_PERM_USER_READ | + GNUNET_DISK_PERM_USER_WRITE); + if (NULL == bf->fh) { GNUNET_free (bf); return NULL; @@ -423,6 +433,14 @@ GNUNET_CONTAINER_bloomfilter_load (const char *filename, unsigned int size, } /* Alloc block */ bf->bitArray = GNUNET_malloc_large (size); + if (bf->bitArray == NULL) + { + if (bf->fh != NULL) + GNUNET_DISK_file_close (bf->fh); + GNUNET_free_non_null (bf->filename); + GNUNET_free (bf); + return NULL; + } bf->bitArraySize = size; bf->addressesPerElement = k; memset (bf->bitArray, 0, bf->bitArraySize); @@ -437,6 +455,11 @@ GNUNET_CONTAINER_bloomfilter_load (const char *filename, unsigned int size, int res; res = GNUNET_DISK_file_read (bf->fh, rbuff, BUFFSIZE); + if (res == -1) + { + GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, + "read", bf->filename); + } if (res == 0) break; /* is ok! we just did not use that many bits yet */ for (i = 0; i < res; i++) @@ -470,11 +493,11 @@ GNUNET_CONTAINER_bloomfilter_load (const char *filename, unsigned int size, * @return the bloomfilter */ struct GNUNET_CONTAINER_BloomFilter * -GNUNET_CONTAINER_bloomfilter_init (const char *data, unsigned int size, - unsigned int k) +GNUNET_CONTAINER_bloomfilter_init (const char *data, + size_t size, unsigned int k) { struct GNUNET_CONTAINER_BloomFilter *bf; - unsigned int ui; + size_t ui; if ((k == 0) || (size == 0)) return NULL; @@ -490,6 +513,11 @@ GNUNET_CONTAINER_bloomfilter_init (const char *data, unsigned int size, bf->filename = NULL; bf->fh = NULL; bf->bitArray = GNUNET_malloc_large (size); + if (bf->bitArray == NULL) + { + GNUNET_free (bf); + return NULL; + } bf->bitArraySize = size; bf->addressesPerElement = k; if (data != NULL) @@ -504,13 +532,14 @@ GNUNET_CONTAINER_bloomfilter_init (const char *data, unsigned int size, * Copy the raw data of this bloomfilter into * the given data array. * + * @param bf bloomfilter to take the raw data from * @param data where to write the data * @param size the size of the given data array * @return GNUNET_SYSERR if the data array is not big enough */ int GNUNET_CONTAINER_bloomfilter_get_raw_data (struct GNUNET_CONTAINER_BloomFilter - *bf, char *data, unsigned int size) + *bf, char *data, size_t size) { if (NULL == bf) return GNUNET_SYSERR; @@ -533,11 +562,9 @@ GNUNET_CONTAINER_bloomfilter_free (struct GNUNET_CONTAINER_BloomFilter *bf) { if (NULL == bf) return; - if (bf->filename != NULL) - { - GNUNET_DISK_file_close (&bf->fh); - GNUNET_free (bf->filename); - } + if (bf->fh != NULL) + GNUNET_DISK_file_close (bf->fh); + GNUNET_free_non_null (bf->filename); GNUNET_free (bf->bitArray); GNUNET_free (bf); } @@ -601,21 +628,31 @@ GNUNET_CONTAINER_bloomfilter_add (struct GNUNET_CONTAINER_BloomFilter *bf, * data of the given bloom filter. Assumes that * the size of the data array and the current filter * match. + * * @param bf the filter + * @param data the data to or-in + * @param size number of bytes in data */ int GNUNET_CONTAINER_bloomfilter_or (struct GNUNET_CONTAINER_BloomFilter *bf, - const char *data, unsigned int size) + const char *data, size_t size) { unsigned int i; + unsigned int n; + unsigned long long* fc; + const unsigned long long* dc; if (NULL == bf) return GNUNET_YES; if (bf->bitArraySize != size) return GNUNET_SYSERR; - /* FIXME: we could do this 4-8x faster by - going over int/long arrays */ - for (i = 0; i < size; i++) + fc = (unsigned long long*) bf->bitArray; + dc = (const unsigned long long*) data; + n = size / sizeof (unsigned long long); + + for (i = 0; i < n; i++) + fc[i] |= dc[i]; + for (i = n * sizeof(unsigned long long); i < size; i++) bf->bitArray[i] |= data[i]; return GNUNET_OK; } @@ -644,15 +681,15 @@ GNUNET_CONTAINER_bloomfilter_remove (struct GNUNET_CONTAINER_BloomFilter *bf, * * @param bf the filter * @param iterator an iterator over all elements stored in the BF - * @param iterator_arg argument to the iterator function + * @param iterator_cls argument to the iterator function * @param size the new size for the filter * @param k the new number of GNUNET_CRYPTO_hash-function to apply per element */ void GNUNET_CONTAINER_bloomfilter_resize (struct GNUNET_CONTAINER_BloomFilter *bf, GNUNET_HashCodeIterator iterator, - void *iterator_arg, unsigned int size, - unsigned int k) + void *iterator_cls, + size_t size, unsigned int k) { GNUNET_HashCode hc; unsigned int i; @@ -668,7 +705,7 @@ GNUNET_CONTAINER_bloomfilter_resize (struct GNUNET_CONTAINER_BloomFilter *bf, memset (bf->bitArray, 0, bf->bitArraySize); if (bf->filename != NULL) makeEmptyFile (bf->fh, bf->bitArraySize * 4); - while (GNUNET_YES == iterator (&hc, iterator_arg)) + while (GNUNET_YES == iterator (iterator_cls, &hc)) GNUNET_CONTAINER_bloomfilter_add (bf, &hc); }