Struct vmap::Options[][src]

pub struct Options<T: FromPtr> { /* fields omitted */ }
Expand description

Options and flags which can be used to configure how a map is allocated.

This builder exposes the ability to configure how a Map or a MapMut is allocated. These options can be used to either map a file or allocate an anonymous memory region. For file-based operations, a std::fs::OpenOptions value is maintained to match the desired abilities between the mapping and the underlying resource. This allows the creation, truncation, and resizing of a file to be coordinated when allocating a named map. For both mapping and anonymous allocations the option can also specify an offset and a mapping length.

The T must either be a Map or a MapMut. Generally, this will be created by Map::with_options() or MapMut::with_options(), then chain calls to methods to set each option, then call either .open(), .map(), or .alloc(). This will return a Result with the correct Map or MapMut inside. Additionally, there are .open_if() and .map_if() variations which instead return a Result containing an Option<T>. These return Ok(None) if the attempted range lies outside of the file rather than an Err.

Without specifying a size, the options defaults to either the full size of the file when using .open() or .map(). When using .alloc(), the default size will be a single unit of allocation granularity.

Implementations

Creates a new Options value with a default state.

Generally, Map::with_options() or MapMut::with_options() is the preferred way to create options.

Sets the option for write access.

This is applied automatically when using MapMut::with_options(). This can be useful with Map when there is a future intent to call Map::into_map_mut().

Examples
use vmap::Map;

let (map, file) = Map::with_options().open("README.md")?;
assert!(map.into_map_mut().is_err());

let (map, file) = Map::with_options().write().open("README.md")?;
assert!(map.into_map_mut().is_ok());

Sets the option for copy-on-write access.

This efficiently implements a copy to an underlying modifiable resource. The allocated memory can be shared between multiple unmodified instances, and the copy operation is deferred until the first write. When used for an anonymous allocation, the deffered copy can be used in a child process.

Examples
use vmap::MapMut;

let (mut map1, file) = MapMut::with_options().copy().open("README.md")?;
let (mut map2, _) = MapMut::with_options().copy().open("README.md")?;
let first = map1[0];

map1[0] = b'X';

assert_eq!(first, map2[0]);

Sets the option to create a new file, or open it if it already exists.

This only applies when using .open() or .open_if(). In order for the file to be created, .write() access must be used.

Examples
use vmap::{Map, MapMut};
use std::path::PathBuf;

let path: PathBuf = /* path to file */
let (mut map, file) = MapMut::with_options().create(true).resize(100).open(&path)?;
assert_eq!(100, map.len());
assert_eq!(b"\0\0\0\0", &map[..4]);

map[..4].clone_from_slice(b"test");

let (map, file) = Map::with_options().open(&path)?;
assert_eq!(100, map.len());
assert_eq!(b"test", &map[..4]);

Sets the option to create a new file, failing if it already exists.

This option is useful because it is atomic. Otherwise between checking whether a file exists and creating a new one, the file may have been created by another process (a TOCTOU race condition / attack).

If .create_new(true) is set, .create() and .truncate() are ignored.

This only applies when using .open() or .open_if(). In order for the file to be created, .write() access must be used.

Examples
use vmap::MapMut;
use std::path::PathBuf;

let path: PathBuf = /* path to file */

let (map, file) = MapMut::with_options().create_new(true).resize(10).open(&path)?;
assert_eq!(10, map.len());
assert!(MapMut::with_options().create_new(true).open(&path).is_err());

Sets the option for truncating a previous file.

If a file is successfully opened with this option set it will truncate the file to 0 length if it already exists. Given that the file will now be empty, a .resize() should be used.

In order for the file to be truncated, .write() access must be used.

Examples
use vmap::MapMut;
use std::path::PathBuf;

let path: PathBuf = /* path to file */

{
    let (mut map, file) = MapMut::with_options()
        .create(true)
        .truncate(true)
        .resize(4)
        .open(&path)?;
    assert_eq!(b"\0\0\0\0", &map[..]);
    map[..4].clone_from_slice(b"test");
    assert_eq!(b"test", &map[..]);
}

let (mut map, file) = MapMut::with_options().truncate(true).resize(4).open(&path)?;
assert_eq!(b"\0\0\0\0", &map[..]);

Sets the byte offset into the mapping.

For file-based mappings, the offset defines the starting byte range from the beginning of the resource. This must be within the range of the file.

Examples
use vmap::Map;
use std::path::PathBuf;
use std::str::from_utf8;
use std::fs;

