Skip to content

Instantly share code, notes, and snippets.

@pzol
Created January 30, 2014 17:47
Show Gist options
  • Save pzol/8714419 to your computer and use it in GitHub Desktop.
Save pzol/8714419 to your computer and use it in GitHub Desktop.
#[ crate_id = "vmod_rpm#0.1" ];
#[ crate_type = "dylib" ];
// #[ no_std ];
#[ allow(ctypes) ];
extern mod extra;
use std::str;
use std::sync::atomics;
use std::sync::atomics::{ AtomicUint, AcqRel };
use std::hashmap::HashMap;
use extra::time;
#[no_mangle]
pub extern fn passable(c_contract: *i8, c_method: *i8) -> bool {
let bucket;
unsafe {
bucket = Bucket { contract: str::raw::from_c_str(c_contract),
method: str::raw::from_c_str(c_method)
}
}
let now = time::now().rfc3339();
let count = increment(&bucket);
let limit = limit(&bucket);
println!("[R {}] {} - {:s} - {}/{}", now, time_bucket(), bucket.to_str(), count, limit);
count < limit
}
#[deriving(IterBytes, Eq)]
struct Bucket {
contract: ~str,
method: ~str
}
impl ToStr for Bucket {
fn to_str(&self) -> ~str {
self.contract + self.method
}
}
fn time_bucket() -> uint {
(time::now().to_timespec().sec / 60 * 60) as uint
}
fn limit(bucket: &Bucket) -> uint {
5
}
fn init() {
println!("init");
unsafe {
counters = Some(HashMap::new());
}
}
static mut counters: Option<HashMap<Bucket, AtomicUint>> = None;
fn increment(bucket: &Bucket) -> uint {
unsafe {
println!("{}", bucket.to_str());
let map = counters.get_mut_ref();
let counter = map.insert_or_update_with(bucket, AtomicUint::new(0), |_, c| {
c.fetch_add(1, atomics::AcqRel);
});
counter.load(atomics::Relaxed)
}
}
#[cfg(test)]
mod tests {
use super::{ init, increment, passable, Bucket };
#[test]
fn test_passable(){
let contract = ~"foo";
let method = ~"bar";
let c_contract;
let c_method;
unsafe {
c_contract = contract.to_c_str().unwrap();
c_method = method.to_c_str().unwrap();
}
let bucket = Bucket { contract: contract, method: method };
init();
assert_eq!(increment(&bucket), 0u);
assert_eq!(increment(&bucket), 1u);
assert_eq!(increment(&bucket), 2u);
assert_eq!(increment(&bucket), 3u);
let mut result = passable(c_contract, c_method);
assert_eq!(result, true);
result = passable(c_contract, c_method);
assert_eq!(result, false);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment