void mbarray_Destroy(MBArray * array) { if (array != NULL) { if (array->vector != NULL) { if (array->filename == NULL) { // This is the case where we initialized the vector // with malloc, and not mmap. As such, be free! free((void*)array->vector); array->vector = NULL; } else { if (munmap(array->vector, _mmap_size(array))) { fprintf(stderr, "Unable to close mmap!\n"); } if (array->fd >= 0) { fsync(array->fd); close(array->fd); array->fd = -1; } array->vector = NULL; } } if (array->filename) { free((void *)array->filename); array->filename = NULL; } free(array); } }
int mbarray_Sync(MBArray * array) { if (!array || !array->vector) { errno = EINVAL; return 1; } if (msync(array->vector, _mmap_size(array), MS_ASYNC)) { return 1; } return 0; }
void mbarray_Destroy(MBArray * array) { if (array != NULL) { if (array->vector != NULL) { if (munmap(array->vector, _mmap_size(array))) { fprintf(stderr, "Unable to close mmap!\n"); } array->vector = NULL; } if (array->filename) { free((void *)array->filename); array->filename = NULL; } /* Make sure that we close the file associated with this array. */ if (array->fd) { close(array->fd); } free(array); } }
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; }