let path: PathBuf = /* path to file */
fs::write(&path, b"this is a test")?;

let (map, file) = Map::with_options().offset(10).open(path)?;
assert_eq!(Ok("test"), from_utf8(&map[..]));

Sets the byte length extent of the mapping.

For file-based mappings, this length must be available in the underlying resource, including any .offset(). When not specified, the default length is implied to be Extent::End.

Length with Extent::End

With this value, the length extent is set to the end of the underlying resource. This is the default if no .len() is applied, but this can be set to override a prior setting if desired.

For anonymous mappings, it is generally preferred to use a different extent strategy. Without setting any other extent, the default length is a single allocation unit of granularity.

Length with Extent::Exact

Using an exact extent option will instruct the map to cover an exact byte length. That is, it will not consider the length of the underlying resource, if any. For file-based mappings, this length must be available in the file. For anonymous mappings, this is the minimum size that will be allocated, however, the resulting map will be sized exactly to this size.

A usize may be used as an Extent::Exact through the usize implementation of Into<Extent>.

use vmap::{Map, MapMut};
use std::path::PathBuf;
use std::str::from_utf8;
use std::fs;

let path: PathBuf = /* path to file */
fs::write(&path, b"this is a test")?;

let (map, file) = Map::with_options()
    .len(4) // or .len(Extent::Exaxt(4))
    .open(&path)?;
assert_eq!(Ok("this"), from_utf8(&map[..]));

let mut anon = MapMut::with_options()
    .len(4)
    .alloc()?;
assert_eq!(4, anon.len());
Length with Extent::Min

The minimum extent strategy creates a mapping that is at least the desired byte length, but may be larger. When applied to a file-based mapping, this ensures that the resulting memory region covers a minimum extent, but otherwise covers to the end of the file. For an anonymous map, this ensures the allocated region meets the minimum size required, but allows accessing the remaining allocated space that would otherwise be unusable.

use vmap::{Extent, Map, MapMut, Size};
use std::path::PathBuf;
use std::str::from_utf8;
use std::fs;

let path: PathBuf = /* path to file */
fs::write(&path, b"this is a test")?;

let (map, file) = Map::with_options()
    .offset(5)
    .len(Extent::Min(4))
    .open(&path)?;
assert_eq!(9, map.len());
assert_eq!(Ok("is a test"), from_utf8(&map[..]));

assert!(
    Map::with_options()
        .len(Extent::Min(100))
        .open_if(&path)?
        .0
        .is_none()
);

let mut anon = MapMut::with_options()
    .len(Extent::Min(2000))
    .alloc()?;
assert_eq!(Size::alloc().size(1), anon.len());
Length with Extent::Max

The maximum extent strategy creates a mapping that is no larger than the desired byte length, but may be smaller. When applied to a file- based mapping, this will ensure that the resulting

use vmap::{Extent, Map, MapMut};
use std::path::PathBuf;
use std::str::from_utf8;
use std::fs;

let path: PathBuf = /* path to file */
fs::write(&path, b"this is a test")?;

let (map, file) = Map::with_options()
   .offset(5)
   .len(Extent::Max(100))
   .open(&path)?;
assert_eq!(9, map.len());
assert_eq!(Ok("is a test"), from_utf8(&map[..]));

let mut anon = MapMut::with_options()
    .len(Extent::Max(2000))
    .alloc()?;
assert_eq!(2000, anon.len());

Sets the option to resize the file prior to mapping.

When mapping to a file using .open(), .open_if(), .map(), or .map_if() this options conditionally adjusts the length of the underlying resource to the desired size by calling .set_len() on the File.

In order for the file to be resized, .write() access must be used.

This has no affect on anonymous mappings.

Resize with Extent::End

This implies resizing to the current size of the file. In other words, no resize is performed, and this is the default strategy.

Resize with Extent::Exact

Using an exact extent option will instruct the map to cover an exact byte length. That is, it will not consider the length of the underlying resource, if any. For file-based mappings, this length must be available in the file. For anonymous mappings, this is the minimum size that will be allocated, however, the resulting map will be sized exactly to this size.

A usize may be used as an Extent::Exact through the usize implementation of Into<Extent>.

use vmap::Map;
use std::path::PathBuf;
use std::str::from_utf8;
use std::fs;

let path: PathBuf = /* path to file */
fs::write(&path, b"this is a test")?;

let (map, file) = Map::with_options()
    .write()
    .resize(7) // or .resize(Extent::Exact(7))
    .open(&path)?;
