void bloomfilter_Destroy(BloomFilter * bf) { if (bf) { if (bf->array) { mbarray_Destroy(bf->array); bf->array = NULL; } free(bf); } }
int main(int argc, char ** argv) { BTYPE bit; int value; MBArray * array; int i; if (argc < 3) { fprintf(stderr, "Usage: %s FILE BIT [VALUE]\nValue is either 0 or 1 and will define a set/clear operation.\n", argv[0]); return 255; } /* Open file */ array = mbarray_Create( 0, argv[1], "", 0, O_RDWR, 0); if (!array) goto error; bit = atol(argv[2]); if (argc > 3) { value = atol(argv[3]); if (value) { if (mbarray_Set(array, bit)) goto error; } else { if (mbarray_Clear(array, bit)) goto error; } } for (i = 0; i < array->bits; i++) { mbarray_Set(array, i); mbarray_Test(array, i); } getc(stdin); bit = 1 - mbarray_Test(array, bit); mbarray_Destroy(array); return bit; error: fprintf(stderr, "Error: %s [%d]\n", strerror(errno), errno); return 255; }
BloomFilter *bloomfilter_Create(size_t max_num_elem, double error_rate, const char * file, BTYPE num_bits, int oflags, int perms, int *hash_seeds, int num_hashes) { BloomFilter * bf = (BloomFilter *)malloc(sizeof(BloomFilter)); MBArray * array; if (!bf) { return NULL; } bf->max_num_elem = max_num_elem; bf->error_rate = error_rate; bf->num_hashes = num_hashes; bf->count_correct = 1; bf->bf_version = BF_CURRENT_VERSION; bf->elem_count = 0; memset(bf->reserved, sizeof(uint32_t) * 32, 0); memset(bf->hash_seeds, sizeof(uint32_t) * 256, 0); memcpy(bf->hash_seeds, hash_seeds, sizeof(uint32_t) * num_hashes); array = mbarray_Create(num_bits, file, (char *)bf, sizeof(BloomFilter), oflags, perms); if (!array) { bloomfilter_Destroy(bf); return NULL; } /* After we create the new array object, this array may already have all of the bloom filter data from the file in the header info. By calling mbarray_Header, we copy that header data back into this BloomFilter object. */ if (mbarray_Header((char *)bf, array, sizeof(BloomFilter)) == NULL) { bloomfilter_Destroy(bf); mbarray_Destroy(array); return NULL; } /* Since we just initialized from a file, we have to fix our pointers */ bf->array = array; return bf; }
MBArray * mbarray_Create_Malloc(BTYPE num_bits) { // Try to allocate space for a MBArray struct errno = 0; MBArray * array = (MBArray *)malloc(sizeof(MBArray)); // And ensure that it was constructed properly if (!array || errno) { return NULL; } // Since we're not using a real mmap file for this instance, // we can get away with setting a bunch of the internal vars // to be reasonable default values array->filename = NULL; array->vector = NULL; array->fd = 0; array->preamblesize = 0; array->preamblebytes = 0; // This is how many DTYPEs there are, and how many bytes there // are in this particular structure. As well as the number of // bits array->size = (size_t)ceil((double)num_bits / sizeof(DTYPE) / 8.0); array->bytes = (size_t)ceil((double)num_bits / 8.0); array->bits = num_bits; // Now try to allocate enough space for our array errno = 0; array->vector = (DTYPE *)calloc(array->bytes, 1); if (errno || !array->vector) { mbarray_Destroy(array); return NULL; } return array; }
BloomFilter * bloomfilter_Copy_Template(BloomFilter * src, char * filename, int perms) { BloomFilter * bf = (BloomFilter *)malloc(sizeof(BloomFilter)); MBArray * array; if (bf == NULL) { return NULL; } array = mbarray_Copy_Template(src->array, filename, perms); if (array == NULL) { free(bf); return NULL; } if (mbarray_Header((char *)bf, array, sizeof(BloomFilter)) == NULL) { bloomfilter_Destroy(bf); mbarray_Destroy(array); return NULL; } bf->array = array; return bf; }
int main(int argc, char ** argv) { MBArray * array; if (argc < 3) { fprintf(stderr, "Usage: %s FILENAME SIZE\nCreate new mmap'd array file.\n", argv[0]); return 1; } array = mbarray_Create( atol(argv[2]), argv[1], "", 0, O_RDWR | O_CREAT, 0777); if (!array) goto error; mbarray_ClearAll(array); mbarray_Destroy(array); return 0; error: fprintf(stderr, "Error: %s [%d]\n", strerror(errno), errno); return 255; }
MBArray * mbarray_Create(BTYPE num_bits, const char * file, const char * header, int32_t header_len, int oflag, int perms) { errno = 0; MBArray * array = (MBArray *)malloc(sizeof(MBArray)); int filesize; int32_t fheaderlen; if (!array || errno) { return NULL; } array->filename = NULL; array->vector = NULL; errno = 0; array->fd = open(file, oflag, perms); if (array->fd < 0) { errno = EINVAL; mbarray_Destroy(array); return NULL; } fheaderlen = mbarray_HeaderLen(array); errno = 0; if (fheaderlen >= 0 && !(oflag && O_CREAT) && fheaderlen != header_len) { errno = EINVAL; mbarray_Destroy(array); return NULL; } else if (fheaderlen >= 0) { header_len = fheaderlen; } array->preamblebytes = MBAMAGICSIZE + sizeof(BTYPE) + sizeof(header_len) + header_len; /* This size is using 256-byte alignment so that we can use pretty much any base 2 data type */ array->preamblesize = ((int)ceil((double)array->preamblebytes / 256.0) * 256) / sizeof(DTYPE); array->preamblebytes = array->preamblesize * (sizeof(DTYPE)); if (errno) { mbarray_Destroy(array); return NULL; } filesize = _filesize(array->fd); if (filesize > 50 && !num_bits) { num_bits = _get_num_bits(array->fd); } array->size = (int)ceil((double)num_bits / sizeof(DTYPE) / 8.0); array->bytes = (int)ceil((double)num_bits / 8.0); if (filesize < 0) { mbarray_Destroy(array); return NULL; } else if (filesize && !_valid_magic(array->fd)) { errno = EINVAL; mbarray_Destroy(array); return NULL; } else if (filesize && filesize < (array->bytes + array->preamblebytes - 1)) { errno = EINVAL; mbarray_Destroy(array); return NULL; } else if (!filesize) { if (!(oflag & O_CREAT) || (!num_bits) || _initialize_file(array->fd, array->bytes + array->preamblebytes - 1, num_bits, header, header_len)) { if (!errno) { errno = ENOENT; } mbarray_Destroy(array); return NULL; } } else { if (!num_bits) { num_bits = _get_num_bits(array->fd); array->size = (int)ceil((double)num_bits / sizeof(DTYPE) / 8.0); array->bytes = (int)ceil((double)num_bits / 8.0); } else if (_get_num_bits(array->fd) != num_bits) { mbarray_Destroy(array); errno = EINVAL; return NULL; } } errno = 0; array->vector = (DTYPE *)mmap(NULL, _mmap_size(array), PROT_READ | PROT_WRITE, MAP_SHARED, array->fd, 0); if (errno || !array->vector) { mbarray_Destroy(array); return NULL; } array->filename = (char *)malloc(strlen(file) + 1); if (!array->filename) { mbarray_Destroy(array); return NULL; } strcpy((char *)array->filename, file); array->bits = num_bits; return array; }