|
3 | 3 |
|
4 | 4 | //! WASM bindings for the Vortex benchmark website. |
5 | 5 | //! |
6 | | -//! This module provides a `load_random_access_data()` function that fetches benchmark data from S3, |
7 | | -//! parses it, and returns it in a format ready for JavaScript to render. |
| 6 | +//! This crate provides functions for fetching and processing benchmark data from S3, returning it |
| 7 | +//! in a format ready for JavaScript to render. |
8 | 8 |
|
9 | 9 | pub mod website; |
10 | 10 |
|
11 | 11 | #[cfg(target_arch = "wasm32")] |
12 | | -mod wasm_bindings { |
13 | | - use serde::Serialize; |
14 | | - use vortex::VortexSessionDefault; |
15 | | - use vortex::io::runtime::wasm::WasmRuntime; |
16 | | - use vortex::io::session::RuntimeSessionExt; |
17 | | - use vortex::session::VortexSession; |
| 12 | +mod wasm_init { |
18 | 13 | use wasm_bindgen::prelude::*; |
19 | 14 |
|
20 | | - use crate::website::read_s3::get_benchmark_data; |
21 | | - use crate::website::read_s3::get_benchmark_summary; |
22 | | - use crate::website::read_s3::get_chart_data; |
23 | | - use crate::website::read_s3::read_benchmark_entries; |
24 | | - |
25 | | - const DATA_KEY: &str = "data.vortex"; |
26 | | - const COMMITS_KEY: &str = "commits.vortex"; |
27 | | - |
28 | | - // Legacy key for old random_access data format. |
29 | | - const LEGACY_KEY: &str = "random_access.vortex"; |
30 | | - |
31 | | - /// Helper macro for logging to browser console. |
32 | | - macro_rules! log { |
33 | | - ($($t:tt)*) => { |
34 | | - web_sys::console::log_1(&format!($($t)*).into()); |
35 | | - } |
36 | | - } |
37 | | - |
38 | | - /// A single random-access benchmark entry for JavaScript. |
39 | | - #[derive(Serialize)] |
40 | | - pub struct JsEntry { |
41 | | - pub commit_id: String, |
42 | | - pub series_name: String, |
43 | | - pub value_ms: f64, |
44 | | - } |
45 | | - |
46 | | - /// Load random-access benchmark data from S3. |
47 | | - /// |
48 | | - /// This function fetches the Vortex file from S3, parses it, and returns an array of benchmark |
49 | | - /// entries ready for rendering. |
50 | | - /// |
51 | | - /// # Returns |
52 | | - /// |
53 | | - /// A JavaScript array of objects with: |
54 | | - /// - `commit_id`: 40-character hex string (SHA-1 hash) |
55 | | - /// - `series_name`: One of "vortex-nvme", "parquet-nvme", "lance-nvme" |
56 | | - /// - `value_ms`: Value in milliseconds |
57 | | - #[wasm_bindgen] |
58 | | - pub async fn load_random_access_data() -> Result<JsValue, JsValue> { |
59 | | - log!("Loading random-access benchmark data..."); |
60 | | - |
61 | | - // Create a session configured with the WASM runtime. |
62 | | - let session = VortexSession::default().with_handle(WasmRuntime::handle()); |
63 | | - |
64 | | - let entries = read_benchmark_entries(&session, LEGACY_KEY) |
65 | | - .await |
66 | | - .map_err(|e| JsValue::from_str(&format!("Failed to read benchmark entries: {}", e)))?; |
67 | | - |
68 | | - log!("Loaded {} entries", entries.len()); |
69 | | - |
70 | | - // Convert to JS-friendly format. |
71 | | - let js_entries: Vec<JsEntry> = entries |
72 | | - .iter() |
73 | | - .map(|e| JsEntry { |
74 | | - commit_id: e.commit_id.to_string(), |
75 | | - series_name: e.series_name.clone(), |
76 | | - value_ms: e.value as f64 / 1_000_000.0, |
77 | | - }) |
78 | | - .collect(); |
79 | | - |
80 | | - log!("Returning {} JS entries", js_entries.len()); |
81 | | - |
82 | | - serde_wasm_bindgen::to_value(&js_entries) |
83 | | - .map_err(|e| JsValue::from_str(&format!("Failed to serialize: {}", e))) |
84 | | - } |
85 | | - |
86 | | - /// Load all benchmark data from S3 (legacy, slow - use load_benchmark_summary instead). |
87 | | - /// |
88 | | - /// This function fetches the commits and benchmark data Vortex files from S3, parses them, |
89 | | - /// aligns the data to commits, and returns a structured response. |
90 | | - /// |
91 | | - /// # Returns |
92 | | - /// |
93 | | - /// A JavaScript object with: |
94 | | - /// - `benchmarks`: Nested object with group_name → charts → chart_name → aligned_series → series_name → values |
95 | | - /// - `commits`: Array of commit objects with timestamp, author, message, and commit_id |
96 | | - /// |
97 | | - /// Values are in nanoseconds (u64). Convert to milliseconds in JavaScript by dividing by |
98 | | - /// 1_000_000. |
99 | | - #[wasm_bindgen] |
100 | | - pub async fn load_benchmark_data() -> Result<JsValue, JsValue> { |
101 | | - log!("Loading benchmark data..."); |
102 | | - |
103 | | - let session = VortexSession::default().with_handle(WasmRuntime::handle()); |
104 | | - |
105 | | - let result = get_benchmark_data(&session, COMMITS_KEY, DATA_KEY) |
106 | | - .await |
107 | | - .map_err(|e| JsValue::from_str(&format!("Failed to load benchmark data: {}", e)))?; |
108 | | - |
109 | | - log!("Benchmark data loaded successfully"); |
110 | | - |
111 | | - Ok(result) |
112 | | - } |
113 | | - |
114 | | - /// Load benchmark summary (metadata only, fast). |
115 | | - /// |
116 | | - /// This function fetches data from S3 (cached after first call), processes it, and returns |
117 | | - /// a summary containing: |
118 | | - /// - `commits`: Array of commit objects |
119 | | - /// - `groups`: Object mapping group names to chart metadata (no values) |
120 | | - /// |
121 | | - /// Use this for fast initial load, then call `load_chart_data` for specific charts. |
122 | | - /// |
123 | | - /// # Returns |
124 | | - /// |
125 | | - /// A JSON string that must be parsed with `JSON.parse()` in JavaScript. |
126 | | - #[wasm_bindgen] |
127 | | - pub async fn load_benchmark_summary() -> Result<String, JsValue> { |
128 | | - log!("Loading benchmark summary..."); |
129 | | - |
130 | | - let session = VortexSession::default().with_handle(WasmRuntime::handle()); |
131 | | - |
132 | | - let json = get_benchmark_summary(&session, COMMITS_KEY, DATA_KEY) |
133 | | - .await |
134 | | - .map_err(|e| JsValue::from_str(&format!("Failed to load benchmark summary: {}", e)))?; |
135 | | - |
136 | | - log!("Benchmark summary loaded successfully"); |
137 | | - |
138 | | - Ok(json) |
139 | | - } |
140 | | - |
141 | | - /// Load chart data for a specific group and chart. |
142 | | - /// |
143 | | - /// This function returns the aligned series data for a single chart. Data is cached after |
144 | | - /// the first call to any load function, so subsequent calls are fast. |
145 | | - /// |
146 | | - /// # Arguments |
147 | | - /// |
148 | | - /// * `group` - The group name (e.g., "random-access", "tpch") |
149 | | - /// * `chart` - The chart name within the group (e.g., "latency", "q1-sf1000-nvme") |
150 | | - /// |
151 | | - /// # Returns |
152 | | - /// |
153 | | - /// A JSON string containing `{ aligned_series: { series_name: [values...] } }`. |
154 | | - /// Values are in nanoseconds (u64). Parse with `JSON.parse()` in JavaScript. |
155 | | - #[wasm_bindgen] |
156 | | - pub async fn load_chart_data(group: &str, chart: &str) -> Result<String, JsValue> { |
157 | | - log!( |
158 | | - "Loading chart data for group='{}', chart='{}'...", |
159 | | - group, |
160 | | - chart |
161 | | - ); |
162 | | - |
163 | | - let session = VortexSession::default().with_handle(WasmRuntime::handle()); |
164 | | - |
165 | | - let json = get_chart_data(&session, COMMITS_KEY, DATA_KEY, group, chart) |
166 | | - .await |
167 | | - .map_err(|e| JsValue::from_str(&format!("Failed to load chart data: {}", e)))?; |
168 | | - |
169 | | - log!("Chart data loaded successfully"); |
170 | | - |
171 | | - Ok(json) |
172 | | - } |
173 | | - |
174 | 15 | /// Initialize the WASM module. |
175 | 16 | #[wasm_bindgen(start)] |
176 | 17 | pub fn init() { |
177 | 18 | console_error_panic_hook::set_once(); |
178 | | - log!("vortex-wasm initialized"); |
179 | 19 | } |
180 | 20 |
|
181 | 21 | /// Get version information. |
|
0 commit comments