+_mincore = getattr(_helpers, 'mincore', None)
+if _mincore:
+ # ./configure ensures that we're on Linux if MINCORE_INCORE isn't defined.
+ MINCORE_INCORE = getattr(_helpers, 'MINCORE_INCORE', 1)
+
+ _fmincore_chunk_size = None
+ def _set_fmincore_chunk_size():
+ global _fmincore_chunk_size
+ pref_chunk_size = 64 * 1024 * 1024
+ chunk_size = sc_page_size
+ if (sc_page_size < pref_chunk_size):
+ chunk_size = sc_page_size * (pref_chunk_size // sc_page_size)
+ _fmincore_chunk_size = chunk_size
+
+ def fmincore(fd):
+ """Return the mincore() data for fd as a bytearray whose values can be
+ tested via MINCORE_INCORE, or None if fd does not fully
+ support the operation."""
+ st = os.fstat(fd)
+ if (st.st_size == 0):
+ return bytearray(0)
+ if not _fmincore_chunk_size:
+ _set_fmincore_chunk_size()
+ pages_per_chunk = _fmincore_chunk_size // sc_page_size;
+ page_count = (st.st_size + sc_page_size - 1) // sc_page_size;
+ chunk_count = (st.st_size + _fmincore_chunk_size - 1) // _fmincore_chunk_size
+ result = bytearray(page_count)
+ for ci in compat.range(chunk_count):
+ pos = _fmincore_chunk_size * ci;
+ msize = min(_fmincore_chunk_size, st.st_size - pos)
+ try:
+ m = mmap.mmap(fd, msize, mmap.MAP_PRIVATE, 0, 0, pos)
+ except mmap.error as ex:
+ if ex.errno == errno.EINVAL or ex.errno == errno.ENODEV:
+ # Perhaps the file was a pipe, i.e. "... | bup split ..."
+ return None
+ raise ex
+ try:
+ _mincore(m, msize, 0, result, ci * pages_per_chunk)
+ except OSError as ex:
+ if ex.errno == errno.ENOSYS:
+ return None
+ raise
+ return result
+
+
+def parse_timestamp(epoch_str):
+ """Return the number of nanoseconds since the epoch that are described
+by epoch_str (100ms, 100ns, ...); when epoch_str cannot be parsed,
+throw a ValueError that may contain additional information."""
+ ns_per = {'s' : 1000000000,
+ 'ms' : 1000000,
+ 'us' : 1000,
+ 'ns' : 1}
+ match = re.match(r'^((?:[-+]?[0-9]+)?)(s|ms|us|ns)$', epoch_str)
+ if not match:
+ if re.match(r'^([-+]?[0-9]+)$', epoch_str):
+ raise ValueError('must include units, i.e. 100ns, 100ms, ...')
+ raise ValueError()
+ (n, units) = match.group(1, 2)
+ if not n:
+ n = 1
+ n = int(n)
+ return n * ns_per[units]
+
+