pub struct SwapFile<'a> {
file: &'a File,
file_mmap: MemoryMapping,
page_states: Vec<PageState>,
file_states: FilePageStates,
cursor_mlock: usize,
min_possible_present_idx_file: usize,
}
Expand description
SwapFile stores active pages in a memory region.
This shares the swap file with other regions and creates mmap corresponding range in the file.
TODO(kawasin): The file structure is straightforward and is not optimized yet. Each page in the file corresponds to the page in the memory region.
Fields§
§file: &'a File
§file_mmap: MemoryMapping
§page_states: Vec<PageState>
§file_states: FilePageStates
§cursor_mlock: usize
§min_possible_present_idx_file: usize
Implementations§
source§impl<'a> SwapFile<'a>
impl<'a> SwapFile<'a>
sourcepub fn page_content(
&self,
idx_page: usize,
allow_cleared: bool
) -> Result<Option<VolatileSlice<'_>>, Error>
pub fn page_content( &self, idx_page: usize, allow_cleared: bool ) -> Result<Option<VolatileSlice<'_>>, Error>
Returns a content of the page corresponding to the index if it is present.
Returns Option::None if no content in the file.
Returns Error::OutOfRange if the idx
is out of range.
§Arguments
idx_page
- the index of the page from the head of the pages.
sourcepub fn lock_and_async_prefetch(
&mut self,
max_pages: usize
) -> Result<usize, Error>
pub fn lock_and_async_prefetch( &mut self, max_pages: usize ) -> Result<usize, Error>
Start readahead the swap file into the page cache from the head.
This also mlock2(2)
the pages not to be dropped again after populated. This does not block
the caller thread by I/O wait because:
mlock2(2)
is executed withMLOCK_ONFAULT
.MADV_WILLNEED
is the same asreadahead(2)
which triggers the readahead background.- However Linux has a bug that
readahead(2)
(and alsoMADV_WILLNEED
) may block due to reading the filesystem metadata.
- However Linux has a bug that
This returns the number of consecutive pages which are newly mlock(2)ed. Returning 0
means
that there is no more data to be mlock(2)ed in this file.
The caller must track the number of pages mlock(2)ed not to mlock(2) more pages than
RLIMIT_MEMLOCK
if it does not have CAP_IPC_LOCK
.
§Arguments
max_pages
- The maximum number of pages to be mlock(2)ed at once.
sourcepub fn clear_range(
&mut self,
idx_page_range: Range<usize>
) -> Result<usize, Error>
pub fn clear_range( &mut self, idx_page_range: Range<usize> ) -> Result<usize, Error>
Mark the pages in the file corresponding to the index as cleared.
The contents on the swap file are preserved and will be reused by
SwapFile::mark_as_present()
and reduce disk I/O.
If the pages are mlock(2)ed, unlock them before MADV_DONTNEED. This returns the number of pages munlock(2)ed.
§Arguments
idx_page_range
- The indices of consecutive pages to be cleared. All the pages must be present and consecutive in the compacted file.
sourcepub fn free_range(
&mut self,
idx_page_range: Range<usize>
) -> Result<usize, Error>
pub fn free_range( &mut self, idx_page_range: Range<usize> ) -> Result<usize, Error>
Free the pages corresponding to the given range in the file.
If the pages are mlock(2)ed, unlock them. This returns the number of pages munlock(2)ed.
§Arguments
idx_page_range
- The indices of consecutive pages to be freed. This may contains non-present pages.
sourcepub fn clear_mlock(&mut self) -> Result<(), Error>
pub fn clear_mlock(&mut self) -> Result<(), Error>
munlock(2) pages if there are mlock(2)ed pages in the mmap and reset the internal cursor for mlock(2) tracking.
sourcepub fn mark_as_present(&mut self, idx_page: usize) -> Result<(), Error>
pub fn mark_as_present(&mut self, idx_page: usize) -> Result<(), Error>
Mark the page as present on the file.
The content on the swap file on previous SwapFile::write_to_file()
is reused.
§Arguments
idx
- the index of the page from the head of the pages.
sourcepub fn write_to_file(
&mut self,
idx_page: usize,
mem_slice: &[u8]
) -> Result<(), Error>
pub fn write_to_file( &mut self, idx_page: usize, mem_slice: &[u8] ) -> Result<(), Error>
Writes the contents to the swap file.
§Arguments
idx_page
- the index of the head page of the content from the head of the pages.mem_slice
- the page content(s). this can be more than 1 page. the size must align with the pagesize.
sourcepub fn first_data_range(&mut self, max_pages: usize) -> Option<Range<usize>>
pub fn first_data_range(&mut self, max_pages: usize) -> Option<Range<usize>>
Returns the first range of indices of consecutive pages present in the swap file.
§Arguments
max_pages
- the max size of the returned chunk even if the chunk of consecutive present pages is longer than this.
sourcepub fn get_slice(
&self,
idx_page_range: Range<usize>
) -> Result<VolatileSlice<'_>, Error>
pub fn get_slice( &self, idx_page_range: Range<usize> ) -> Result<VolatileSlice<'_>, Error>
Returns the [VolatileSlice] corresponding to the indices regardless of whether the pages are present or not.
If the range is out of the region, this returns Error::OutOfRange.
§Arguments
idx_page_range
- the indices of the pages. All the pages must be present and consecutive in the compacted file.
sourcepub fn present_pages(&self) -> usize
pub fn present_pages(&self) -> usize
Returns the count of present pages in the swap file.
sourcefn convert_idx_page_range_to_idx_file(
&self,
idx_page_range: Range<usize>
) -> Result<Range<usize>, Error>
fn convert_idx_page_range_to_idx_file( &self, idx_page_range: Range<usize> ) -> Result<Range<usize>, Error>
Convert the index range to corresponding index range of compacted file.
This validates that the idx_page_range
satisfy:
idx_page_range
has corresponding page in the file.- corresponding index range in the file is consecutive.