Compare commits

...

2 commits

3 changed files with 118 additions and 6 deletions

View file

@ -0,0 +1,53 @@
use std::{collections::HashMap, hash::Hash};
use crate::backing::{containers::Pair, indexed::IndexedBacking, pure::PureBacking};
pub struct IndexedBinaryHeap<D: Hash + Clone + Send + Sync, P: PartialOrd + Clone + Send + Sync> {
data: Vec<Pair<D, P>>,
indices: HashMap<D, usize>,
}
impl<D: Hash + Clone + Send + Sync, P: PartialOrd + Clone + Send + Sync> IndexedBinaryHeap<D, P> {
pub fn new() -> Self {
Self {
data: Vec::new(),
indices: HashMap::new(),
}
}
}
impl<D: Hash + Clone + Send + Sync, P: PartialOrd + Clone + Send + Sync> FromIterator<Pair<D, P>>
for IndexedBinaryHeap<D, P>
{
fn from_iter<T: IntoIterator<Item = Pair<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!()
}
}
impl<D: Hash + Clone + Send + Sync, P: PartialOrd + Clone + Send + Sync> IndexedBacking<D, P>
for IndexedBinaryHeap<D, P>
{
fn update(&mut self, data: D, priority: P) -> bool {
todo!()
}
fn remove(&mut self, data: D) -> bool {
todo!()
}
}

View file

@ -1,4 +1,8 @@
/// Data structures for the "indexed" min-queues, supporting priority updates and arbitrary removals, but no duplicates
mod binary_heap;
pub use binary_heap::IndexedBinaryHeap;
use super::{containers::Pair, pure::PureBacking};
/// A data structure usable for backing an "indexed" queue
@ -6,7 +10,7 @@ pub trait IndexedBacking<D: Clone + Send + Sync, P: PartialOrd + Clone + Send +
PureBacking<Pair<D, P>>
{
/// Update an item's priority
fn update(data: D, priority: P) -> Result<(), ()>;
fn update(&mut self, data: D, priority: P) -> bool;
/// Remove an item from the queue
fn remove(data: D) -> bool;
fn remove(&mut self, data: D) -> bool;
}

View file

@ -1,12 +1,67 @@
use pyo3::prelude::*;
use pyo3::{
exceptions::{PyIndexError, PyStopIteration},
prelude::*,
types::PyType,
};
use crate::backing::indexed::IndexedBacking;
#[pyclass]
pub struct IndexedQueue {}
pub struct IndexedQueue {
backing: Box<dyn IndexedBacking<Py<PyAny>, f64>>,
}
#[pymethods]
impl IndexedQueue {
#[new]
fn new() -> Self {
Self {}
#[pyo3(signature = (items=None))]
fn new(items: Option<Py<PyAny>>) -> PyResult<Self> {
if let Some(py_object) = items {
todo!()
} else {
todo!() // TBD: Determine best way to make Python object hashable from Rust
}
}
fn __setitem__(mut self_: PyRefMut<'_, Self>, key: Py<PyAny>, value: Py<PyAny>) {
todo!()
}
fn __delitem__(mut self_: PyRefMut<'_, Self>, key: Py<PyAny>) {
todo!()
}
fn __contains__(mut self_: PyRefMut<'_, Self>, key: Py<PyAny>) {
todo!()
}
/// 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, _>(()))
}
}
}