1use std::path::PathBuf;
2
3use clap::{Args, Parser, Subcommand};
4
5pub const DEFAULT_PAYLOAD_BYTES: usize = 1024 * 1024 * 1024;
6pub const DEFAULT_CHUNK_BYTES: usize = 8 * 1024 * 1024;
7pub const DEFAULT_MEMFD_BYTES: u64 = 5 * 1024 * 1024 * 1024;
8pub const DEFAULT_MARKER: &str = "TRACER_BULLET_SUCCESS";
9pub const DEFAULT_RECORDS: u64 = 1_000_000;
10pub const DEFAULT_MODULE_D_TARGET_PATH: &str = "/dev/tracer-block";
11pub const DEFAULT_MODULE_D_GROUP_BYTES: usize = 16 * 1024 * 1024;
12pub const DEFAULT_MODULE_D_REQUEST_BYTES: usize = 256 * 1024;
13pub const DEFAULT_MODULE_D_PRODUCERS: usize = 4;
14pub const DEFAULT_MODULE_D_SEED: u64 = 0xD00D_FEED_CAFE_BABE;
15pub const DEFAULT_MODULE_E_INDEX_PATH: &str = "/tmp/tracer-bullet-module-e.fst";
16pub const DEFAULT_MODULE_F_LISTEN_ADDR: &str = "0.0.0.0:8080";
17pub const DEFAULT_MODULE_F_TARGET_PATH: &str = "/dev/tracer-block";
18pub const DEFAULT_MODULE_F_WORKERS: usize = 8;
19pub const DEFAULT_MODULE_F_GROUP_BYTES: usize = 16 * 1024 * 1024;
20pub const DEFAULT_MODULE_F_COMPACTION_THRESHOLD: usize = 250_000;
21pub const DEFAULT_MODULE_F_FLUSH_INTERVAL_MS: u64 = 8;
22pub const DEFAULT_MODULE_F_BUCKET: &str = "nexus";
23pub const DEFAULT_MODULE_F_ACCESS_KEY: &str = "AKIAtracerbullet";
24pub const DEFAULT_MODULE_F_SECRET_KEY: &str = "SECRETtracerbullet";
25
26#[cfg(feature = "dev-mode")]
27pub const DEFAULT_MODULE_D_TOTAL_BYTES: u64 = 2 * 1024 * 1024 * 1024;
28#[cfg(not(feature = "dev-mode"))]
29pub const DEFAULT_MODULE_D_TOTAL_BYTES: u64 = 50 * 1024 * 1024 * 1024;
30
31#[cfg(feature = "dev-mode")]
32pub const DEFAULT_MODULE_E_KEYS: u64 = 2_000_000;
33#[cfg(not(feature = "dev-mode"))]
34pub const DEFAULT_MODULE_E_KEYS: u64 = 50_000_000;
35
36#[cfg(feature = "dev-mode")]
37pub const DEFAULT_MODULE_E_LOOKUPS: u64 = 20_000;
38#[cfg(not(feature = "dev-mode"))]
39pub const DEFAULT_MODULE_E_LOOKUPS: u64 = 100_000;
40
41#[cfg(feature = "dev-mode")]
42pub const DEFAULT_MODULE_E_LIST_QUERIES: u64 = 20_000;
43#[cfg(not(feature = "dev-mode"))]
44pub const DEFAULT_MODULE_E_LIST_QUERIES: u64 = 100_000;
45
46#[derive(Debug, Parser)]
47#[command(
48 name = "tracer-bullet",
49 version,
50 about = "Tracer Bullet prototype runner"
51)]
52pub struct Cli {
53 #[command(subcommand)]
54 pub command: Command,
55}
56
57#[derive(Debug, Subcommand)]
58pub enum Command {
59 ModuleA(ModuleAArgs),
60 ModuleB(ModuleBArgs),
61 ModuleCWrite(ModuleCWriteArgs),
62 ModuleCRead(ModuleCReadArgs),
63 ModuleDAppend(ModuleDAppendArgs),
64 ModuleEFst(ModuleEFstArgs),
65 ModuleETrie(ModuleETrieArgs),
66 ModuleECompare(ModuleECompareArgs),
67 ModuleFServe(ModuleFServeArgs),
68 #[command(name = "module-b-receiver-internal", hide = true)]
69 ModuleBReceiverInternal(ModuleBReceiverInternalArgs),
70}
71
72#[derive(Debug, Clone, Args)]
73pub struct ModuleAArgs {
74 #[arg(long, default_value_t = DEFAULT_PAYLOAD_BYTES)]
75 pub payload_bytes: usize,
76 #[arg(long, default_value_t = DEFAULT_CHUNK_BYTES)]
77 pub chunk_bytes: usize,
78 #[arg(long)]
79 pub json: bool,
80}
81
82#[derive(Debug, Clone, Args)]
83pub struct ModuleBArgs {
84 #[arg(long, default_value_t = DEFAULT_MEMFD_BYTES)]
85 pub memfd_bytes: u64,
86 #[arg(long)]
87 pub socket_path: Option<PathBuf>,
88 #[arg(long, default_value_t = String::from(DEFAULT_MARKER))]
89 pub marker: String,
90 #[arg(long)]
91 pub json: bool,
92}
93
94#[derive(Debug, Clone, Args)]
95pub struct ModuleBReceiverInternalArgs {
96 #[arg(long)]
97 pub socket_path: PathBuf,
98 #[arg(long)]
99 pub marker: String,
100 #[arg(long)]
101 pub memfd_bytes: u64,
102}
103
104#[derive(Debug, Clone, Args)]
105pub struct ModuleCWriteArgs {
106 #[arg(long, default_value_t = DEFAULT_RECORDS)]
107 pub records: u64,
108 #[arg(long, default_value = "wal.bin")]
109 pub wal_path: PathBuf,
110 #[arg(long)]
111 pub json: bool,
112}
113
114#[derive(Debug, Clone, Args)]
115pub struct ModuleCReadArgs {
116 #[arg(long, default_value = "wal.bin")]
117 pub wal_path: PathBuf,
118 #[arg(long)]
119 pub expect_records: Option<u64>,
120 #[arg(long)]
121 pub json: bool,
122}
123
124#[derive(Debug, Clone, Args)]
125pub struct ModuleDAppendArgs {
126 #[arg(long, default_value = DEFAULT_MODULE_D_TARGET_PATH)]
127 pub target_path: PathBuf,
128 #[arg(long, default_value_t = DEFAULT_MODULE_D_TOTAL_BYTES)]
129 pub total_bytes: u64,
130 #[arg(long, default_value_t = DEFAULT_MODULE_D_GROUP_BYTES)]
131 pub group_bytes: usize,
132 #[arg(long, default_value_t = DEFAULT_MODULE_D_REQUEST_BYTES)]
133 pub request_bytes: usize,
134 #[arg(long, default_value_t = DEFAULT_MODULE_D_PRODUCERS)]
135 pub producers: usize,
136 #[arg(long, default_value_t = DEFAULT_MODULE_D_SEED)]
137 pub seed: u64,
138 #[arg(long)]
139 pub allow_file_fallback: bool,
140 #[arg(long)]
141 pub require_io_uring: bool,
142 #[arg(long)]
143 pub json: bool,
144}
145
146#[derive(Debug, Clone, Args)]
147pub struct ModuleEFstArgs {
148 #[arg(long, default_value_t = DEFAULT_MODULE_E_KEYS)]
149 pub keys: u64,
150 #[arg(long, default_value_t = DEFAULT_MODULE_E_LOOKUPS)]
151 pub lookups: u64,
152 #[arg(long, default_value_t = DEFAULT_MODULE_E_LIST_QUERIES)]
153 pub list_queries: u64,
154 #[arg(long, default_value = DEFAULT_MODULE_E_INDEX_PATH)]
155 pub index_path: PathBuf,
156 #[arg(long)]
157 pub json: bool,
158}
159
160#[derive(Debug, Clone, Args)]
161pub struct ModuleETrieArgs {
162 #[arg(long, default_value_t = DEFAULT_MODULE_E_KEYS)]
163 pub keys: u64,
164 #[arg(long, default_value_t = DEFAULT_MODULE_E_LOOKUPS)]
165 pub lookups: u64,
166 #[arg(long, default_value_t = DEFAULT_MODULE_E_LIST_QUERIES)]
167 pub list_queries: u64,
168 #[arg(long)]
169 pub json: bool,
170}
171
172#[derive(Debug, Clone, Args)]
173pub struct ModuleECompareArgs {
174 #[arg(long, default_value_t = DEFAULT_MODULE_E_KEYS)]
175 pub keys: u64,
176 #[arg(long, default_value_t = DEFAULT_MODULE_E_LOOKUPS)]
177 pub lookups: u64,
178 #[arg(long, default_value_t = DEFAULT_MODULE_E_LIST_QUERIES)]
179 pub list_queries: u64,
180 #[arg(long, default_value = DEFAULT_MODULE_E_INDEX_PATH)]
181 pub index_path: PathBuf,
182 #[arg(long)]
183 pub json: bool,
184}
185
186#[derive(Debug, Clone, Args)]
187pub struct ModuleFServeArgs {
188 #[arg(long, default_value = DEFAULT_MODULE_F_LISTEN_ADDR)]
189 pub listen_addr: String,
190 #[arg(long, default_value_t = DEFAULT_MODULE_F_WORKERS)]
191 pub workers: usize,
192 #[arg(long, default_value = DEFAULT_MODULE_F_TARGET_PATH)]
193 pub target_path: PathBuf,
194 #[arg(long, default_value_t = DEFAULT_MODULE_F_GROUP_BYTES)]
195 pub group_bytes: usize,
196 #[arg(long, default_value_t = DEFAULT_MODULE_F_COMPACTION_THRESHOLD)]
197 pub compaction_threshold: usize,
198 #[arg(long, default_value_t = DEFAULT_MODULE_F_FLUSH_INTERVAL_MS)]
199 pub flush_interval_ms: u64,
200 #[arg(long, default_value_t = String::from(DEFAULT_MODULE_F_BUCKET))]
201 pub bucket: String,
202 #[arg(long, default_value_t = String::from(DEFAULT_MODULE_F_ACCESS_KEY))]
203 pub access_key: String,
204 #[arg(long, default_value_t = String::from(DEFAULT_MODULE_F_SECRET_KEY))]
205 pub secret_key: String,
206 #[arg(long)]
207 pub allow_file_fallback: bool,
208 #[arg(long)]
209 pub require_io_uring: bool,
210}