cista icon indicating copy to clipboard operation
cista copied to clipboard

mmap with mmap::protection::MODIFY throws exception

Open BinaryCat17 opened this issue 3 years ago • 3 comments

I try to run this simple code and I get exception 'std::runtime_error': what(): open file mode not supported from file "cista/targets/file.h" line 31 verify(read || write, "open file mode not supported");

I use Windows with msys2(mingw64).

    namespace data = cista::offset;
    constexpr auto const MODE = cista::mode::WITH_VERSION | cista::mode::WITH_INTEGRITY;

    struct pos {
        int x, y;
    };

    using vec = data::vector<pos>;

    {
        vec positions{{1, 2}, {3, 4}, {5, 6}, {7, 8}};
        cista::buf mmap{cista::mmap{"data"}};
        cista::serialize<MODE>(mmap, positions);
    }

    auto b = cista::mmap("data", cista::mmap::protection::MODIFY);
    auto positions = cista::deserialize<vec, MODE>(b);
    positions->push_back({5, 5});

    for(auto pos : *positions) {
        std::cout << pos.x << " " << pos.y << std::endl;
    }

And question. I need load data from disk and modify it, but I don't need to sync data always with disk. Should I serialize data from disk, copy it to memory and, after changing it, serialize it back? Or should I just use mmap::modify? I do not fully understand how much mmap costs and what is more efficient"

BinaryCat17 avatar Feb 05 '21 08:02 BinaryCat17

Note that using MODIFY mode on an mmap is a really bad idea if you want to read and modify serialized data. Using push_back in your example will allocate memory from the heap and replace the pointer in the pointer of the vector serialized in the memory mapped file with the heap pointer. However, the data the pointer points to (the contents of the vector) won't be written to the file. This way, you get a dangling pointer in your serialized data. This can't be fixed.

The only modifications that are possible are changing scalar values in-place. Allocations will allocate from the heap and will lead to dangling pointers in the data serialized in the file.

Should I serialize data from disk, copy it to memory and, after changing it, serialize it back?

Yes: read data from disk, modify it in-memory and write it back to another file. Then replace the original file (swap new vs old).

felixguendling avatar Feb 05 '21 09:02 felixguendling

I added support for MODIFY on windows. However, this should not be used for changing serialized data beyond simple scalar modifications.

felixguendling avatar Feb 05 '21 09:02 felixguendling

Thanks a lot, I think it's better to cover this issue in the documentation.

BinaryCat17 avatar Feb 05 '21 11:02 BinaryCat17

added a note to https://github.com/felixguendling/cista/wiki/Installation-and-Usage

felixguendling avatar Dec 23 '22 09:12 felixguendling