Skip to main content

clone_solana_ledger/
blockstore_options.rs

1use {
2    crate::blockstore_db::{default_num_compaction_threads, default_num_flush_threads},
3    rocksdb::{DBCompressionType as RocksCompressionType, DBRecoveryMode},
4    std::num::NonZeroUsize,
5};
6
7/// The subdirectory under ledger directory where the Blockstore lives
8pub const BLOCKSTORE_DIRECTORY_ROCKS_LEVEL: &str = "rocksdb";
9
10#[derive(Debug, Clone)]
11pub struct BlockstoreOptions {
12    // The access type of blockstore. Default: Primary
13    pub access_type: AccessType,
14    // Whether to open a blockstore under a recovery mode. Default: None.
15    pub recovery_mode: Option<BlockstoreRecoveryMode>,
16    // When opening the Blockstore, determines whether to error or not if the
17    // desired open file descriptor limit cannot be configured. Default: true.
18    pub enforce_ulimit_nofile: bool,
19    pub column_options: LedgerColumnOptions,
20    pub num_rocksdb_compaction_threads: NonZeroUsize,
21    pub num_rocksdb_flush_threads: NonZeroUsize,
22}
23
24impl Default for BlockstoreOptions {
25    /// The default options are the values used by [`Blockstore::open`].
26    ///
27    /// [`Blockstore::open`]: crate::blockstore::Blockstore::open
28    fn default() -> Self {
29        Self {
30            access_type: AccessType::Primary,
31            recovery_mode: None,
32            enforce_ulimit_nofile: true,
33            column_options: LedgerColumnOptions::default(),
34            num_rocksdb_compaction_threads: default_num_compaction_threads(),
35            num_rocksdb_flush_threads: default_num_flush_threads(),
36        }
37    }
38}
39
40impl BlockstoreOptions {
41    pub fn default_for_tests() -> Self {
42        Self {
43            // No need to enforce the limit in tests
44            enforce_ulimit_nofile: false,
45            ..BlockstoreOptions::default()
46        }
47    }
48}
49
50#[derive(Clone, Debug, PartialEq, Eq)]
51pub enum AccessType {
52    /// Primary (read/write) access; only one process can have Primary access.
53    Primary,
54    /// Primary (read/write) access with RocksDB automatic compaction disabled.
55    PrimaryForMaintenance,
56    /// Secondary (read) access; multiple processes can have Secondary access.
57    /// Additionally, Secondary access can be obtained while another process
58    /// already has Primary access.
59    Secondary,
60}
61
62#[derive(Debug, Clone)]
63pub enum BlockstoreRecoveryMode {
64    TolerateCorruptedTailRecords,
65    AbsoluteConsistency,
66    PointInTime,
67    SkipAnyCorruptedRecord,
68}
69
70impl From<&str> for BlockstoreRecoveryMode {
71    fn from(string: &str) -> Self {
72        match string {
73            "tolerate_corrupted_tail_records" => {
74                BlockstoreRecoveryMode::TolerateCorruptedTailRecords
75            }
76            "absolute_consistency" => BlockstoreRecoveryMode::AbsoluteConsistency,
77            "point_in_time" => BlockstoreRecoveryMode::PointInTime,
78            "skip_any_corrupted_record" => BlockstoreRecoveryMode::SkipAnyCorruptedRecord,
79            bad_mode => panic!("Invalid recovery mode: {bad_mode}"),
80        }
81    }
82}
83
84impl From<BlockstoreRecoveryMode> for DBRecoveryMode {
85    fn from(brm: BlockstoreRecoveryMode) -> Self {
86        match brm {
87            BlockstoreRecoveryMode::TolerateCorruptedTailRecords => {
88                DBRecoveryMode::TolerateCorruptedTailRecords
89            }
90            BlockstoreRecoveryMode::AbsoluteConsistency => DBRecoveryMode::AbsoluteConsistency,
91            BlockstoreRecoveryMode::PointInTime => DBRecoveryMode::PointInTime,
92            BlockstoreRecoveryMode::SkipAnyCorruptedRecord => {
93                DBRecoveryMode::SkipAnyCorruptedRecord
94            }
95        }
96    }
97}
98
99/// Options for LedgerColumn.
100/// Each field might also be used as a tag that supports group-by operation when
101/// reporting metrics.
102#[derive(Default, Debug, Clone)]
103pub struct LedgerColumnOptions {
104    // Determine the way to compress column families which are eligible for
105    // compression.
106    pub compression_type: BlockstoreCompressionType,
107
108    // Control how often RocksDB read/write performance samples are collected.
109    // If the value is greater than 0, then RocksDB read/write perf sample
110    // will be collected once for every `rocks_perf_sample_interval` ops.
111    pub rocks_perf_sample_interval: usize,
112}
113
114impl LedgerColumnOptions {
115    pub fn get_compression_type_string(&self) -> &'static str {
116        match self.compression_type {
117            BlockstoreCompressionType::None => "None",
118            BlockstoreCompressionType::Snappy => "Snappy",
119            BlockstoreCompressionType::Lz4 => "Lz4",
120            BlockstoreCompressionType::Zlib => "Zlib",
121        }
122    }
123}
124
125#[derive(Debug, Clone)]
126pub enum BlockstoreCompressionType {
127    None,
128    Snappy,
129    Lz4,
130    Zlib,
131}
132
133impl Default for BlockstoreCompressionType {
134    fn default() -> Self {
135        Self::None
136    }
137}
138
139impl BlockstoreCompressionType {
140    pub(crate) fn to_rocksdb_compression_type(&self) -> RocksCompressionType {
141        match self {
142            Self::None => RocksCompressionType::None,
143            Self::Snappy => RocksCompressionType::Snappy,
144            Self::Lz4 => RocksCompressionType::Lz4,
145            Self::Zlib => RocksCompressionType::Zlib,
146        }
147    }
148}