[][src]Struct retriever::types::reduction::Reduction

pub struct Reduction<ChunkKey: ?Sized, Element, Summary> where
    ChunkKey: BorrowedKey,
    ChunkKey::Owned: ValidKey
{ /* fields omitted */ }

Summarize a Storage using a cached multi-layered reduction strategy. Repeated evaluations will only re-compute the parts of the reduction that have changed. If you've used map-reduce in something like CouchDB, this is a lot like that.

Type Parameters

  • ChunkKey: matches the ChunkKey of the Storage.
  • Element: matches the Element of the Storage.
  • Summary: this is the type of the result of summarizing all of the Elements in Storage.

Methods

impl<ChunkKey: ?Sized, Element, Summary> Reduction<ChunkKey, Element, Summary> where
    ChunkKey: BorrowedKey,
    ChunkKey::Owned: ValidKey,
    Summary: Default + Clone
[src]

pub fn new<ItemKey: ?Sized, Map, Fold>(
    storage: &Storage<ChunkKey, ItemKey, Element>,
    group_size: usize,
    map: Map,
    fold: Fold
) -> Self where
    ItemKey: BorrowedKey,
    ItemKey::Owned: ValidKey,
    Element: Record<ChunkKey, ItemKey>,
    Map: Fn(&Element, &Summary) -> Option<Summary> + Clone + Send + Sync + 'static,
    Fold: Fn(&[Summary], &Summary) -> Option<Summary> + Clone + Send + Sync + 'static, 
[src]

Create a new Reduction on a Storage.

A Reduction is constructed from two rules: Map and Fold (or reduce). The only difference between these rules is that the Map rule examines a single element while the Fold rule examines a list of Summaries. Both rules receive a reference to the old Summary. If the Summary has never been evaluated before, then the old Summary will be Summary::default().

Each rule constructs a new Summary, and if the new Summary is different from the old Summary, returns Some(new_summary). If the Summary is unchanged, indicate this by returning None.

Try to re-use Reductions as much as possible. If you drop a Reduction and re-create it, then the Reduction's internal index has to be rebuilt, which might take a lot of time.

Type Parameters

  • ItemKey: this is the ItemKey matching the Storage.
  • Map: this operation produces a Summary of a single Element. If the result Summary has not changed since the last Summary, return None.
  • Fold: this operations folds several Summaries into one Summary. If the result Summary has not changed since the last Summary, return None.

pub fn reduce<ItemKey: ?Sized>(
    &mut self,
    storage: &Storage<ChunkKey, ItemKey, Element>
) -> Option<&Summary> where
    Element: Record<ChunkKey, ItemKey>,
    ItemKey: BorrowedKey,
    ItemKey::Owned: ValidKey
[src]

Reduce all of the elements of the given Storage down to a single value.

Example

use retriever::prelude::*;
use std::borrow::Cow;
use std::collections::HashSet;

#[derive(Clone, Eq, PartialEq)]
struct Notification {
  user_id: usize,
  id: usize,
  priority: usize,
  msg: String,
  service: &'static str,
}

#[derive(Clone,Default,Eq,PartialEq)]
struct NotificationSummary {
  count: usize,
  priority: usize,
  services: HashSet<&'static str>,
}

impl Record<usize, usize> for Notification {
  fn chunk_key(&self) -> Cow<usize> {
    Cow::Owned(self.user_id)
  }

  fn item_key(&self) -> Cow<usize> {
    Cow::Owned(self.id)
  }
}

impl NotificationSummary {
  fn add_one(&mut self, n: &Notification) {
    self.count += 1;
    self.priority = self.priority.max(n.priority);
    self.services.insert(n.service);
  }

  fn add_summary(&mut self, s: &NotificationSummary) {
    self.count += s.count;
    self.priority = self.priority.max(s.priority);

    for i in s.services.iter() {
      self.services.insert(*i);
    }
  }
}

let mut storage : Storage<usize, usize, Notification> = Storage::new();
let mut reduction : Reduction<usize, Notification, NotificationSummary> =
  Reduction::new(
    &storage,
    2,
    |element: &Notification, was: &NotificationSummary| {
      let mut summary = NotificationSummary::default();
      summary.add_one(element);
      if &summary != was {
        Some(summary)
      } else {
        None
      }
    },
    |notifications: &[NotificationSummary], was: &NotificationSummary| {
      let mut summary = NotificationSummary::default();

      for n in notifications {
        summary.add_summary(n);
      }

      if &summary != was {
        Some(summary)
      } else {
        None
      }
    }
  );

storage.add(Notification {
  user_id: 1000,
  id: 1,
  priority: 2,
  msg: String::from("You have mail!"),
  service: "mail",
});

storage.add(Notification {
  user_id: 1000,
  id: 2,
  priority: 2,
  msg: String::from("New email from Susan."),
  service: "mail",
});

storage.add(Notification {
  user_id: 0,
  id: 3,
  priority: 8,
  msg: String::from("Battery low"),
  service: "power",
});

storage.add(Notification {
  user_id: 1000,
  id: 4,
  priority: 0,
  msg: String::from("You have won 13 gold coins!!"),
  service: "games",
});

let summary = reduction.reduce(&storage).unwrap();

assert_eq!(summary.count, 4);
assert_eq!(summary.priority, 8);
assert!(summary.services.contains("power"));
assert!(summary.services.contains("mail"));
assert!(summary.services.contains("games"));

pub fn reduce_chunk<ItemKey: ?Sized>(
    &mut self,
    storage: &Storage<ChunkKey, ItemKey, Element>,
    chunk_key: &ChunkKey
) -> Option<&Summary> where
    Element: Record<ChunkKey, ItemKey>,
    ItemKey: BorrowedKey,
    ItemKey::Owned: ValidKey
[src]

Reduce all of the elements of a single chunk down to a single value.

Auto Trait Implementations

impl<ChunkKey: ?Sized, Element, Summary> Send for Reduction<ChunkKey, Element, Summary> where
    Summary: Send,
    <ChunkKey as ToOwned>::Owned: Send

impl<ChunkKey: ?Sized, Element, Summary> Sync for Reduction<ChunkKey, Element, Summary> where
    Summary: Sync,
    <ChunkKey as ToOwned>::Owned: Sync

impl<ChunkKey: ?Sized, Element, Summary> Unpin for Reduction<ChunkKey, Element, Summary> where
    Summary: Unpin,
    <ChunkKey as ToOwned>::Owned: Unpin

impl<ChunkKey, Element, Summary> !UnwindSafe for Reduction<ChunkKey, Element, Summary>

impl<ChunkKey, Element, Summary> !RefUnwindSafe for Reduction<ChunkKey, Element, Summary>

Blanket Implementations

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> From<T> for T[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]