assert_eq!(7, map.len());
assert_eq!(Ok("this is"), from_utf8(&map[..]));
Resize with Extent::Min

The minimum extent strategy resizes the file to be at least the desired byte length, but may be larger. If the file is already equal to or larger than the extent, no resize is performed.

use vmap::{Extent, Map};
use std::path::PathBuf;
use std::str::from_utf8;
use std::fs;

let path: PathBuf = /* path to file */

fs::write(&path, b"this")?;

{
    let (map, file) = Map::with_options()
        .write()
        .resize(Extent::Min(7))
        .open(&path)?;
    assert_eq!(7, map.len());
    assert_eq!(Ok("this\0\0\0"), from_utf8(&map[..]));
}

fs::write(&path, b"this is a test")?;

let (map, file) = Map::with_options()
    .write()
    .resize(Extent::Min(7))
    .open(&path)?;
assert_eq!(14, map.len());
assert_eq!(Ok("this is a test"), from_utf8(&map[..]));
Resize with Extent::Max

The maximum extent strategy resizes the file to be no larger than the desired byte length, but may be smaller. If the file is already equal to or smaller than the extent, no resize is performed.

use vmap::{Extent, Map};
use std::path::PathBuf;
use std::str::from_utf8;
use std::fs;

let path: PathBuf = /* path to file */
fs::write(&path, b"this")?;

{
    let (map, file) = Map::with_options()
        .write()
        .resize(Extent::Max(7))
        .open(&path)?;
    assert_eq!(4, map.len());
    assert_eq!(Ok("this"), from_utf8(&map[..]));
}

fs::write(&path, b"this is a test")?;

let (map, file) = Map::with_options()
    .write()
    .resize(Extent::Max(7))
    .open(&path)?;
assert_eq!(7, map.len());
assert_eq!(Ok("this is"), from_utf8(&map[..]));

Opens and maps a file using the current options specified by self.

Unlike .open_if(), when the requested offset or length lies outside of the underlying file, an error is returned.

The returned File can be discarded if no longer needed to .flush() or .map() other regions. This does not need to be kept open in order to use the mapped value.

Examples
use vmap::Map;
use std::path::PathBuf;
use std::fs;

let path: PathBuf = /* path to file */
fs::write(&path, b"this is a test")?;

assert!(Map::with_options().len(4).open(&path).is_ok());
assert!(Map::with_options().len(25).open(&path).is_err());

Opens and maps a file with the options specified by self if the provided byte range is valid.

Unlike .open(), when the requested offset or length lies outside of the underlying file, Ok(None) will be returned rather than an error.

The returned File can be discarded if no longer needed to .flush() or .map() other regions. This does not need to be kept open in order to use the mapped value.

Examples
use vmap::Map;
use std::path::PathBuf;
use std::fs;

let path: PathBuf = /* path to file */
fs::write(&path, b"this is a test")?;

assert!(Map::with_options().len(4).open_if(&path).is_ok());

let result = Map::with_options().len(25).open_if(&path);
assert!(result.is_ok());
assert!(result.unwrap().0.is_none());

Maps an open File using the current options specified by self.

Unlike .map_if(), when the requested offset or length lies outside of the underlying file, an error is returned.

Examples
use vmap::Map;
use std::path::PathBuf;
use std::fs::OpenOptions;

let path: PathBuf = /* path to file */
let f = OpenOptions::new()
    .read(true)
    .write(true)
    .create(true)
    .open(path)?;
f.set_len(8)?;

assert!(Map::with_options().len(4).map(&f).is_ok());
assert!(Map::with_options().len(25).map(&f).is_err());

Maps an open File with the options specified by self if the provided byte range is valid.

Unlike .map(), when the requested offset or length lies outside of the underlying file, Ok(None) will be returned rather than an error.

Examples
use vmap::Map;
use std::path::PathBuf;
use std::fs::OpenOptions;

let path: PathBuf = /* path to file */
let f = OpenOptions::new()
    .read(true)
    .write(true)
    .create(true)
    .open(path)?;
f.set_len(8)?;

assert!(Map::with_options().len(4).map_if(&f).is_ok());

let result = Map::with_options().len(25).map_if(&f);
assert!(result.is_ok());
assert!(result.unwrap().is_none());

Creates an anonymous allocation using the options specified by self.

Examples
use vmap::{Extent, MapMut};

let map = MapMut::with_options().len(Extent::Min(500)).alloc()?;
assert!(map.len() >= 500);

Trait Implementations

Returns the “default value” for a type. Read more

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Performs the conversion.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.