Files
turso/core/sorter.rs
Pekka Enberg 30ec86a81e Add sorter utility functions and opcodes
This adds basic in-memory sorting utility functions, similar to SQLite's
src/vdbesort.c. We need to improve this later with external sorting so
to support large data sets.

This also adds sorting functionality to the VDBE. Note that none of this
is wired to SQL translation yet so it's unused for now.
2024-07-07 13:56:55 +03:00

79 lines
2.0 KiB
Rust

use crate::types::{Cursor, CursorResult, OwnedRecord, OwnedValue};
use anyhow::Result;
use log::trace;
use ordered_multimap::ListOrderedMultimap;
use std::cell::{Ref, RefCell};
pub struct Sorter {
records: ListOrderedMultimap<String, OwnedRecord>,
current: RefCell<Option<OwnedRecord>>,
}
impl Sorter {
pub fn new() -> Self {
Self {
records: ListOrderedMultimap::new(),
current: RefCell::new(None),
}
}
pub fn insert(&mut self, key: String, record: OwnedRecord) {
self.records.insert(key, record);
}
}
impl Cursor for Sorter {
fn is_empty(&self) -> bool {
self.current.borrow().is_none()
}
fn rewind(&mut self) -> Result<CursorResult<()>> {
let current = self.records.pop_front();
match current {
Some((_, record)) => {
*self.current.borrow_mut() = Some(record);
}
None => {
*self.current.borrow_mut() = None;
}
};
Ok(CursorResult::Ok(()))
}
fn next(&mut self) -> Result<CursorResult<()>> {
let current = self.records.pop_front();
match current {
Some((_, record)) => {
*self.current.borrow_mut() = Some(record);
}
None => {
*self.current.borrow_mut() = None;
}
};
Ok(CursorResult::Ok(()))
}
fn wait_for_completion(&mut self) -> Result<()> {
Ok(())
}
fn rowid(&self) -> Result<Ref<Option<u64>>> {
todo!();
}
fn record(&self) -> Result<Ref<Option<OwnedRecord>>> {
Ok(self.current.borrow())
}
fn insert(&mut self, record: &OwnedRecord) -> Result<()> {
let key = match record.values[0] {
OwnedValue::Integer(i) => i.to_string(),
OwnedValue::Text(ref s) => s.to_string(),
_ => todo!(),
};
trace!("Inserting record with key: {}", key);
self.insert(key, record.clone());
Ok(())
}
}