mirror of
https://github.com/ankitects/anki.git
synced 2025-09-23 08:22:24 -04:00
rework aux table sorting
Instead of inserting text into the aux table and sorting on the fly (which does a binary sort), we insert the ids in unicase-sorted order, and then sort based on the automatically assigned rowids - giving us faster sorts, and proper unicase folding.
This commit is contained in:
parent
8246ba148e
commit
8d17edc1e6
7 changed files with 65 additions and 62 deletions
|
@ -158,7 +158,7 @@ impl Collection {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, PartialEq, Debug)]
|
||||
#[derive(Deserialize, PartialEq, Debug, Clone, Copy)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum SortKind {
|
||||
#[serde(rename = "noteCrt")]
|
||||
|
|
|
@ -8,7 +8,6 @@ use crate::collection::Collection;
|
|||
use crate::config::SortKind;
|
||||
use crate::err::Result;
|
||||
use crate::search::parser::parse;
|
||||
use rusqlite::params;
|
||||
|
||||
pub enum SortMode {
|
||||
NoOrder,
|
||||
|
@ -31,14 +30,14 @@ impl Collection {
|
|||
SortMode::NoOrder => (),
|
||||
SortMode::FromConfig => {
|
||||
let kind = self.get_browser_sort_kind();
|
||||
prepare_sort(self, &kind)?;
|
||||
prepare_sort(self, kind)?;
|
||||
sql.push_str(" order by ");
|
||||
write_order(&mut sql, &kind, self.get_browser_sort_reverse())?;
|
||||
write_order(&mut sql, kind, self.get_browser_sort_reverse())?;
|
||||
}
|
||||
SortMode::Builtin { kind, reverse } => {
|
||||
prepare_sort(self, &kind)?;
|
||||
prepare_sort(self, kind)?;
|
||||
sql.push_str(" order by ");
|
||||
write_order(&mut sql, &kind, reverse)?;
|
||||
write_order(&mut sql, kind, reverse)?;
|
||||
}
|
||||
SortMode::Custom(order_clause) => {
|
||||
sql.push_str(" order by ");
|
||||
|
@ -56,7 +55,7 @@ impl Collection {
|
|||
}
|
||||
|
||||
/// Add the order clause to the sql.
|
||||
fn write_order(sql: &mut String, kind: &SortKind, reverse: bool) -> Result<()> {
|
||||
fn write_order(sql: &mut String, kind: SortKind, reverse: bool) -> Result<()> {
|
||||
let tmp_str;
|
||||
let order = match kind {
|
||||
SortKind::NoteCreation => "n.id asc, c.ord asc",
|
||||
|
@ -72,9 +71,13 @@ fn write_order(sql: &mut String, kind: &SortKind, reverse: bool) -> Result<()> {
|
|||
SortKind::CardLapses => "c.lapses asc",
|
||||
SortKind::CardInterval => "c.ivl asc",
|
||||
SortKind::NoteTags => "n.tags asc",
|
||||
SortKind::CardDeck => "(select v from sort_order where k = c.did) asc",
|
||||
SortKind::NoteType => "(select v from sort_order where k = n.mid) asc",
|
||||
SortKind::CardTemplate => "(select v from sort_order where k1 = n.mid and k2 = c.ord) asc",
|
||||
SortKind::CardDeck => "(select pos from sort_order where did = c.did) asc",
|
||||
SortKind::NoteType => "(select pos from sort_order where ntid = n.mid) asc",
|
||||
SortKind::CardTemplate => concat!(
|
||||
"coalesce((select pos from sort_order where ntid = n.mid and ord = c.ord),",
|
||||
// need to fall back on ord 0 for cloze cards
|
||||
"(select pos from sort_order where ntid = n.mid and ord = 0)) asc"
|
||||
),
|
||||
};
|
||||
if order.is_empty() {
|
||||
return Ok(());
|
||||
|
@ -92,60 +95,28 @@ fn write_order(sql: &mut String, kind: &SortKind, reverse: bool) -> Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
// fixme: use the new tables
|
||||
fn prepare_sort(col: &mut Collection, kind: &SortKind) -> Result<()> {
|
||||
fn needs_aux_sort_table(kind: SortKind) -> bool {
|
||||
use SortKind::*;
|
||||
match kind {
|
||||
CardDeck | NoteType => {
|
||||
prepare_sort_order_table(col)?;
|
||||
let mut stmt = col
|
||||
.storage
|
||||
.db
|
||||
.prepare("insert into sort_order (k,v) values (?,?)")?;
|
||||
CardDeck | NoteType | CardTemplate => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
match kind {
|
||||
CardDeck => {
|
||||
for (k, v) in col.storage.get_all_decks_as_schema11()? {
|
||||
stmt.execute(params![k, v.name()])?;
|
||||
}
|
||||
}
|
||||
NoteType => {
|
||||
for (k, v) in col.storage.get_all_notetypes_as_schema11()? {
|
||||
stmt.execute(params![k, v.name])?;
|
||||
}
|
||||
fn prepare_sort(col: &mut Collection, kind: SortKind) -> Result<()> {
|
||||
if !needs_aux_sort_table(kind) {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
use SortKind::*;
|
||||
let sql = match kind {
|
||||
CardDeck => include_str!("deck_order.sql"),
|
||||
NoteType => include_str!("notetype_order.sql"),
|
||||
CardTemplate => include_str!("template_order.sql"),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
CardTemplate => {
|
||||
prepare_sort_order_table2(col)?;
|
||||
let mut stmt = col
|
||||
.storage
|
||||
.db
|
||||
.prepare("insert into sort_order (k1,k2,v) values (?,?,?)")?;
|
||||
};
|
||||
|
||||
for (ntid, nt) in col.storage.get_all_notetypes_as_schema11()? {
|
||||
for tmpl in nt.tmpls {
|
||||
stmt.execute(params![ntid, tmpl.ord, tmpl.name])?;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
col.storage.db.execute_batch(sql)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn prepare_sort_order_table(col: &mut Collection) -> Result<()> {
|
||||
col.storage
|
||||
.db
|
||||
.execute_batch(include_str!("sort_order.sql"))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn prepare_sort_order_table2(col: &mut Collection) -> Result<()> {
|
||||
col.storage
|
||||
.db
|
||||
.execute_batch(include_str!("sort_order2.sql"))?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
11
rslib/src/search/deck_order.sql
Normal file
11
rslib/src/search/deck_order.sql
Normal file
|
@ -0,0 +1,11 @@
|
|||
drop table if exists sort_order;
|
||||
create temporary table sort_order (
|
||||
pos integer primary key,
|
||||
did integer not null unique
|
||||
);
|
||||
insert into sort_order (did)
|
||||
select
|
||||
id
|
||||
from decks
|
||||
order by
|
||||
name;
|
11
rslib/src/search/notetype_order.sql
Normal file
11
rslib/src/search/notetype_order.sql
Normal file
|
@ -0,0 +1,11 @@
|
|||
drop table if exists sort_order;
|
||||
create temporary table sort_order (
|
||||
pos integer primary key,
|
||||
ntid integer not null unique
|
||||
);
|
||||
insert into sort_order (ntid)
|
||||
select
|
||||
id
|
||||
from notetypes
|
||||
order by
|
||||
name;
|
|
@ -1,2 +0,0 @@
|
|||
drop table if exists sort_order;
|
||||
create temporary table sort_order (k int primary key, v text);
|
|
@ -1,2 +0,0 @@
|
|||
drop table if exists sort_order;
|
||||
create temporary table sort_order (k1 int, k2 int, v text, primary key (k1, k2)) without rowid;
|
14
rslib/src/search/template_order.sql
Normal file
14
rslib/src/search/template_order.sql
Normal file
|
@ -0,0 +1,14 @@
|
|||
drop table if exists sort_order;
|
||||
create temporary table sort_order (
|
||||
pos integer primary key,
|
||||
ntid integer not null,
|
||||
ord integer not null,
|
||||
unique(ntid, ord)
|
||||
);
|
||||
insert into sort_order (ntid, ord)
|
||||
select
|
||||
ntid,
|
||||
ord
|
||||
from templates
|
||||
order by
|
||||
name
|
Loading…
Reference in a new issue