Skip to content

Commit 20cdb67

Browse files
committed
refactor(mem_wal): align LsmScanner with the dataset Scanner interface
LsmScanner gains a Scanner-aligned (owned) builder so an LSM read reads like a normal scan. `nearest()` and `full_text_search()` become state setters and `create_plan()` dispatches to the vector, FTS, point-lookup, or plain planner, mirroring `Scanner::create_plan` / `MemTableScanner::create_plan`. - Add `nearest`, `nprobes`, `refine`, `distance_metric` (vector search folds the LsmVectorSearchPlanner behind the builder; honors the builder filter). - `full_text_search(FullTextSearchQuery)` is now a setter (column from the query, k from `limit`) instead of returning a plan directly. - Align `project` (`<T: AsRef<str>>` + `Result`) and `limit` (`Option<i64>, Option<i64>` + `Result`) with `Scanner`. Knobs the LSM planner cannot yet honor (ef, distance_range, maximum_nprobes, with_row_id) are intentionally not exposed to avoid silently ignoring them.
1 parent 52d508e commit 20cdb67

5 files changed

Lines changed: 817 additions & 58 deletions

File tree

java/lance-jni/src/mem_wal.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ fn inner_scanner_project(env: &mut JNIEnv, this: JObject, columns: JObject) -> R
361361
let columns = env.get_strings(&columns)?;
362362
with_lsm_scanner(env, &this, |scanner| {
363363
let cols: Vec<&str> = columns.iter().map(String::as_str).collect();
364-
Ok(scanner.project(&cols))
364+
Ok(scanner.project(&cols)?)
365365
})
366366
}
367367

@@ -395,10 +395,12 @@ fn inner_scanner_limit(
395395
limit: jlong,
396396
offset: JObject,
397397
) -> Result<()> {
398-
let offset = env.get_u64_opt(&offset)?.map(|v| v as usize);
399-
with_lsm_scanner(env, &this, |scanner| {
400-
Ok(scanner.limit(limit as usize, offset))
401-
})
398+
let offset = env.get_u64_opt(&offset)?.map(|v| v as i64);
399+
with_lsm_scanner(
400+
env,
401+
&this,
402+
|scanner| Ok(scanner.limit(Some(limit), offset)?),
403+
)
402404
}
403405

404406
#[unsafe(no_mangle)]

python/src/mem_wal.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -520,7 +520,11 @@ impl PyLsmScanner {
520520
.take()
521521
.ok_or_else(|| PyRuntimeError::new_err("Scanner has already been consumed"))?;
522522
let cols: Vec<&str> = columns.iter().map(|s| s.as_str()).collect();
523-
slf.inner = Some(scanner.project(&cols));
523+
slf.inner = Some(
524+
scanner
525+
.project(&cols)
526+
.map_err(|e| PyValueError::new_err(e.to_string()))?,
527+
);
524528
Ok(slf)
525529
}
526530

@@ -549,7 +553,11 @@ impl PyLsmScanner {
549553
.inner
550554
.take()
551555
.ok_or_else(|| PyRuntimeError::new_err("Scanner has already been consumed"))?;
552-
slf.inner = Some(scanner.limit(n, offset));
556+
slf.inner = Some(
557+
scanner
558+
.limit(Some(n as i64), offset.map(|o| o as i64))
559+
.map_err(|e| PyValueError::new_err(e.to_string()))?,
560+
);
553561
Ok(slf)
554562
}
555563

rust/lance/src/dataset/mem_wal/scanner.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@
2424
//! use lance::dataset::mem_wal::scanner::LsmScanner;
2525
//!
2626
//! let scanner = LsmScanner::new(base_table, shard_snapshots, vec!["pk".to_string()])
27-
//! .project(&["id", "name"])
27+
//! .project(&["id", "name"])?
2828
//! .filter("id > 10")?
29-
//! .limit(100, None);
29+
//! .limit(Some(100), None)?;
3030
//!
3131
//! let stream = scanner.try_into_stream().await?;
3232
//! ```

0 commit comments

Comments
 (0)