use constants;
use hopper;
use metric;
use mio;
use seahash::SeaHasher;
use slab;
use std::collections;
use std::hash;
use std::ops::{Index, IndexMut};
use std::sync::atomic::{AtomicUsize, Ordering};
pub static UTIL_SEND_HOPPER_ERROR_FULL: AtomicUsize = AtomicUsize::new(0);
pub type HashMap<K, V> =
collections::HashMap<K, V, hash::BuildHasherDefault<SeaHasher>>;
pub type Channel = Vec<hopper::Sender<metric::Event>>;
pub fn send(chans: &mut Channel, mut event: metric::Event) {
if chans.is_empty() {
return;
}
let max: usize = chans.len().saturating_sub(1);
if max != 0 {
for chan in &mut chans[1..] {
let mut snd_event = event.clone();
while let Err(res) = chan.send(snd_event) {
match res.1 {
hopper::Error::Full => {
UTIL_SEND_HOPPER_ERROR_FULL.fetch_add(1, Ordering::Relaxed);
break;
}
_ => {
snd_event = res.0;
continue;
}
}
}
}
}
while let Err(res) = chans[0].send(event) {
match res.1 {
hopper::Error::Full => {
UTIL_SEND_HOPPER_ERROR_FULL.fetch_add(1, Ordering::Relaxed);
break;
}
_ => {
event = res.0;
continue;
}
}
}
}
#[derive(Debug, PartialEq)]
pub enum Valve {
Open,
Closed,
}
#[inline]
fn token_to_idx(token: &mio::Token) -> usize {
match *token {
mio::Token(idx) => idx,
}
}
pub struct TokenSlab<E: mio::Evented> {
tokens: slab::Slab<E>,
}
impl<E: mio::Evented> Default for TokenSlab<E> {
fn default() -> Self {
Self::new()
}
}
impl<E: mio::Evented> Index<mio::Token> for TokenSlab<E> {
type Output = E;
fn index(&self, token: mio::Token) -> &E {
&self.tokens[token_to_idx(&token)]
}
}
impl<E: mio::Evented> IndexMut<mio::Token> for TokenSlab<E> {
fn index_mut(&mut self, token: mio::Token) -> &mut E {
&mut self.tokens[token_to_idx(&token)]
}
}
impl<E: mio::Evented> TokenSlab<E> {
pub fn new() -> TokenSlab<E> {
TokenSlab {
tokens: slab::Slab::with_capacity(token_to_idx(&constants::SYSTEM)),
}
}
pub fn iter(&self) -> slab::Iter<E> {
self.tokens.iter()
}
pub fn insert(&mut self, thing: E) -> mio::Token {
let idx = self.tokens.insert(thing);
mio::Token::from(idx)
}
}