Skip to content

Commit

Permalink
expose number of active injectors from matcher
Browse files Browse the repository at this point in the history
  • Loading branch information
pascalkuthe committed Feb 20, 2024
1 parent 88a0853 commit 980413f
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 8 deletions.
53 changes: 45 additions & 8 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ should not be far away).
While the high level `nucleo` crate also works well (and is also used in helix),
there are still additional features that will be added in the future. The high
level crate also need better documentation and will likely see a few API
level crate also need better documentation and will likely see a few minor API
changes in the future.
*/
Expand All @@ -43,6 +43,9 @@ mod par_sort;
pub mod pattern;
mod worker;

#[cfg(test)]
mod tests;

/// A match candidate stored in a [`Nucleo`] worker.
pub struct Item<'a, T> {
pub data: &'a T,
Expand Down Expand Up @@ -219,6 +222,33 @@ impl<T: Sync + Send + 'static> Snapshot<T> {
}
}

#[repr(u8)]
#[derive(Clone, Copy, PartialEq, Eq)]
enum State {
Init,
/// items have been cleared but snapshot and items are still outdated
Cleared,
/// items are fresh
Fresh,
}

impl State {
fn matcher_item_refs(self) -> usize {
match self {
State::Cleared => 1,
State::Init | State::Fresh => 2,
}
}

fn canceled(self) -> bool {
self != State::Fresh
}

fn cleared(self) -> bool {
self != State::Fresh
}
}

/// A high level matcher worker that quickly computes matches in a background
/// threadpool.
pub struct Nucleo<T: Sync + Send + 'static> {
Expand All @@ -228,7 +258,7 @@ pub struct Nucleo<T: Sync + Send + 'static> {
should_notify: Arc<AtomicBool>,
worker: Arc<Mutex<Worker<T>>>,
pool: ThreadPool,
cleared: bool,
state: State,
items: Arc<boxcar::Vec<T>>,
notify: Arc<(dyn Fn() + Sync + Send)>,
snapshot: Snapshot<T>,
Expand Down Expand Up @@ -273,11 +303,18 @@ impl<T: Sync + Send + 'static> Nucleo<T> {
items: worker.items.clone(),
},
worker: Arc::new(Mutex::new(worker)),
cleared: true,
state: State::Init,
notify,
}
}

/// Returns the total number of active injectors
pub fn active_injectors(&self) -> usize {
Arc::strong_count(&self.items)
- self.state.matcher_item_refs()
- (Arc::ptr_eq(&self.snapshot.items, &self.items)) as usize
}

/// Returns a snapshot of the current matcher state.
pub fn snapshot(&self) -> &Snapshot<T> {
&self.snapshot
Expand Down Expand Up @@ -305,7 +342,7 @@ impl<T: Sync + Send + 'static> Nucleo<T> {
pub fn restart(&mut self, clear_snapshot: bool) {
self.canceled.store(true, Ordering::Relaxed);
self.items = Arc::new(boxcar::Vec::with_capacity(1024, self.items.columns()));
self.cleared = true;
self.state = State::Cleared;
if clear_snapshot {
self.snapshot.clear(self.items.clone());
}
Expand All @@ -322,12 +359,12 @@ impl<T: Sync + Send + 'static> Nucleo<T> {
pub fn tick(&mut self, timeout: u64) -> Status {
self.should_notify.store(false, atomic::Ordering::Relaxed);
let status = self.pattern.status();
let canceled = status != pattern::Status::Unchanged || self.cleared;
let canceled = status != pattern::Status::Unchanged || self.state.canceled();
let mut res = self.tick_inner(timeout, canceled, status);
if !canceled {
return res;
}
self.cleared = false;
self.state = State::Fresh;
let status2 = self.tick_inner(timeout, false, pattern::Status::Unchanged);
res.changed |= status2.changed;
res.running = status2.running;
Expand Down Expand Up @@ -355,7 +392,7 @@ impl<T: Sync + Send + 'static> Nucleo<T> {
let running = canceled || self.items.count() > inner.item_count();
if inner.running {
inner.running = false;
if !inner.was_canceled && !self.cleared {
if !inner.was_canceled && !self.state.canceled() {
self.snapshot.update(&inner)
}
}
Expand All @@ -365,7 +402,7 @@ impl<T: Sync + Send + 'static> Nucleo<T> {
if !canceled {
self.should_notify.store(true, atomic::Ordering::Release);
}
let cleared = self.cleared;
let cleared = self.state.cleared();
if cleared {
inner.items = self.items.clone();
}
Expand Down
27 changes: 27 additions & 0 deletions src/tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use std::sync::Arc;

use nucleo_matcher::Config;

use crate::Nucleo;

#[test]
fn active_injector_count() {
let mut nucleo: Nucleo<()> = Nucleo::new(Config::DEFAULT, Arc::new(|| ()), Some(1), 1);
assert_eq!(nucleo.active_injectors(), 0);
let injector = nucleo.injector();
assert_eq!(nucleo.active_injectors(), 1);
let injector2 = nucleo.injector();
assert_eq!(nucleo.active_injectors(), 2);
drop(injector2);
assert_eq!(nucleo.active_injectors(), 1);
nucleo.restart(false);
assert_eq!(nucleo.active_injectors(), 0);
let injector3 = nucleo.injector();
assert_eq!(nucleo.active_injectors(), 1);
nucleo.tick(0);
assert_eq!(nucleo.active_injectors(), 1);
drop(injector);
assert_eq!(nucleo.active_injectors(), 1);
drop(injector3);
assert_eq!(nucleo.active_injectors(), 0);
}

0 comments on commit 980413f

Please sign in to comment.