-
Notifications
You must be signed in to change notification settings - Fork 32
queue: support priority queue #72
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 9 commits
1b9d2d4
d7dc51b
5e35595
4bde2f5
c652691
dd767d2
4a056c4
298e50e
c9c1050
9dcf235
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,6 +9,7 @@ | |
//! data structs. | ||
|
||
pub mod multilevel; | ||
pub mod priority; | ||
|
||
mod extras; | ||
mod single_level; | ||
|
@@ -18,7 +19,7 @@ pub use self::extras::Extras; | |
use std::time::Instant; | ||
|
||
/// A cell containing a task and needed extra information. | ||
pub trait TaskCell { | ||
pub trait TaskCell: 'static { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The skiplist's value must be 'static. I think it's fair that a task spawned in the thread pool should live long enough. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't see why skiplist's value should be 'static. Technically, as long as the value outlive skiplist, it should be OK. If that's an API shortcoming, then the constraint should be put into priority queue instead of here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks like an API shortcoming. I tried making the constraint priority-queue-only, but because we use |
||
/// Gets mutable extra information. | ||
fn mut_extras(&mut self) -> &mut Extras; | ||
} | ||
|
@@ -42,6 +43,7 @@ pub(crate) struct TaskInjector<T>(InjectorInner<T>); | |
enum InjectorInner<T> { | ||
SingleLevel(single_level::TaskInjector<T>), | ||
Multilevel(multilevel::TaskInjector<T>), | ||
Priority(priority::TaskInjector<T>), | ||
} | ||
|
||
impl<T: TaskCell + Send> TaskInjector<T> { | ||
|
@@ -50,13 +52,15 @@ impl<T: TaskCell + Send> TaskInjector<T> { | |
match &self.0 { | ||
InjectorInner::SingleLevel(q) => q.push(task_cell), | ||
InjectorInner::Multilevel(q) => q.push(task_cell), | ||
InjectorInner::Priority(q) => q.push(task_cell), | ||
} | ||
} | ||
|
||
pub fn default_extras(&self) -> Extras { | ||
match self.0 { | ||
InjectorInner::SingleLevel(_) => Extras::single_level(), | ||
InjectorInner::Multilevel(_) => Extras::multilevel_default(), | ||
InjectorInner::Priority(_) => Extras::single_level(), | ||
} | ||
} | ||
} | ||
|
@@ -80,6 +84,7 @@ pub(crate) struct LocalQueue<T>(LocalQueueInner<T>); | |
enum LocalQueueInner<T> { | ||
SingleLevel(single_level::LocalQueue<T>), | ||
Multilevel(multilevel::LocalQueue<T>), | ||
Priority(priority::LocalQueue<T>), | ||
} | ||
|
||
impl<T: TaskCell + Send> LocalQueue<T> { | ||
|
@@ -88,6 +93,7 @@ impl<T: TaskCell + Send> LocalQueue<T> { | |
match &mut self.0 { | ||
LocalQueueInner::SingleLevel(q) => q.push(task_cell), | ||
LocalQueueInner::Multilevel(q) => q.push(task_cell), | ||
LocalQueueInner::Priority(q) => q.push(task_cell), | ||
} | ||
} | ||
|
||
|
@@ -97,13 +103,15 @@ impl<T: TaskCell + Send> LocalQueue<T> { | |
match &mut self.0 { | ||
LocalQueueInner::SingleLevel(q) => q.pop(), | ||
LocalQueueInner::Multilevel(q) => q.pop(), | ||
LocalQueueInner::Priority(q) => q.pop(), | ||
} | ||
} | ||
|
||
pub fn default_extras(&self) -> Extras { | ||
match self.0 { | ||
LocalQueueInner::SingleLevel(_) => Extras::single_level(), | ||
LocalQueueInner::Multilevel(_) => Extras::multilevel_default(), | ||
LocalQueueInner::Priority(_) => Extras::single_level(), | ||
} | ||
} | ||
|
||
|
@@ -113,6 +121,7 @@ impl<T: TaskCell + Send> LocalQueue<T> { | |
match &mut self.0 { | ||
LocalQueueInner::SingleLevel(q) => q.has_tasks_or_pull(), | ||
LocalQueueInner::Multilevel(q) => q.has_tasks_or_pull(), | ||
LocalQueueInner::Priority(q) => q.has_tasks_or_pull(), | ||
} | ||
} | ||
} | ||
|
@@ -125,6 +134,8 @@ pub enum QueueType { | |
/// | ||
/// More to see: https://en.wikipedia.org/wiki/Multilevel_feedback_queue. | ||
Multilevel(multilevel::Builder), | ||
/// A concurrent prioirty queue. | ||
Priority(priority::Builder), | ||
} | ||
|
||
impl Default for QueueType { | ||
|
@@ -139,10 +150,17 @@ impl From<multilevel::Builder> for QueueType { | |
} | ||
} | ||
|
||
impl From<priority::Builder> for QueueType { | ||
fn from(b: priority::Builder) -> QueueType { | ||
QueueType::Priority(b) | ||
} | ||
} | ||
|
||
pub(crate) fn build<T>(ty: QueueType, local_num: usize) -> (TaskInjector<T>, Vec<LocalQueue<T>>) { | ||
match ty { | ||
QueueType::SingleLevel => single_level(local_num), | ||
QueueType::Multilevel(b) => b.build(local_num), | ||
QueueType::Priority(b) => b.build(local_num), | ||
} | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
comment