Fully implement PureQueue
This commit is contained in:
parent
608ff1a3d5
commit
7184ddb9b0
3 changed files with 56 additions and 11 deletions
|
@ -8,12 +8,12 @@ pub struct PyItem(Py<PyAny>);
|
||||||
|
|
||||||
impl PyItem {
|
impl PyItem {
|
||||||
/// Creates a new instance
|
/// Creates a new instance
|
||||||
fn new(item: Py<PyAny>) -> Self {
|
pub fn new(item: Py<PyAny>) -> Self {
|
||||||
PyItem(item)
|
PyItem(item)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieves the internal data
|
/// Retrieves the internal data
|
||||||
fn item(self) -> Py<PyAny> {
|
pub fn data(self) -> Py<PyAny> {
|
||||||
self.0
|
self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
/// A "paired" priority queue that links some data to a priority and supports duplicates, but not arbitrary deletions or weight updates
|
|
||||||
use crate::backing::{
|
use crate::backing::{
|
||||||
containers::Pair,
|
containers::Pair,
|
||||||
pure::{BinaryHeap, PureBacking},
|
pure::{BinaryHeap, PureBacking},
|
||||||
|
@ -14,6 +13,7 @@ pub struct PairedQueue {
|
||||||
backing: Box<dyn PureBacking<Pair<Py<PyAny>, f64>>>,
|
backing: Box<dyn PureBacking<Pair<Py<PyAny>, f64>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A "paired" priority queue that links some data to a priority and supports duplicates, but not arbitrary deletions or priority updates
|
||||||
#[pymethods]
|
#[pymethods]
|
||||||
impl PairedQueue {
|
impl PairedQueue {
|
||||||
/// Enables generic typing
|
/// Enables generic typing
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
use pyo3::{prelude::*, types::PyType};
|
use pyo3::{
|
||||||
|
exceptions::{PyIndexError, PyStopIteration, PyTypeError},
|
||||||
|
prelude::*,
|
||||||
|
types::PyType,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::backing::{
|
use crate::backing::{
|
||||||
containers::PyItem,
|
containers::PyItem,
|
||||||
|
@ -10,23 +14,64 @@ pub struct PureQueue {
|
||||||
backing: Box<dyn PureBacking<PyItem>>,
|
backing: Box<dyn PureBacking<PyItem>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A "pure" priority queue just contains the priorities without any linked data, and does not support arbitrary deletions or priority updates
|
||||||
#[pymethods]
|
#[pymethods]
|
||||||
impl PureQueue {
|
impl PureQueue {
|
||||||
/// Enables generic typing
|
|
||||||
#[classmethod]
|
|
||||||
fn __class_getitem__(cls_: Bound<'_, PyType>, _key: Py<PyAny>) -> Bound<'_, PyType> {
|
|
||||||
cls_
|
|
||||||
}
|
|
||||||
|
|
||||||
#[new]
|
#[new]
|
||||||
#[pyo3(signature = (items=None))]
|
#[pyo3(signature = (items=None))]
|
||||||
fn new(items: Option<Py<PyAny>>) -> PyResult<Self> {
|
fn new(items: Option<Py<PyAny>>) -> PyResult<Self> {
|
||||||
if let Some(py_object) = items {
|
if let Some(py_object) = items {
|
||||||
todo!()
|
Python::with_gil(|py| {
|
||||||
|
if let Ok(vec) = py_object.extract::<Vec<Py<PyAny>>>(py) {
|
||||||
|
Ok(Self {
|
||||||
|
backing: Box::new(BinaryHeap::from_iter(vec.into_iter().map(PyItem::new))),
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Err(PyErr::new::<PyTypeError, _>("Items was not a sequence"))
|
||||||
|
}
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
backing: Box::new(BinaryHeap::new()),
|
backing: Box::new(BinaryHeap::new()),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn insert(mut self_: PyRefMut<'_, Self>, item: Py<PyAny>) {
|
||||||
|
self_.backing.add(PyItem::new(item));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Below methods are identical to PairedQueue
|
||||||
|
// Normally I'd try to solve using a trait with default implementations but that doesn't seem to play nice with #[pymethods]
|
||||||
|
// (Although I shouldn't rule it out)
|
||||||
|
|
||||||
|
/// Enables generic typing
|
||||||
|
#[classmethod]
|
||||||
|
fn __class_getitem__(cls_: Bound<'_, PyType>, _key: Py<PyAny>) -> Bound<'_, PyType> {
|
||||||
|
cls_
|
||||||
|
}
|
||||||
|
|
||||||
|
fn __len__(self_: PyRef<'_, Self>) -> usize {
|
||||||
|
self_.backing.len()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn __iter__(self_: PyRef<'_, Self>) -> PyRef<'_, Self> {
|
||||||
|
self_
|
||||||
|
}
|
||||||
|
|
||||||
|
fn __next__(mut self_: PyRefMut<'_, Self>) -> PyResult<Py<PyAny>> {
|
||||||
|
if let Some(item) = self_.backing.pop() {
|
||||||
|
Ok(item.data())
|
||||||
|
} else {
|
||||||
|
Err(PyErr::new::<PyStopIteration, _>(()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pop(mut self_: PyRefMut<'_, Self>) -> PyResult<Py<PyAny>> {
|
||||||
|
if let Some(item) = self_.backing.pop() {
|
||||||
|
Ok(item.data())
|
||||||
|
} else {
|
||||||
|
Err(PyErr::new::<PyIndexError, _>(()))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue