Skip to content

Commit 1f93670

Browse files
noahgiftclaude
andcommitted
chore: Release trueno-db v0.3.7 (Refs #1)
Dependencies updated: - trueno: 0.8.0 → 0.8.7 Also fixed slow pre-commit hook and formatting. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 17a28ac commit 1f93670

File tree

10 files changed

+105
-86
lines changed

10 files changed

+105
-86
lines changed

Cargo.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "trueno-db"
3-
version = "0.3.6"
3+
version = "0.3.7"
44
edition = "2021"
55
authors = ["Pragmatic AI Labs <info@paiml.com>"]
66
license = "MIT"
@@ -13,7 +13,7 @@ resolver = "2"
1313

1414
[dependencies]
1515
# Core compute (SIMD - always included)
16-
trueno = "0.8.0" # SIMD-accelerated compute
16+
trueno = "0.8.7" # SIMD-accelerated compute
1717

1818
# Serialization (experiment tracking schema)
1919
serde = { version = "1.0", features = ["derive"] }

examples/kv_store.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,18 @@ async fn demo_basic_crud() -> trueno_db::Result<()> {
4141

4242
// Read
4343
let alice = store.get("user:1001").await?;
44-
println!(" GET user:1001 = {:?}", alice.map(|v| String::from_utf8_lossy(&v).to_string()));
44+
println!(
45+
" GET user:1001 = {:?}",
46+
alice.map(|v| String::from_utf8_lossy(&v).to_string())
47+
);
4548

4649
// Update
4750
store.set("user:1001", b"Alice Smith".to_vec()).await?;
4851
let updated = store.get("user:1001").await?;
49-
println!(" UPDATE user:1001 = {:?}", updated.map(|v| String::from_utf8_lossy(&v).to_string()));
52+
println!(
53+
" UPDATE user:1001 = {:?}",
54+
updated.map(|v| String::from_utf8_lossy(&v).to_string())
55+
);
5056

5157
// Exists
5258
println!(" EXISTS user:1001 = {}", store.exists("user:1001").await?);
@@ -81,7 +87,9 @@ async fn demo_batch_operations() -> trueno_db::Result<()> {
8187
let values = store.batch_get(&keys).await?;
8288
println!(" BATCH GET results:");
8389
for (key, value) in keys.iter().zip(values.iter()) {
84-
let display = value.as_ref().map(|v| String::from_utf8_lossy(v).to_string());
90+
let display = value
91+
.as_ref()
92+
.map(|v| String::from_utf8_lossy(v).to_string());
8593
println!(" {} = {:?}", key, display);
8694
}
8795

src/experiment/metric_record.rs

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,7 @@ impl MetricRecord {
3737
///
3838
/// A new `MetricRecord` with the current timestamp.
3939
#[must_use]
40-
pub fn new(
41-
run_id: impl Into<String>,
42-
key: impl Into<String>,
43-
step: u64,
44-
value: f64,
45-
) -> Self {
40+
pub fn new(run_id: impl Into<String>, key: impl Into<String>, step: u64, value: f64) -> Self {
4641
Self {
4742
run_id: run_id.into(),
4843
key: key.into(),
@@ -107,12 +102,7 @@ pub struct MetricRecordBuilder {
107102
impl MetricRecordBuilder {
108103
/// Create a new builder with required fields.
109104
#[must_use]
110-
pub fn new(
111-
run_id: impl Into<String>,
112-
key: impl Into<String>,
113-
step: u64,
114-
value: f64,
115-
) -> Self {
105+
pub fn new(run_id: impl Into<String>, key: impl Into<String>, step: u64, value: f64) -> Self {
116106
Self {
117107
run_id: run_id.into(),
118108
key: key.into(),

src/kv/mod.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,10 @@ pub trait KvStore: Send + Sync {
6060
/// Get multiple keys in a batch (SIMD-optimized).
6161
///
6262
/// Returns values in the same order as keys. Missing keys return `None`.
63-
fn batch_get(&self, keys: &[&str]) -> impl Future<Output = Result<Vec<Option<Vec<u8>>>>> + Send {
63+
fn batch_get(
64+
&self,
65+
keys: &[&str],
66+
) -> impl Future<Output = Result<Vec<Option<Vec<u8>>>>> + Send {
6467
async move {
6568
let mut results = Vec::with_capacity(keys.len());
6669
for key in keys {
@@ -71,10 +74,7 @@ pub trait KvStore: Send + Sync {
7174
}
7275

7376
/// Set multiple key-value pairs in a batch (SIMD-optimized).
74-
fn batch_set(
75-
&self,
76-
pairs: Vec<(&str, Vec<u8>)>,
77-
) -> impl Future<Output = Result<()>> + Send {
77+
fn batch_set(&self, pairs: Vec<(&str, Vec<u8>)>) -> impl Future<Output = Result<()>> + Send {
7878
async move {
7979
for (key, value) in pairs {
8080
self.set(key, value).await?;
@@ -222,7 +222,10 @@ mod tests {
222222
let store = MemoryKvStore::new();
223223

224224
store.set("", b"empty_key_value".to_vec()).await.unwrap();
225-
assert_eq!(store.get("").await.unwrap(), Some(b"empty_key_value".to_vec()));
225+
assert_eq!(
226+
store.get("").await.unwrap(),
227+
Some(b"empty_key_value".to_vec())
228+
);
226229
}
227230

228231
#[tokio::test]

src/wasm.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -173,11 +173,7 @@ impl Database {
173173
DataType::Int32 => {
174174
let values: Vec<Option<i32>> = records
175175
.iter()
176-
.map(|r| {
177-
r.get(col_name)
178-
.and_then(|v| v.as_i64())
179-
.map(|n| n as i32)
180-
})
176+
.map(|r| r.get(col_name).and_then(|v| v.as_i64()).map(|n| n as i32))
181177
.collect();
182178
columns.push(Arc::new(Int32Array::from(values)));
183179
}

src/wasm/http_range.rs

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@
2121
2222
#![cfg(target_arch = "wasm32")]
2323

24+
use js_sys::Uint8Array;
2425
use wasm_bindgen::prelude::*;
2526
use wasm_bindgen::JsCast;
2627
use wasm_bindgen_futures::JsFuture;
27-
use web_sys::{Request, RequestInit, Response, Headers};
28-
use js_sys::Uint8Array;
28+
use web_sys::{Headers, Request, RequestInit, Response};
2929

3030
/// Byte range for HTTP range requests
3131
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -51,7 +51,7 @@ impl ByteRange {
5151
/// Create range for last N bytes of file
5252
pub fn last_n_bytes(n: u64) -> Self {
5353
Self {
54-
start: u64::MAX - n + 1, // Will be converted to suffix-range
54+
start: u64::MAX - n + 1, // Will be converted to suffix-range
5555
end: u64::MAX,
5656
}
5757
}
@@ -116,8 +116,7 @@ impl RangeClient {
116116

117117
/// Try to fetch once (no retry)
118118
async fn try_fetch(&self, request: &Request) -> Result<Vec<u8>, JsValue> {
119-
let window = web_sys::window()
120-
.ok_or_else(|| JsValue::from_str("No window object"))?;
119+
let window = web_sys::window().ok_or_else(|| JsValue::from_str("No window object"))?;
121120

122121
// Execute fetch
123122
let response_promise = window.fetch_with_request(request);
@@ -140,8 +139,7 @@ impl RangeClient {
140139

141140
/// Get file size using HEAD request
142141
pub async fn get_file_size(&self) -> Result<u64, JsValue> {
143-
let window = web_sys::window()
144-
.ok_or_else(|| JsValue::from_str("No window object"))?;
142+
let window = web_sys::window().ok_or_else(|| JsValue::from_str("No window object"))?;
145143

146144
let mut opts = RequestInit::new();
147145
opts.method("HEAD");
@@ -156,10 +154,9 @@ impl RangeClient {
156154
let content_length_js = headers.get("content-length")?;
157155

158156
match content_length_js {
159-
Some(length_str) => {
160-
length_str.parse::<u64>()
161-
.map_err(|e| JsValue::from_str(&format!("Invalid content-length: {}", e)))
162-
}
157+
Some(length_str) => length_str
158+
.parse::<u64>()
159+
.map_err(|e| JsValue::from_str(&format!("Invalid content-length: {}", e))),
163160
None => Err(JsValue::from_str("No content-length header")),
164161
}
165162
}

src/wasm/streaming_parquet.rs

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -90,15 +90,15 @@ impl StreamingParquetReader {
9090
}
9191

9292
// Read footer metadata (last 8 bytes)
93-
let footer_range = ByteRange::new(
94-
self.file_size - FOOTER_METADATA_SIZE,
95-
self.file_size - 1,
96-
);
93+
let footer_range =
94+
ByteRange::new(self.file_size - FOOTER_METADATA_SIZE, self.file_size - 1);
9795
let footer_bytes = self.client.fetch_range(footer_range).await?;
9896

9997
// Verify magic number
10098
if &footer_bytes[4..8] != PARQUET_MAGIC {
101-
return Err(JsValue::from_str("Invalid Parquet file: missing magic number"));
99+
return Err(JsValue::from_str(
100+
"Invalid Parquet file: missing magic number",
101+
));
102102
}
103103

104104
// Parse footer length (little-endian i32)
@@ -153,7 +153,9 @@ impl StreamingParquetReader {
153153
/// # Returns
154154
/// Row group data as raw bytes (to be decoded into Arrow RecordBatch)
155155
pub async fn read_row_group(&self, index: usize) -> Result<Vec<u8>, JsValue> {
156-
let metadata = self.metadata.as_ref()
156+
let metadata = self
157+
.metadata
158+
.as_ref()
157159
.ok_or_else(|| JsValue::from_str("Metadata not loaded. Call read_metadata() first"))?;
158160

159161
if index >= metadata.row_groups.len() {
@@ -165,12 +167,18 @@ impl StreamingParquetReader {
165167
}
166168

167169
let row_group = &metadata.row_groups[index];
168-
let range = ByteRange::new(row_group.file_offset, row_group.file_offset + row_group.total_byte_size - 1);
170+
let range = ByteRange::new(
171+
row_group.file_offset,
172+
row_group.file_offset + row_group.total_byte_size - 1,
173+
);
169174

170-
console::log_1(&format!(
171-
"Reading row group {}: {} bytes at offset {}",
172-
index, row_group.total_byte_size, row_group.file_offset
173-
).into());
175+
console::log_1(
176+
&format!(
177+
"Reading row group {}: {} bytes at offset {}",
178+
index, row_group.total_byte_size, row_group.file_offset
179+
)
180+
.into(),
181+
);
174182

175183
self.client.fetch_range(range).await
176184
}
@@ -183,7 +191,9 @@ impl StreamingParquetReader {
183191
row_group_index: usize,
184192
column_indices: &[usize],
185193
) -> Result<Vec<Vec<u8>>, JsValue> {
186-
let metadata = self.metadata.as_ref()
194+
let metadata = self
195+
.metadata
196+
.as_ref()
187197
.ok_or_else(|| JsValue::from_str("Metadata not loaded"))?;
188198

189199
let row_group = &metadata.row_groups[row_group_index];
@@ -198,7 +208,10 @@ impl StreamingParquetReader {
198208
}
199209

200210
let column = &row_group.columns[col_idx];
201-
let range = ByteRange::new(column.file_offset, column.file_offset + column.total_compressed_size - 1);
211+
let range = ByteRange::new(
212+
column.file_offset,
213+
column.file_offset + column.total_compressed_size - 1,
214+
);
202215
let bytes = self.client.fetch_range(range).await?;
203216
column_data.push(bytes);
204217
}

tests/backend_story.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -290,10 +290,7 @@ mod gpu_tests {
290290
.await
291291
.expect("GPU sum should work");
292292

293-
assert_eq!(
294-
scalar_sum, gpu_sum,
295-
"GPU sum should equal Scalar sum"
296-
);
293+
assert_eq!(scalar_sum, gpu_sum, "GPU sum should equal Scalar sum");
297294
}
298295

299296
/// Test GPU min matches Scalar min
@@ -353,7 +350,10 @@ mod gpu_tests {
353350
.await
354351
.expect("GPU count should work");
355352

356-
assert_eq!(scalar_count, gpu_count, "GPU count should equal Scalar count");
353+
assert_eq!(
354+
scalar_count, gpu_count,
355+
"GPU count should equal Scalar count"
356+
);
357357
}
358358

359359
/// Test GPU fused filter+sum works correctly
@@ -402,8 +402,8 @@ mod gpu_tests {
402402
mod backend_completeness {
403403
//! Compile-time verification that critical traits/types exist
404404
405-
use trueno_db::Backend;
406405
use trueno_db::backend::BackendDispatcher;
406+
use trueno_db::Backend;
407407

408408
/// Verify Backend enum has required variants
409409
#[test]

0 commit comments

Comments
 (0)