X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Futil%2Fcontainer_bloomfilter.c;h=6e8fc78377f4db6ec600e423222752072bc60c3d;hb=8226d9807819dbbc4b05751f4cdd09603832367d;hp=5e69fe8ab4d0354ddabca47ae9b7b1ce199c5a51;hpb=aa907f2d51d9409635e5d1438b67efa6857a4c69;p=oweals%2Fgnunet.git diff --git a/src/util/container_bloomfilter.c b/src/util/container_bloomfilter.c index 5e69fe8ab..6e8fc7837 100644 --- a/src/util/container_bloomfilter.c +++ b/src/util/container_bloomfilter.c @@ -142,7 +142,8 @@ 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_DISK_FileHandle *fh) +incrementBit (char *bitArray, unsigned int bitIdx, + const struct GNUNET_DISK_FileHandle *fh) { off_t fileSlot; unsigned char value; @@ -157,8 +158,8 @@ incrementBit (char *bitArray, unsigned int bitIdx, const struct GNUNET_DISK_File fileSlot = bitIdx / 2; targetLoc = bitIdx % 2; - GNUNET_assert (fileSlot == - GNUNET_DISK_file_seek (fh, fileSlot, GNUNET_DISK_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; @@ -175,9 +176,9 @@ incrementBit (char *bitArray, unsigned int bitIdx, const struct GNUNET_DISK_File high++; } value = ((high << 4) | low); - GNUNET_assert (fileSlot == GNUNET_DISK_file_seek (fh, - fileSlot, - GNUNET_DISK_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)); } @@ -190,7 +191,8 @@ incrementBit (char *bitArray, unsigned int bitIdx, const struct GNUNET_DISK_File * @param fh A file to keep the 4bit address usage counters in */ static void -decrementBit (char *bitArray, unsigned int bitIdx, const struct GNUNET_DISK_FileHandle *fh) +decrementBit (char *bitArray, unsigned int bitIdx, + const struct GNUNET_DISK_FileHandle *fh) { off_t fileSlot; unsigned char value; @@ -243,8 +245,7 @@ decrementBit (char *bitArray, unsigned int bitIdx, const struct GNUNET_DISK_File * @return GNUNET_OK if created ok, GNUNET_SYSERR otherwise */ static int -makeEmptyFile (const struct GNUNET_DISK_FileHandle *fh, - size_t size) +makeEmptyFile (const struct GNUNET_DISK_FileHandle *fh, size_t size) { char *buffer; size_t bytesleft = size; @@ -286,7 +287,7 @@ makeEmptyFile (const struct GNUNET_DISK_FileHandle *fh, * @param bit the current bit */ typedef void (*BitIterator) (void *cls, - struct GNUNET_CONTAINER_BloomFilter * bf, + struct GNUNET_CONTAINER_BloomFilter * bf, unsigned int bit); /** @@ -314,9 +315,9 @@ iterateBits (struct GNUNET_CONTAINER_BloomFilter *bf, { while (slot < (sizeof (GNUNET_HashCode) / sizeof (uint32_t))) { - callback (arg, - bf, - (((uint32_t *) &tmp[round & 1])[slot]) & + callback (arg, + bf, + (((uint32_t *) & tmp[round & 1])[slot]) & ((bf->bitArraySize * 8) - 1)); slot++; bitCount--; @@ -342,7 +343,7 @@ iterateBits (struct GNUNET_CONTAINER_BloomFilter *bf, */ static void incrementBitCallback (void *cls, - struct GNUNET_CONTAINER_BloomFilter *bf, + struct GNUNET_CONTAINER_BloomFilter *bf, unsigned int bit) { incrementBit (bf->bitArray, bit, bf->fh); @@ -357,7 +358,7 @@ incrementBitCallback (void *cls, */ static void decrementBitCallback (void *cls, - struct GNUNET_CONTAINER_BloomFilter *bf, + struct GNUNET_CONTAINER_BloomFilter *bf, unsigned int bit) { decrementBit (bf->bitArray, bit, bf->fh); @@ -372,7 +373,7 @@ decrementBitCallback (void *cls, */ static void testBitCallback (void *cls, - struct GNUNET_CONTAINER_BloomFilter *bf, unsigned int bit) + struct GNUNET_CONTAINER_BloomFilter *bf, unsigned int bit) { int *arg = cls; if (GNUNET_NO == testBit (bf->bitArray, bit)) @@ -392,9 +393,8 @@ testBitCallback (void *cls, * @return the bloomfilter */ struct GNUNET_CONTAINER_BloomFilter * -GNUNET_CONTAINER_bloomfilter_load (const char *filename, - size_t size, - unsigned int k) +GNUNET_CONTAINER_bloomfilter_load (const char *filename, + size_t size, unsigned int k) { struct GNUNET_CONTAINER_BloomFilter *bf; char *rbuff; @@ -416,8 +416,9 @@ GNUNET_CONTAINER_bloomfilter_load (const char *filename, if (filename != NULL) { 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); + | GNUNET_DISK_OPEN_CREATE, + GNUNET_DISK_PERM_USER_READ | + GNUNET_DISK_PERM_USER_WRITE); if (NULL == bf->fh) { GNUNET_free (bf); @@ -432,6 +433,14 @@ GNUNET_CONTAINER_bloomfilter_load (const char *filename, } /* 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); @@ -446,12 +455,11 @@ GNUNET_CONTAINER_bloomfilter_load (const char *filename, 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 == -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++) @@ -486,8 +494,7 @@ GNUNET_CONTAINER_bloomfilter_load (const char *filename, */ struct GNUNET_CONTAINER_BloomFilter * GNUNET_CONTAINER_bloomfilter_init (const char *data, - size_t size, - unsigned int k) + size_t size, unsigned int k) { struct GNUNET_CONTAINER_BloomFilter *bf; size_t ui; @@ -506,6 +513,11 @@ GNUNET_CONTAINER_bloomfilter_init (const char *data, 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) @@ -527,8 +539,7 @@ GNUNET_CONTAINER_bloomfilter_init (const char *data, */ int GNUNET_CONTAINER_bloomfilter_get_raw_data (struct GNUNET_CONTAINER_BloomFilter - *bf, char *data, - size_t size) + *bf, char *data, size_t size) { if (NULL == bf) return GNUNET_SYSERR; @@ -551,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); } @@ -626,18 +635,24 @@ GNUNET_CONTAINER_bloomfilter_add (struct GNUNET_CONTAINER_BloomFilter *bf, */ int GNUNET_CONTAINER_bloomfilter_or (struct GNUNET_CONTAINER_BloomFilter *bf, - const char *data, - size_t 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; } @@ -666,16 +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, - size_t size, - unsigned int k) + void *iterator_cls, + size_t size, unsigned int k) { GNUNET_HashCode hc; unsigned int i; @@ -691,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 (iterator_arg, &hc)) + while (GNUNET_YES == iterator (iterator_cls, &hc)) GNUNET_CONTAINER_bloomfilter_add (bf, &hc); }