From 7a71b592886fc963c91410805dcbbec634e794e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Hern=C3=A1ndez=20Bab=C3=B3n?= Date: Mon, 23 Jan 2023 18:45:47 +0100 Subject: [PATCH] Add an option to change the size of the pool of candidates This can be changed through the CLI args or in the config file. --- CHANGELOG.md | 14 ++++++++++---- src/config.rs | 8 ++++++++ src/config/components.rs | 19 +++++++++++++++++++ src/engine.rs | 16 +++++++++------- src/main.rs | 4 ++++ src/supervisor.rs | 4 ++-- 6 files changed, 52 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b0e42a..d9a0755 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,10 +5,11 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] -### Fixed -- If the setting `screen.lines` is present in the TOML config file, apply it only on inline mode -- Respect `screen.lines` option from config file when no `--lines` argument is given -- Ensure `-v` flag is in lowercase in CLI help message +### Added +- New argument, `--pool`, and config option `advanced.pool_size` (or `advanced.pool`). + This option can change the size of the pool of candidates that are kept in memory. + Increasing this number might result in the program using too much memory. + This is an advanced feature and should be used with care. ### Changed - Bump `unicode-segmentation` 1.9.0 to 1.10.0 @@ -16,6 +17,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Bump `env_logger` from 0.9.0 to 0.10.0 - Bump `libc` from 0.2.129 to 0.2.139 +### Fixed +- If the setting `screen.lines` is present in the TOML config file, apply it only on inline mode +- Respect `screen.lines` option from config file when no `--lines` argument is given +- Ensure `-v` flag is in lowercase in CLI help message + ## [v2.6.0] 2022-01-23 ### Changed - Update to edition 2021 and set rust-version to 1.58 diff --git a/src/config.rs b/src/config.rs index 06c5475..0c5bd8a 100644 --- a/src/config.rs +++ b/src/config.rs @@ -25,6 +25,7 @@ pub struct Args { pub lines: Option, pub config: Option, pub search: Option, + pub pool: Option, } /// Arc version of Cfg @@ -46,6 +47,9 @@ pub struct Cfg { pub candidate: CandidateConfig, #[serde(default)] pub selection: SelectionConfig, + + #[serde(default)] + pub advanced: AdvancedConfig, } /// Configuration constructor @@ -125,6 +129,10 @@ impl Configurator { config.initial_query = Some(q); } + if let Some(pool) = args.pool { + config.advanced.set_pool_size(pool); + } + self.config = Some(config); } diff --git a/src/config/components.rs b/src/config/components.rs index 29547b4..65b3180 100644 --- a/src/config/components.rs +++ b/src/config/components.rs @@ -7,6 +7,8 @@ const DEFAULT_HEIGHT: usize = 6; const MIN_HEIGHT: usize = 3; const MIN_WIDTH: usize = 4; +const DEFAULT_POOL_SIZE: usize = 50000; + #[derive(Deserialize, Clone, Debug, PartialEq)] enum Mode { #[serde(rename = "full")] @@ -91,6 +93,23 @@ impl ScreenConfig { } } +/// Main advanced set of configuration options +#[derive(Deserialize, Clone, Debug, Default)] +pub struct AdvancedConfig { + #[serde(default, alias = "pool")] + pool_size: Option, +} + +impl AdvancedConfig { + pub fn pool_size(&self) -> usize { + self.pool_size.unwrap_or(DEFAULT_POOL_SIZE) + } + + pub fn set_pool_size(&mut self, pool_size: usize) { + self.pool_size = Some(pool_size) + } +} + /// Prompt UI component configuration options /// /// The prompt is where you write the search query diff --git a/src/engine.rs b/src/engine.rs index d7a26a2..8e7b09a 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -4,6 +4,7 @@ //! Once a search is done all the results will be sent to the screen. use crate::common::{Result, Text, TextBuilder}; +use crate::config::Config; use crate::events::Event; use crate::fuzzy; use async_std::channel::{Receiver, Sender}; @@ -11,12 +12,16 @@ use async_std::prelude::*; use std::collections::VecDeque; const BUFFER_LIMIT: usize = 5000; -const POOL_LIMIT: usize = 50000; /// Run the search engine task -pub async fn task(mut input_recv: Receiver, output_sender: Sender) -> Result<()> { +pub async fn task( + config: Config, + mut input_recv: Receiver, + output_sender: Sender, +) -> Result<()> { log::trace!("starting search engine"); + let pool_size = config.advanced.pool_size(); let mut pool: VecDeque = VecDeque::new(); let mut count = 0; let mut query = String::from(""); @@ -32,11 +37,8 @@ pub async fn task(mut input_recv: Receiver, output_sender: Sender) // The pool might be full (too many lines in memory) // so we drop the first line - if pool.len() > POOL_LIMIT { - log::trace!( - "pool limit ({:?}) exceeded, dropping first line", - POOL_LIMIT - ); + if pool.len() > pool_size { + log::trace!("pool limit ({:?}) exceeded, dropping first line", pool_size); let _f = pool.pop_front(); } diff --git a/src/main.rs b/src/main.rs index bb5d13c..c6eed49 100644 --- a/src/main.rs +++ b/src/main.rs @@ -28,6 +28,9 @@ OPTIONS: -c, --config Uses a custom config file -l, --lines Number of lines to display in inline mode, including prompt -s, --search Start searching with the given query + -p, --pool Advanced: size of the pool of candidates to keep in memory. + Default is 50000. Note that increasing this number might + result in the program using too much memory SUPPORTED KEYS: - Enter to select the current highlighted match and print it to STDOUT @@ -158,6 +161,7 @@ fn parse_args() -> std::result::Result { search, lines: pargs.opt_value_from_str(["-l", "--lines"])?, config: pargs.opt_value_from_str(["-c", "--config"])?, + pool: pargs.opt_value_from_str(["-p", "--pool"])?, }; let remaining = pargs.finish(); diff --git a/src/supervisor.rs b/src/supervisor.rs index 6cdf0af..7cc807d 100644 --- a/src/supervisor.rs +++ b/src/supervisor.rs @@ -56,12 +56,12 @@ where let screen_task = task::spawn(screen::task(config.clone(), outbox, output_recv)); let person_task = task::spawn(person_input::task( - config, + config.clone(), inbox, input_sender.clone(), output_sender.clone(), )); - let engine_task = task::spawn(engine::task(input_recv, output_sender)); + let engine_task = task::spawn(engine::task(config, input_recv, output_sender)); let data_task = task::spawn(data_input::task(stdin, input_sender)); let selection = screen_task.await;