xerial/larray

Allow prefetching of a range of mapped file

Opened this issue · 0 comments

CAFxX commented

In #46 it is requested to expose madvise() but the OP does not specify what they are trying to accomplish. One of the possible uses, and a very important one when mapping files significantly larger than the page cache, is the ability to communicate to the OS that the application is going to need to access a specific range of the file, so that the OS has 1) the ability to prefetch the range or, at the very least, 2) enough information to issue efficient reads for the whole range instead of paging in individual pages (this can happen especially if the mapping is used for random accesses, in which case it is likely that the OS will turn off any page cache prefetching mechanism for that file).

To address this, I would like to propose the addition of one of the following two methods to MMapBuffer:

    /**
     * Attempts to prefetch the specified range in memory so that followup
     * accesses do not incur I/O. This method is best-effort: there are no
     * guarantees that the JVM and the OS will honor this request, and even
     * if they do there are no guarantees for how long the data in the range
     * will remain in memory before being paged out. When this method
     * returns the prefetch operation may be still ongoing.
     * You should only attempt to prefetch data you are going to access soon,
     * and most likely length should be significantly smaller than the size of
     * the page cache.
     */
    public void prefetch(long offset, long length) {
        // ...
    }

    /**
     * Attempts to prefetch the specified range in memory so that followup
     * accesses do not incur I/O. This method is best-effort: there are no
     * guarantees that the JVM and the OS will honor this request, and even
     * if they do there are no guarantees for how long the data in the range
     * will remain in memory before being paged out. When this method
     * returns the prefetch operation may be still ongoing.
     * You should only attempt to prefetch data you are going to access soon,
     * and most likely length should be significantly smaller than the size of
     * the page cache.
     * This method returns false if the prefetch request could not be issued
     * to the OS; true otherwise. Note that the best-effort behavior described
     * above applies even if prefetch returns true.
     */
    public bool prefetch(long offset, long length) {
        // ...
    }

Note that an acceptable implementation of both (e.g. for platforms where prefetching is not supported) is just a no-op implementation.

On Unix, this could map to posix_madvise(rawAddr+offset, length, POSIX_MADV_WILLNEED).
On Windows, this could map to PrefetchVirtualMemory.

This could potentially be useful also for anonymous mappings, but this is less of a concern in our case.