Last active
August 7, 2019 17:57
-
-
Save max6cn/8e42cacffecfce07920f6fecba936dad to your computer and use it in GitHub Desktop.
Q Framework
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pub struct Context<'a , T = i32>{ | |
simulator: *mut Simulator, | |
servers : *mut Server, | |
generator: *mut Generator, | |
events: *mut EventQueue, | |
queue: *mut Queue, | |
_marker: PhantomData<&'a T>, | |
} | |
impl <'a, T> Context<'a, T>{ | |
pub fn get_simulator(&self) -> &'a mut Simulator { | |
let ptr = unsafe { &mut *self.simulator }; | |
ptr | |
} | |
pub fn get_servers(&self) -> &'a mut Server { | |
let ptr = unsafe { &mut *self.servers }; | |
ptr | |
} | |
pub fn get_generator(&self) -> &'a mut Generator { | |
let ptr = unsafe { &mut *self.generator }; | |
ptr | |
} | |
pub fn get_events(&self) -> &'a mut EventQueue { | |
let ptr = unsafe { &mut *self.events }; | |
ptr | |
} | |
pub fn get_queue(&self) -> &'a mut Queue { | |
let ptr = unsafe { &mut *self.queue }; | |
ptr | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pub struct Event { | |
id: EventId, | |
clock: Clock, | |
etype: EventType | |
} | |
// | |
// Explicitly implement the trait so the queue becomes a min-heap instead of a max-heap. | |
impl Ord for Event { | |
fn cmp(&self, other: &Self) -> Ordering { | |
other.clock.cmp(&self.clock) | |
} | |
} | |
impl PartialOrd for Event { | |
fn partial_cmp(&self, other: &Self) -> Option<Ordering> { | |
Some(other.get_clock().cmp(&self.get_clock())) | |
} | |
} | |
impl PartialEq for Event { | |
fn eq(&self, other: &Self) -> bool { | |
self.get_clock() == other.get_clock() | |
} | |
} | |
impl Eq for Event { | |
} | |
impl AbstractEvent for Event { | |
fn execute(&mut self, ctx : &mut Context) { | |
// info!("Running Event"); | |
match self.etype { | |
EventType::ServerEvent => { | |
trace!("Running Server"); | |
let mut server = ctx.get_servers(); | |
server.execute(ctx); | |
}, | |
EventType::GeneratorEvent =>{ | |
trace!("Running Generator"); | |
let mut generator = ctx.get_generator(); | |
generator.execute(ctx); | |
} | |
} | |
} | |
} | |
impl Clocked for Event{ | |
fn get_clock(&self) -> Clock { | |
self.clock | |
} | |
fn set_clock(&mut self, t: Clock) { | |
self.clock = t; | |
} | |
} | |
impl Event{ | |
pub fn new( etype: EventType, clock: Clock) -> Self{ | |
let id = 0; | |
Event {id, clock, etype} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pub struct Generator { | |
max_sim_time: Clock, | |
clock: Clock, | |
pub count: u64, | |
} | |
impl AbstractEvent for Generator { | |
fn execute(&mut self, ctx: &mut Context) { | |
let customer = Customer::new(self.count); | |
info!("{:?} generated {:?}", self.get_clock(), customer); | |
let mut queue = ctx.get_queue(); | |
queue.insert(ctx, customer); | |
self.count += 1; | |
self.clock = 1+ self.clock; | |
if self.get_clock() < self.max_sim_time { | |
let event = Event::new(EventType::GeneratorEvent, self.get_clock()); | |
ctx.get_events().insert(event); | |
} | |
} | |
} | |
impl Clocked for Generator { | |
fn get_clock(&self) -> Clock { | |
self.clock | |
} | |
fn set_clock(&mut self, t: Clock) { | |
self.clock = t; | |
} | |
} | |
impl Generator { | |
pub fn new( max_sim_time: Clock ) -> Self { | |
Generator { max_sim_time, clock: Clock::from(0), count: 0 } | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pub struct Queue{ | |
customers: Vec<Customer>, | |
pub capacity: usize, | |
} | |
impl Queue { | |
pub fn new() -> Self { | |
return Queue {customers: Default::default(), capacity: 10}; | |
} | |
pub fn size(&self) -> usize { | |
self.customers.len() | |
} | |
pub fn insert( &mut self, ctx: &mut Context, customer: Customer) { | |
let mut server = ctx.get_servers(); | |
let mut sim = ctx.get_simulator(); | |
let t = sim.get_clock(); | |
if server.is_available() { | |
server.insert( ctx, Some(customer)); | |
} else if self.customers.len() >= self.capacity { | |
info!("{:?} rejected {:?}", server.get_clock(), customer) ; | |
} else { | |
self.customers.push(customer); | |
trace!("adding customer {:?}", customer); | |
} | |
} | |
pub fn remove(&mut self) -> Option<Customer>{ | |
self.customers.pop() | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pub struct Server { | |
pub total_customers_servered :i32, | |
pub customer_being_served : Option<Customer>, | |
clock: Clock | |
} | |
impl Clocked for Server { | |
fn get_clock(&self) -> Clock { | |
self.clock | |
} | |
fn set_clock(&mut self, t: Clock) { | |
self.clock = t; | |
} | |
} | |
impl Server { | |
pub fn is_available(&self) -> bool { | |
self.customer_being_served.is_none() | |
} | |
pub fn new() -> Self { | |
Server { total_customers_servered: Default::default(), | |
customer_being_served: Default::default(), | |
clock: Clock::from(0)} | |
} | |
pub fn insert( &mut self, ctx: &mut Context, customer: Option<Customer>) { | |
if self.customer_being_served.is_some() { | |
return; | |
} else { | |
self.customer_being_served = customer; | |
self.clock = self.clock + 1; | |
let event = Event::new(EventType::ServerEvent, self.get_clock()); | |
ctx.get_events().insert(event); | |
} | |
} | |
} | |
impl AbstractEvent for Server { | |
fn execute( &mut self, ctx: &mut Context ){ | |
let c = self.customer_being_served.take(); | |
self.total_customers_servered += 1; | |
info!("{:?} serving {:?} \ttotal served {:?}", self.get_clock(), c, self.total_customers_servered); | |
let q = ctx.get_queue(); | |
if let Some(c) = q.remove() { | |
self.insert(ctx, Some(c) ); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
impl Clocked for Simulator { | |
fn get_clock(&self) -> Clock { | |
self.clock | |
} | |
fn set_clock(&mut self, t: Clock) { | |
self.clock = t; | |
} | |
} | |
impl Simulator { | |
pub fn new() -> Simulator { | |
Simulator { clock: Clock::from(0)} | |
} | |
} | |
pub fn do_all_events(ctx: &mut Context) -> (i64,i64,f64) { | |
loop { | |
let event = ctx.get_events().remove_first(); | |
match event { | |
Some(mut e) => { | |
let t = e.get_clock() ; | |
ctx.get_simulator().set_clock(t); | |
e.execute( ctx); | |
} | |
_ => { | |
info!("{:?} Finished All Events",ctx.get_simulator().get_clock()); | |
break; | |
} | |
} | |
} | |
(ctx.get_generator().count as i64, | |
ctx.get_servers().total_customers_servered as i64, | |
ctx.get_simulator().get_clock().get_raw()) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment