Skip to content

Commit

Permalink
ref(byteview): Expose API to apply access hints
Browse files Browse the repository at this point in the history
  • Loading branch information
Dav1dde committed Mar 5, 2025
1 parent 64379db commit 1686bd8
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 0 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## Unreleased

**Features**

- Expose API to apply access pattern hints to a `ByteView`.([#899](https://github.com/getsentry/symbolic/pull/899)).

## 12.13.2

**Fixes**
Expand Down
69 changes: 69 additions & 0 deletions symbolic-common/src/byteview.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,37 @@ impl<'a> ByteView<'a> {
pub fn as_slice(&self) -> &[u8] {
self.backing.deref()
}

/// Applies a [`AccessPattern`] hint to the backing storage.
///
/// A hint can be applied when the predominantly access pattern
/// for this byte view is known.
///
/// Applying the wrong hint may have significant effects on performance.
///
/// Hints are applied on best effort basis, not all platforms
/// support the same hints, not all backing storages support
/// hints.
///
/// # Example
///
/// ```
/// use std::io::Write;
/// use symbolic_common::{ByteView, AccessPattern};
///
/// fn main() -> Result<(), std::io::Error> {
/// let mut file = tempfile::tempfile()?;
/// let view = ByteView::map_file_ref(&file)?;
/// let _ = view.hint(AccessPattern::Random);
/// Ok(())
/// }
/// ```
pub fn hint(&self, hint: AccessPattern) -> Result<(), io::Error> {
match self.backing.deref() {
ByteViewBacking::Buf(_) => Ok(()),
ByteViewBacking::Mmap(mmap) => mmap.advise(hint.to_madvise()),
}
}
}

impl AsRef<[u8]> for ByteView<'_> {
Expand All @@ -253,6 +284,44 @@ impl Deref for ByteView<'_> {

unsafe impl StableDeref for ByteView<'_> {}

/// Values supported by [`ByteView::hint`].
///
/// This is largely an abstraction over [`madvise(2)`] and [`fadvise(2)`].
///
/// [`madvise(2)`]: https://man7.org/linux/man-pages/man2/madvise.2.html
/// [`fadvise(2)`]: https://man7.org/linux/man-pages/man2/posix_fadvise.2.html
#[derive(Debug, Default)]
pub enum AccessPattern {
/// No special treatment.
///
/// The operating system is in full control of the buffer,
/// a generally good default.
///
/// This is the default.
#[default]
Normal,
/// Expect access to be random.
///
/// Read ahead might be less useful than normally.
Rnadom,
/// Expect access to be in sequential order, read ahead might be very useful.
/// After reading data there is a high chance it will not be accessed again
/// and can be aggressively freed.
Sequential,
}

impl AccessPattern {
fn to_madvise(self) -> memmap2::Advice {
match self {
AccessPattern::Normal => memmap2::Advice::Normal,
AccessPattern::Rnadom => memmap2::Advice::Random,
AccessPattern::Sequential => memmap2::Advice::Sequential,
}
}
}



#[cfg(test)]
mod tests {
use super::*;
Expand Down

0 comments on commit 1686bd8

Please sign in to comment.