From 63515e2314ad5038132ef7e2e449e28063c7cfff Mon Sep 17 00:00:00 2001 From: Michael Bradley Date: Mon, 13 Jan 2025 22:07:43 +1300 Subject: [PATCH] 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. --- src/backing/indexed/binary_heap.rs | 40 ++++++++++++------------------ src/backing/indexed/mod.rs | 16 ++++++------ src/queue/indexed.rs | 40 +++++++++++------------------- 3 files changed, 40 insertions(+), 56 deletions(-) diff --git a/src/backing/indexed/binary_heap.rs b/src/backing/indexed/binary_heap.rs index 50c3878..84415ec 100644 --- a/src/backing/indexed/binary_heap.rs +++ b/src/backing/indexed/binary_heap.rs @@ -1,6 +1,6 @@ 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 { data: Vec>, @@ -16,26 +16,10 @@ impl Indexed } } -impl FromIterator> +impl FromIterator<(D, P)> for IndexedBinaryHeap { - fn from_iter>>(iter: T) -> Self { - todo!() - } -} - -impl PureBacking> - for IndexedBinaryHeap -{ - fn add(&mut self, item: Pair) { - todo!() - } - - fn pop(&mut self) -> Option> { - todo!() - } - - fn len(&self) -> usize { + fn from_iter>(iter: T) -> Self { todo!() } } @@ -43,15 +27,23 @@ impl PureBac impl IndexedBacking for IndexedBinaryHeap { - fn update(&mut self, data: D, priority: P) -> bool { - todo!() - } - - fn remove(&mut self, data: D) -> bool { + fn len(&self) -> usize { todo!() } fn contains(&self, data: &D) -> bool { todo!() } + + fn set(&mut self, data: D, priority: P) { + todo!() + } + + fn remove(&mut self, data: D) -> Option

{ + todo!() + } + + fn pop(&mut self) -> Option { + todo!() + } } diff --git a/src/backing/indexed/mod.rs b/src/backing/indexed/mod.rs index baf2158..3ebfc91 100644 --- a/src/backing/indexed/mod.rs +++ b/src/backing/indexed/mod.rs @@ -3,16 +3,18 @@ mod binary_heap; pub use binary_heap::IndexedBinaryHeap; -use super::{containers::Pair, pure::PureBacking}; - /// A data structure usable for backing an "indexed" queue pub trait IndexedBacking: - PureBacking> + Send + Sync { - /// Update an item's priority - fn update(&mut self, data: D, priority: P) -> bool; - /// Remove an item from the queue - fn remove(&mut self, data: D) -> bool; + /// The length of the queue + fn len(&self) -> usize; /// Check if an item is already in the queue 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

; + /// Remove the top of the queue, if it exists + fn pop(&mut self) -> Option; } diff --git a/src/queue/indexed.rs b/src/queue/indexed.rs index 382a697..c83da6f 100644 --- a/src/queue/indexed.rs +++ b/src/queue/indexed.rs @@ -1,11 +1,11 @@ use pyo3::{ - exceptions::{PyIndexError, PyKeyError, PyRuntimeError, PyStopIteration, PyTypeError}, + exceptions::{PyIndexError, PyKeyError, PyStopIteration, PyTypeError}, prelude::*, types::{PyDict, PyType}, }; use crate::backing::{ - containers::{Pair, PyItem}, + containers::PyItem, indexed::{IndexedBacking, IndexedBinaryHeap}, }; @@ -35,26 +35,16 @@ impl IndexedQueue { } } - fn __setitem__(mut self_: PyRefMut<'_, Self>, key: Py, value: f64) -> PyResult<()> { - let data = PyItem::new(key); - if self_.backing.contains(&data) { - if self_.backing.update(data, value) { - Ok(()) - } else { - Err(PyErr::new::("Key could not be updated")) - } - } else { - Ok(self_.backing.add(Pair::new(data, value))) - } + fn __setitem__(mut self_: PyRefMut<'_, Self>, key: Py, value: f64) { + self_.backing.set(PyItem::new(key), value) } fn __delitem__(mut self_: PyRefMut<'_, Self>, key: Py) -> PyResult<()> { - if self_.backing.remove(PyItem::new(key)) { - Ok(()) - } else { - Err(PyErr::new::( + match self_.backing.remove(PyItem::new(key)) { + Some(_) => Ok(()), + None => Err(PyErr::new::( "Key was not contained in queue", - )) + )), } } @@ -78,7 +68,7 @@ impl IndexedQueue { fn __next__(mut self_: PyRefMut<'_, Self>) -> PyResult> { if let Some(item) = self_.backing.pop() { - Ok(item.data().data()) + Ok(item.data()) } else { Err(PyErr::new::(())) } @@ -86,7 +76,7 @@ impl IndexedQueue { fn pop(mut self_: PyRefMut<'_, Self>) -> PyResult> { if let Some(item) = self_.backing.pop() { - Ok(item.data().data()) + Ok(item.data()) } else { Err(PyErr::new::(())) } @@ -95,7 +85,7 @@ impl IndexedQueue { impl<'py> IndexedQueue { /// Tries to a Python object into a vector suitable for ingestion into the backing - fn from_any(object: &Bound<'py, PyAny>) -> PyResult>> { + fn from_any(object: &Bound<'py, PyAny>) -> PyResult> { if let Ok(vec) = object.extract::, f64)>>() { Ok(Self::from_vec(vec)) } else { @@ -116,18 +106,18 @@ impl<'py> IndexedQueue { } /// Converts a vector of Python objects and priorities into a vector of items - fn from_vec(list: Vec<(Py, f64)>) -> Vec> { + fn from_vec(list: Vec<(Py, f64)>) -> Vec<(PyItem, f64)> { list.into_iter() - .map(|(data, priority)| Pair::new(PyItem::new(data), priority)) + .map(|(data, priority)| (PyItem::new(data), priority)) .collect() } /// Converts a Python dictionary into a vector of items - fn from_dict(dict: &Bound<'py, PyDict>) -> PyResult>> { + fn from_dict(dict: &Bound<'py, PyDict>) -> PyResult> { if let Ok(items) = dict .into_iter() .map(|(data, priority)| match priority.extract::() { - Ok(value) => Ok(Pair::new(PyItem::new(data.unbind()), value)), + Ok(value) => Ok((PyItem::new(data.unbind()), value)), Err(err) => Err(err), }) .collect::, _>>()