BucketStrainer

Struct BucketStrainer 

Source
pub struct BucketStrainer<T>
where T: Clone,
{ /* private fields */ }
Expand description

Bucket strainer is a data collection processor that splits and sorts input data into buckets with rules that item must obey to fall into them. Items that does not obey any bucket rule, are leftovers returned by processing.

Best problem that bucket strainer can solve is task commander that will sort AI agents into buckets that represent different tasks to perform.

§How it works

  1. Bucket strainer contains layers of filtering organized in sequential manner, so there is more possibility for items to fall into first layers than into last layers.
  2. Each layer contains buckets that will compete for incomming items, item can fall only into one of all layer buckets and that bucket is selected based on highest score that bucket will get from item based on bucket rules.
  3. Each Bucket contains collection of items that fall into them and main rule that will score each incomming item and use that score to tell processor which bucket got highest score and by that which bucket will get incoming item.

Implementations§

Source§

impl<T> BucketStrainer<T>
where T: Clone,

Source

pub fn new(layers: Vec<Layer<T>>) -> Self

Creates bucket strainer processor.

§Arguments
  • layers - List of layers that will process incoming items.
§Return

Instance of bucket strainer.

§Example
use psyche_utils::Scalar;
use psyche_utils::bucket_strainer::{BucketStrainer, Layer, Bucket, Rule};

#[derive(Clone, Copy)]
enum EvenOrOddRule {
    Even,
    Odd,
}

impl Rule<i32> for EvenOrOddRule {
    fn score(&self, item: &i32, _: &Bucket<i32>) -> Scalar {
        let even = match self {
            EvenOrOddRule::Even => 0,
            EvenOrOddRule::Odd => 1,
        };
        if *item % 2 == even {
            1.0
        } else {
            0.0
        }
    }

    fn box_clone(&self) -> Box<dyn Rule<i32>> {
        Box::new((*self).clone())
    }
}

let bs = BucketStrainer::new(vec![
    Layer::new(vec![
        Bucket::new("even".to_owned(), Box::new(EvenOrOddRule::Even)),
    ]),
    Layer::new(vec![
        Bucket::new("odd".to_owned(), Box::new(EvenOrOddRule::Odd)),
    ]),
]);
Source

pub fn layers(&self) -> &[Layer<T>]

Gets list of layers.

§Return

Reference to slice of layers.

Source

pub fn replace_layers(&mut self, layers: Vec<Layer<T>>) -> Vec<Layer<T>>

Replace existing layers with new ones.

§Arguments
  • layers - List of new layers.
§Return

List of old layers.

§Example
use psyche_utils::bucket_strainer::{BucketStrainer, Layer, Bucket, BucketLimitRule};

let mut bs = BucketStrainer::<()>::new(vec![]);
bs.replace_layers(vec![
    Bucket::new("limit".to_owned(), Box::new(BucketLimitRule::new(3))).into(),
]);
Source

pub fn bucket(&self, id: &str) -> Option<&Bucket<T>>

Finds bucket by its ID.

§Arguments
  • id - Bucket ID.
§Return

Reference to bucket.

§Example
use psyche_utils::bucket_strainer::{BucketStrainer, Layer, Bucket, BucketLimitRule};

let bs = BucketStrainer::<()>::new(vec![
    Bucket::new("limit".to_owned(), Box::new(BucketLimitRule::new(3))).into(),
]);
assert!(bs.bucket("limit").is_some());
Source

pub fn clear_layers_buckets(&mut self)

Clears all layers buckets items collections.

§Example
use psyche_utils::bucket_strainer::{BucketStrainer, Layer, Bucket, BucketLimitRule};

let mut bs = BucketStrainer::new(vec![
    Bucket::new("limit".to_owned(), Box::new(BucketLimitRule::new(3))).into(),
]);
bs.process(vec![0, 1, 2, 3, 4, 5, 6]);
assert_eq!(bs.bucket("limit").unwrap().items().len(), 3);
bs.clear_layers_buckets();
assert_eq!(bs.bucket("limit").unwrap().items().len(), 0);
Source

pub fn process(&mut self, items: Vec<T>) -> Vec<T>

Process input items.

§Arguments
  • items - List of items to process.
§Return

Processed items leftovers that does not fall into any bucket.

§Example
use psyche_utils::bucket_strainer::{BucketStrainer, Layer, Bucket, BucketLimitRule};

let mut bs = BucketStrainer::new(vec![
    Bucket::new("limitA".to_owned(), Box::new(BucketLimitRule::new(3))).into(),
    Bucket::new("limitB".to_owned(), Box::new(BucketLimitRule::new(2))).into(),
]);
let leftovers = bs.process(vec![0, 1, 2, 3, 4, 5, 6]);
assert_eq!(bs.bucket("limitA").unwrap().items(), &[0, 1, 2]);
assert_eq!(bs.bucket("limitB").unwrap().items(), &[3, 4]);
assert_eq!(&leftovers, &[5, 6]);
Source

pub fn buckets_items_pairs<'a>(&'a self) -> Vec<(&'a str, &'a [T])>

Get list of bucket with their items pairs.

§Return

Pairs of buckets with their items.

§Example
use psyche_utils::bucket_strainer::{BucketStrainer, Layer, Bucket, BucketLimitRule};

let mut bs = BucketStrainer::new(vec![
    Bucket::new("limitA".to_owned(), Box::new(BucketLimitRule::new(3))).into(),
    Bucket::new("limitB".to_owned(), Box::new(BucketLimitRule::new(2))).into(),
]);
bs.process(vec![0, 1, 2, 3, 4, 5, 6]);
let pairs = bs.buckets_items_pairs();
assert_eq!(pairs.len(), 2);
assert_eq!(pairs[0].0, "limitA");
assert_eq!(pairs[0].1.to_vec(), vec![0, 1, 2]);
assert_eq!(pairs[1].0, "limitB");
assert_eq!(pairs[1].1.to_vec(), vec![3, 4]);

Trait Implementations§

Source§

impl<T> Clone for BucketStrainer<T>
where T: Clone + Clone,

Source§

fn clone(&self) -> BucketStrainer<T>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more

Auto Trait Implementations§

§

impl<T> Freeze for BucketStrainer<T>

§

impl<T> !RefUnwindSafe for BucketStrainer<T>

§

impl<T> !Send for BucketStrainer<T>

§

impl<T> !Sync for BucketStrainer<T>

§

impl<T> Unpin for BucketStrainer<T>
where T: Unpin,

§

impl<T> !UnwindSafe for BucketStrainer<T>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.