Skip to content

Commit

Permalink
Cache memmap in npyarray (#237)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jarno Lintusaari committed Sep 8, 2017
1 parent 24bbbe1 commit 832046a
Showing 1 changed file with 26 additions and 13 deletions.
39 changes: 26 additions & 13 deletions elfi/store.py
Original file line number Diff line number Diff line change
Expand Up @@ -641,28 +641,20 @@ def __init__(self, filename, array=None, truncate=False):
else:
self.fs = open(self.filename, 'w+b')

# Numpy memmap for the file array data
self._memmap = None

if array is not None:
self.append(array)
self.flush()

def __getitem__(self, sl):
"""Return a slice `sl` of data."""
if not self.initialized:
raise IndexError("NpyArray is not initialized")
order = 'F' if self.fortran_order else 'C'
# TODO: do not recreate if nothing has changed
mmap = np.memmap(
self.fs, dtype=self.dtype, shape=self.shape, offset=self.header_length, order=order)
return mmap[sl]
return self.memmap[sl]

def __setitem__(self, sl, value):
"""Set data at slice `sl` to `value`."""
if not self.initialized:
raise IndexError("NpyArray is not initialized")
order = 'F' if self.fortran_order else 'C'
mmap = np.memmap(
self.fs, dtype=self.dtype, shape=self.shape, offset=self.header_length, order=order)
mmap[sl] = value
self.memmap[sl] = value

def __len__(self):
"""Return the length of array."""
Expand Down Expand Up @@ -695,6 +687,20 @@ def append(self, array):
# Only prepare the header bytes, need to be flushed to take effect
self._prepare_header_data()

# Invalidate the memmap
self._memmap = None

@property
def memmap(self):
if not self.initialized:
raise IndexError("NpyArray is not initialized")

if self._memmap is None:
order = 'F' if self.fortran_order else 'C'
self._memmap = np.memmap(self.fs, dtype=self.dtype, shape=self.shape,
offset=self.header_length, order=order)
return self._memmap

def _init_from_file_header(self):
"""Initialize the object from an existing file."""
self.fs.seek(self.HEADER_DATA_SIZE_OFFSET)
Expand Down Expand Up @@ -777,11 +783,16 @@ def truncate(self, length=0):
self.fs.seek(self.header_length + self.size * self.itemsize)
self.fs.truncate()

# Invalidate the memmap
self._memmap = None

def close(self):
"""Close the file."""
if self.initialized:
self._write_header_data()
self.fs.close()
# Invalidate the memmap
self._memmap = None

def clear(self):
"""Truncate the array to 0."""
Expand All @@ -796,6 +807,8 @@ def delete(self):
os.remove(name)
self.fs = None
self.header_length = None
# Invalidate the memmap
self._memmap = None

def flush(self):
"""Flush any changes in memory to array."""
Expand Down

0 comments on commit 832046a

Please sign in to comment.