Simplify IndexedQueue API
Although similar to PureQueue, it doesn't make sense to use the exact same signatures. Also don't make API users use Pair<D, P>.
This commit is contained in:
parent
16c1a4d390
commit
63515e2314
3 changed files with 40 additions and 56 deletions
|
@ -1,6 +1,6 @@
|
||||||
use std::{collections::HashMap, hash::Hash};
|
use std::{collections::HashMap, hash::Hash};
|
||||||
|
|
||||||
use crate::backing::{containers::Pair, indexed::IndexedBacking, pure::PureBacking};
|
use crate::backing::{containers::Pair, indexed::IndexedBacking};
|
||||||
|
|
||||||
pub struct IndexedBinaryHeap<D: Hash + Clone + Send + Sync, P: PartialOrd + Clone + Send + Sync> {
|
pub struct IndexedBinaryHeap<D: Hash + Clone + Send + Sync, P: PartialOrd + Clone + Send + Sync> {
|
||||||
data: Vec<Pair<D, P>>,
|
data: Vec<Pair<D, P>>,
|
||||||
|
@ -16,26 +16,10 @@ impl<D: Hash + Clone + Send + Sync, P: PartialOrd + Clone + Send + Sync> Indexed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: Hash + Clone + Send + Sync, P: PartialOrd + Clone + Send + Sync> FromIterator<Pair<D, P>>
|
impl<D: Hash + Clone + Send + Sync, P: PartialOrd + Clone + Send + Sync> FromIterator<(D, P)>
|
||||||
for IndexedBinaryHeap<D, P>
|
for IndexedBinaryHeap<D, P>
|
||||||
{
|
{
|
||||||
fn from_iter<T: IntoIterator<Item = Pair<D, P>>>(iter: T) -> Self {
|
fn from_iter<T: IntoIterator<Item = (D, P)>>(iter: T) -> Self {
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<D: Hash + Clone + Send + Sync, P: PartialOrd + Clone + Send + Sync> PureBacking<Pair<D, P>>
|
|
||||||
for IndexedBinaryHeap<D, P>
|
|
||||||
{
|
|
||||||
fn add(&mut self, item: Pair<D, P>) {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn pop(&mut self) -> Option<Pair<D, P>> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn len(&self) -> usize {
|
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,15 +27,23 @@ impl<D: Hash + Clone + Send + Sync, P: PartialOrd + Clone + Send + Sync> PureBac
|
||||||
impl<D: Hash + Clone + Send + Sync, P: PartialOrd + Clone + Send + Sync> IndexedBacking<D, P>
|
impl<D: Hash + Clone + Send + Sync, P: PartialOrd + Clone + Send + Sync> IndexedBacking<D, P>
|
||||||
for IndexedBinaryHeap<D, P>
|
for IndexedBinaryHeap<D, P>
|
||||||
{
|
{
|
||||||
fn update(&mut self, data: D, priority: P) -> bool {
|
fn len(&self) -> usize {
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remove(&mut self, data: D) -> bool {
|
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn contains(&self, data: &D) -> bool {
|
fn contains(&self, data: &D) -> bool {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set(&mut self, data: D, priority: P) {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove(&mut self, data: D) -> Option<P> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pop(&mut self) -> Option<D> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,16 +3,18 @@ mod binary_heap;
|
||||||
|
|
||||||
pub use binary_heap::IndexedBinaryHeap;
|
pub use binary_heap::IndexedBinaryHeap;
|
||||||
|
|
||||||
use super::{containers::Pair, pure::PureBacking};
|
|
||||||
|
|
||||||
/// A data structure usable for backing an "indexed" queue
|
/// A data structure usable for backing an "indexed" queue
|
||||||
pub trait IndexedBacking<D: Clone + Send + Sync, P: PartialOrd + Clone + Send + Sync>:
|
pub trait IndexedBacking<D: Clone + Send + Sync, P: PartialOrd + Clone + Send + Sync>:
|
||||||
PureBacking<Pair<D, P>>
|
Send + Sync
|
||||||
{
|
{
|
||||||
/// Update an item's priority
|
/// The length of the queue
|
||||||
fn update(&mut self, data: D, priority: P) -> bool;
|
fn len(&self) -> usize;
|
||||||
/// Remove an item from the queue
|
|
||||||
fn remove(&mut self, data: D) -> bool;
|
|
||||||
/// Check if an item is already in the queue
|
/// Check if an item is already in the queue
|
||||||
fn contains(&self, data: &D) -> bool;
|
fn contains(&self, data: &D) -> bool;
|
||||||
|
/// Set an item's priority, will update if the item is already enqueued
|
||||||
|
fn set(&mut self, data: D, priority: P);
|
||||||
|
/// Remove a specific item from the queue, returns the associated priority if the item existed
|
||||||
|
fn remove(&mut self, data: D) -> Option<P>;
|
||||||
|
/// Remove the top of the queue, if it exists
|
||||||
|
fn pop(&mut self) -> Option<D>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
use pyo3::{
|
use pyo3::{
|
||||||
exceptions::{PyIndexError, PyKeyError, PyRuntimeError, PyStopIteration, PyTypeError},
|
exceptions::{PyIndexError, PyKeyError, PyStopIteration, PyTypeError},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
types::{PyDict, PyType},
|
types::{PyDict, PyType},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::backing::{
|
use crate::backing::{
|
||||||
containers::{Pair, PyItem},
|
containers::PyItem,
|
||||||
indexed::{IndexedBacking, IndexedBinaryHeap},
|
indexed::{IndexedBacking, IndexedBinaryHeap},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -35,26 +35,16 @@ impl IndexedQueue {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn __setitem__(mut self_: PyRefMut<'_, Self>, key: Py<PyAny>, value: f64) -> PyResult<()> {
|
fn __setitem__(mut self_: PyRefMut<'_, Self>, key: Py<PyAny>, value: f64) {
|
||||||
let data = PyItem::new(key);
|
self_.backing.set(PyItem::new(key), value)
|
||||||
if self_.backing.contains(&data) {
|
|
||||||
if self_.backing.update(data, value) {
|
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
Err(PyErr::new::<PyRuntimeError, _>("Key could not be updated"))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Ok(self_.backing.add(Pair::new(data, value)))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn __delitem__(mut self_: PyRefMut<'_, Self>, key: Py<PyAny>) -> PyResult<()> {
|
fn __delitem__(mut self_: PyRefMut<'_, Self>, key: Py<PyAny>) -> PyResult<()> {
|
||||||
if self_.backing.remove(PyItem::new(key)) {
|
match self_.backing.remove(PyItem::new(key)) {
|
||||||
Ok(())
|
Some(_) => Ok(()),
|
||||||
} else {
|
None => Err(PyErr::new::<PyKeyError, _>(
|
||||||
Err(PyErr::new::<PyKeyError, _>(
|
|
||||||
"Key was not contained in queue",
|
"Key was not contained in queue",
|
||||||
))
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +68,7 @@ impl IndexedQueue {
|
||||||
|
|
||||||
fn __next__(mut self_: PyRefMut<'_, Self>) -> PyResult<Py<PyAny>> {
|
fn __next__(mut self_: PyRefMut<'_, Self>) -> PyResult<Py<PyAny>> {
|
||||||
if let Some(item) = self_.backing.pop() {
|
if let Some(item) = self_.backing.pop() {
|
||||||
Ok(item.data().data())
|
Ok(item.data())
|
||||||
} else {
|
} else {
|
||||||
Err(PyErr::new::<PyStopIteration, _>(()))
|
Err(PyErr::new::<PyStopIteration, _>(()))
|
||||||
}
|
}
|
||||||
|
@ -86,7 +76,7 @@ impl IndexedQueue {
|
||||||
|
|
||||||
fn pop(mut self_: PyRefMut<'_, Self>) -> PyResult<Py<PyAny>> {
|
fn pop(mut self_: PyRefMut<'_, Self>) -> PyResult<Py<PyAny>> {
|
||||||
if let Some(item) = self_.backing.pop() {
|
if let Some(item) = self_.backing.pop() {
|
||||||
Ok(item.data().data())
|
Ok(item.data())
|
||||||
} else {
|
} else {
|
||||||
Err(PyErr::new::<PyIndexError, _>(()))
|
Err(PyErr::new::<PyIndexError, _>(()))
|
||||||
}
|
}
|
||||||
|
@ -95,7 +85,7 @@ impl IndexedQueue {
|
||||||
|
|
||||||
impl<'py> IndexedQueue {
|
impl<'py> IndexedQueue {
|
||||||
/// Tries to a Python object into a vector suitable for ingestion into the backing
|
/// Tries to a Python object into a vector suitable for ingestion into the backing
|
||||||
fn from_any(object: &Bound<'py, PyAny>) -> PyResult<Vec<Pair<PyItem, f64>>> {
|
fn from_any(object: &Bound<'py, PyAny>) -> PyResult<Vec<(PyItem, f64)>> {
|
||||||
if let Ok(vec) = object.extract::<Vec<(Py<PyAny>, f64)>>() {
|
if let Ok(vec) = object.extract::<Vec<(Py<PyAny>, f64)>>() {
|
||||||
Ok(Self::from_vec(vec))
|
Ok(Self::from_vec(vec))
|
||||||
} else {
|
} else {
|
||||||
|
@ -116,18 +106,18 @@ impl<'py> IndexedQueue {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a vector of Python objects and priorities into a vector of items
|
/// Converts a vector of Python objects and priorities into a vector of items
|
||||||
fn from_vec(list: Vec<(Py<PyAny>, f64)>) -> Vec<Pair<PyItem, f64>> {
|
fn from_vec(list: Vec<(Py<PyAny>, f64)>) -> Vec<(PyItem, f64)> {
|
||||||
list.into_iter()
|
list.into_iter()
|
||||||
.map(|(data, priority)| Pair::new(PyItem::new(data), priority))
|
.map(|(data, priority)| (PyItem::new(data), priority))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a Python dictionary into a vector of items
|
/// Converts a Python dictionary into a vector of items
|
||||||
fn from_dict(dict: &Bound<'py, PyDict>) -> PyResult<Vec<Pair<PyItem, f64>>> {
|
fn from_dict(dict: &Bound<'py, PyDict>) -> PyResult<Vec<(PyItem, f64)>> {
|
||||||
if let Ok(items) = dict
|
if let Ok(items) = dict
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(data, priority)| match priority.extract::<f64>() {
|
.map(|(data, priority)| match priority.extract::<f64>() {
|
||||||
Ok(value) => Ok(Pair::new(PyItem::new(data.unbind()), value)),
|
Ok(value) => Ok((PyItem::new(data.unbind()), value)),
|
||||||
Err(err) => Err(err),
|
Err(err) => Err(err),
|
||||||
})
|
})
|
||||||
.collect::<Result<Vec<_>, _>>()
|
.collect::<Result<Vec<_>, _>>()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue