file_model: Use binary search to find index

Binary search is a fast method to sort for an item within
a sorted list. We have a sorted list, so we can take advantage
of binary search instead of having a linear traversal through
the list.

Because binary search requires a sorted list, we need to use
the same logic for sorting and searching. Here we factor out
the filename comparison logic into `util::compare_by_name()`.
In the future we may want to have a module for sorting algorithm
logic and checking what sorting algortihm Nautilus uses.
This commit is contained in:
Christopher Davis 2022-07-14 15:25:03 -04:00
parent d609c4e0b2
commit 5f7aa595db
2 changed files with 18 additions and 13 deletions

View file

@ -3,6 +3,10 @@ use crate::deps::*;
use gio::prelude::*;
use glib::translate::*;
use anyhow::Context;
use std::fmt::Write;
pub fn utf8_collate_key_for_filename(filename: &str) -> String {
unsafe {
from_glib_full(glib::ffi::g_utf8_collate_key_for_filename(
@ -18,14 +22,11 @@ pub fn get_file_display_name(file: &gio::File) -> Option<String> {
Some(info.display_name().to_string())
}
pub fn query_attributes(
file: &gio::File,
attributes: Vec<&str>,
) -> Result<gio::FileInfo, glib::Error> {
pub fn query_attributes(file: &gio::File, attributes: Vec<&str>) -> anyhow::Result<gio::FileInfo> {
let mut attributes = attributes;
let mut attr_str = String::from(attributes.remove(0));
for attr in attributes {
attr_str.push_str(&format!(",{}", attr));
write!(attr_str, ",{}", attr)?;
}
file.query_info(
@ -33,4 +34,12 @@ pub fn query_attributes(
gio::FileQueryInfoFlags::empty(),
gio::Cancellable::NONE,
)
.context("Failed to query string")
}
pub fn compare_by_name(file_a: &gio::File, file_b: &gio::File) -> std::cmp::Ordering {
let name_a = get_file_display_name(file_a).unwrap_or_default();
let name_b = get_file_display_name(file_b).unwrap_or_default();
utf8_collate_key_for_filename(&name_a).cmp(&utf8_collate_key_for_filename(&name_b))
}