Skip to content

mmap-backed persistent ZFP arrays #59

Open
@jvo203

Description

@jvo203

It would be nice to be able to save to/restore compressed ZFP arrays from mmapped files. At present a crude workaround has been applied to zfparray.h:

added three extra variables to the array class:
std::string storage; //persistent storage via mmap
bool is_mmapped;
size_t storage_size;

and then alloc() / free() have been changed too:

// allocate memory for compressed data
void alloc(bool clear = true)
{
bytes = blocks * blkbits / CHAR_BIT;
printf("zfp::array3::alloc<clear:%d, storage:%s, bytes:%zu>\n", clear, storage.c_str(), bytes);
if (bytes > 1 && storage != "")
{
//try mmap first
int fd = open(storage.c_str(), O_RDWR | O_CREAT, (mode_t)0600);
if (fd != -1)
{
int stat = ftruncate64(fd, bytes);
if (!stat)
{
void *buffer = mmap(0, bytes, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

      if (buffer != MAP_FAILED)
      {
        data = (uchar *)buffer;
        is_mmapped = true;
        storage_size = bytes;
        printf("zfp::array3::alloc<mmap OK>.\n");
      }
      else
        perror("mmap");
    }
    else
    {
      perror("ftruncate64");
    }
    close(fd);
  }
}

if (!is_mmapped)
{
  reallocate(data, bytes, 0x100u);
  if (clear)
    std::fill(data, data + bytes, 0);
}
stream_close(zfp->stream);
zfp_stream_set_bit_stream(zfp, stream_open(data, bytes));
clear_cache();

}

// free memory associated with compressed data
void free()
{
nx = ny = nz = 0;
bx = by = bz = 0;
blocks = 0;
stream_close(zfp->stream);
zfp_stream_set_bit_stream(zfp, 0);
bytes = 0;
if (!is_mmapped)
deallocate(data);
else
{
if (data != NULL)
{
if (munmap(data, storage_size) == -1)
perror("un-mapping error");
else
printf("zfp::array3::free.\n");

    storage_size = 0;
    is_mmapped = false;
  };
};
data = 0;
deallocate(shape);
shape = 0;

}

This is a "quick&dirty" workaround. A more elegant ZFP-wide solution would be much nicer.

the array3 constructor in zfparray3.h has been modified slightly too:
array3(uint nx, uint ny, uint nz, double rate, const Scalar* p = 0, size_t csize = 0, std::string _storage = std::string("")) :
array(3, Codec::type),
cache(lines(csize, nx, ny, nz))
{
storage = _storage;
is_mmapped = false;
storage_size = 0;
set_rate(rate);
resize(nx, ny, nz, p == 0);
if (p)
set(p);
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions