Skip to main content

liquid_cache_common/
io_mode.rs

1use std::{fmt::Display, str::FromStr};
2
3use serde::Serialize;
4
5/// Mode in which Disk IO is done (direct IO or page cache)
6#[derive(Debug, Clone, Copy, PartialEq, Default, Serialize)]
7pub enum IoMode {
8    /// Uses io_uring and bypass the page cache (uses direct IO), only available on Linux
9    #[serde(rename = "uring-direct")]
10    UringDirect,
11
12    /// Uses io_uring and uses OS's page cache, only available on Linux
13    #[serde(rename = "uring")]
14    Uring,
15
16    /// Uses multiple async io_uring instances leased per future, only available on Linux
17    #[serde(rename = "uring-multi-async")]
18    #[cfg_attr(target_os = "linux", default)]
19    UringMultiAsync,
20
21    /// Uses io_uring with a single shared ring on the runtime thread, only available on Linux
22    #[serde(rename = "uring-shared")]
23    UringShared,
24
25    /// Uses io_uring on the calling thread and blocks until completion.
26    #[serde(rename = "uring-blocking")]
27    UringBlocking,
28
29    /// Uses rust's std::fs::File, this is blocking IO.
30    /// On Linux, this is essentially `pread/pwrite`
31    /// This is the default on non-Linux platforms.
32    #[cfg_attr(not(target_os = "linux"), default)]
33    #[serde(rename = "std-blocking")]
34    StdBlocking,
35
36    /// Uses tokio's async IO, this is non-blocking IO, but quite slow: <https://github.com/tokio-rs/tokio/issues/3664>
37    #[serde(rename = "tokio")]
38    TokioIO,
39
40    /// Use rust's std::fs::File, but will try to `spawn_blocking`, just like `object_store` does:
41    /// <https://github.com/apache/arrow-rs-object-store/blob/28b2fc563feb44bb3d15718cf58036772334a704/src/datafusion-local.rs#L440-L448>
42    #[serde(rename = "std-spawn-blocking")]
43    StdSpawnBlocking,
44}
45
46impl Display for IoMode {
47    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
48        write!(
49            f,
50            "{}",
51            match self {
52                IoMode::Uring => "uring",
53                IoMode::UringDirect => "uring-direct",
54                IoMode::UringMultiAsync => "uring-multi-async",
55                IoMode::UringShared => "uring-shared",
56                IoMode::UringBlocking => "uring-blocking",
57                IoMode::StdBlocking => "std-blocking",
58                IoMode::TokioIO => "tokio",
59                IoMode::StdSpawnBlocking => "std-spawn-blocking",
60            }
61        )
62    }
63}
64
65impl FromStr for IoMode {
66    type Err = String;
67
68    fn from_str(s: &str) -> Result<Self, Self::Err> {
69        Ok(match s {
70            "uring-direct" => IoMode::UringDirect,
71            "uring" => IoMode::Uring,
72            "uring-multi-async" => IoMode::UringMultiAsync,
73            "uring-shared" => IoMode::UringShared,
74            "uring-blocking" => IoMode::UringBlocking,
75            "std-blocking" => IoMode::StdBlocking,
76            "tokio" => IoMode::TokioIO,
77            "std-spawn-blocking" => IoMode::StdSpawnBlocking,
78            _ => return Err(format!("Invalid IO mode: {s}")),
79        })
80    }
81}