+def _fadvise_pages_done(fd, first_page, count):
+ assert(first_page >= 0)
+ assert(count >= 0)
+ if count > 0:
+ _helpers.fadvise_done(fd,
+ first_page * sc_page_size,
+ count * sc_page_size)
+
+
+def _nonresident_page_regions(status_bytes, incore_mask, max_region_len=None):
+ """Return (start_page, count) pairs in ascending start_page order for
+ each contiguous region of nonresident pages indicated by the
+ mincore() status_bytes. Limit the number of pages in each region
+ to max_region_len."""
+ assert(max_region_len is None or max_region_len > 0)
+ start = None
+ for i, x in enumerate(status_bytes):
+ in_core = x & incore_mask
+ if start is None:
+ if not in_core:
+ start = i
+ else:
+ count = i - start
+ if in_core:
+ yield (start, count)
+ start = None
+ elif max_region_len and count >= max_region_len:
+ yield (start, count)
+ start = i
+ if start is not None:
+ yield (start, len(status_bytes) - start)
+
+
+def _uncache_ours_upto(fd, offset, first_region, remaining_regions):
+ """Uncache the pages of fd indicated by first_region and
+ remaining_regions that are before offset, where each region is a
+ (start_page, count) pair. The final region must have a start_page
+ of None."""
+ rstart, rlen = first_region
+ while rstart is not None and (rstart + rlen) * sc_page_size <= offset:
+ _fadvise_pages_done(fd, rstart, rlen)
+ rstart, rlen = next(remaining_regions, (None, None))
+ return (rstart, rlen)
+
+