diff --git a/blosc/blosc2-stdio.c b/blosc/blosc2-stdio.c index 44c314c9..02ce6c59 100644 --- a/blosc/blosc2-stdio.c +++ b/blosc/blosc2-stdio.c @@ -110,10 +110,25 @@ void *blosc2_stdio_mmap_open(const char *urlpath, const char *mode, void* params blosc2_stdio_mmap *mmap_file = (blosc2_stdio_mmap *) params; if (mmap_file->addr != NULL) { + if (strcmp(mmap_file->urlpath, urlpath) != 0) { + BLOSC_TRACE_ERROR( + "The memory-mapped file is already opened with the path %s and hence cannot be reopened with the path %s. This " + "happens if you try to open a sframe (sparse frame) but please not that memory-mapped files are not supported " + "for sframes.", + mmap_file->urlpath, + urlpath + ); + return NULL; + } + /* A memory-mapped file is only opened once */ return mmap_file; } + // Keep the original path to ensure that all future file openings are with the same path + mmap_file->urlpath = malloc(strlen(urlpath) + 1); + strcpy(mmap_file->urlpath, urlpath); + /* mmap_file->mode mapping is similar to Numpy's memmap (https://github.com/numpy/numpy/blob/main/numpy/_core/memmap.py) and CPython (https://github.com/python/cpython/blob/main/Modules/mmapmodule.c) */ @@ -452,6 +467,7 @@ int blosc2_stdio_mmap_destroy(void* params) { err = -1; } + free(mmap_file->urlpath); if (mmap_file->needs_free) { free(mmap_file); } diff --git a/include/blosc2/blosc2-stdio.h b/include/blosc2/blosc2-stdio.h index 2798ef44..7eaefeed 100644 --- a/include/blosc2/blosc2-stdio.h +++ b/include/blosc2/blosc2-stdio.h @@ -45,7 +45,9 @@ BLOSC_EXPORT int blosc2_stdio_truncate(void *stream, int64_t size); /** - * @brief Parameters for memory-mapped I/O. + * @brief Parameters for memory-mapped I/O. Existing schunks can be opened memory-mapped with the *_udio functions and + * new schunks be created by setting the io member of the #blosc2_storage struct (see test_mmap for examples). Please + * note that only cframes and not sframes can be opened memory-mapped. */ typedef struct { /* Arguments of the mapping */ @@ -56,7 +58,8 @@ typedef struct { //!< but keep all modifications in-memory. On Windows, the file size cannot change in the c mode. int64_t initial_mapping_size; //!< The initial size of the memory mapping used as a large enough write buffer for the r+, w+ and c modes (for - //!< Windows, only the r+ and w+ modes). + //!< Windows, only the r+ and w+ modes). On Windows, this will also be the size of the file while the file is opened. + //!< It will be truncated to the target size when the file is closed (e.g., when the schunk is destroyed). bool needs_free; //!< Indicates whether this object should be freed in the blosc2_destroy_cb callback (set to true if the //!< blosc2_stdio_mmap struct was created on the heap). @@ -64,6 +67,8 @@ typedef struct { /* Internal attributes of the mapping */ char* addr; //!< The starting address of the mapping. + char* urlpath; + //!< The path to the file which is associated with this object. int64_t file_size; //!< The size of the file. int64_t mapping_size; @@ -86,7 +91,7 @@ typedef struct { * @brief Default struct for memory-mapped I/O for user initialization. */ static const blosc2_stdio_mmap BLOSC2_STDIO_MMAP_DEFAULTS = { - "r", (1 << 30), false, NULL, -1, -1, NULL, -1, -1, -1 + "r", (1 << 30), false, NULL, NULL, -1, -1, NULL, -1, -1, -1 #if defined(_WIN32) , INVALID_HANDLE_VALUE #endif