Address Clippy lints
Some checks failed
CI / Formatting (push) Successful in 39s
CI / Clippy (push) Failing after 59s
CI / Build (push) Successful in 1m28s
CI / Python tests (push) Successful in 38s
CI / Rust tests (push) Successful in 1m18s

This commit is contained in:
Michael Bradley 2025-02-23 09:50:20 -05:00
parent b1d49624d4
commit 8ed5e410ff
Signed by: MichaelBradley
SSH key fingerprint: SHA256:cj/YZ5VT+QOKncqSkx+ibKTIn0Obg7OIzwzl9BL8EO8
6 changed files with 109 additions and 102 deletions

View file

@ -13,6 +13,14 @@ pub struct IndexedBinaryHeap<
indices: HashMap<D, usize>,
}
impl<D: Hash + Eq + Clone + Send + Sync, P: PartialOrd + Clone + Send + Sync> Default
for IndexedBinaryHeap<D, P>
{
fn default() -> Self {
Self::new()
}
}
impl<D: Hash + Eq + Clone + Send + Sync, P: PartialOrd + Clone + Send + Sync>
IndexedBinaryHeap<D, P>
{
@ -54,49 +62,47 @@ impl<D: Hash + Eq + Clone + Send + Sync, P: PartialOrd + Clone + Send + Sync>
if i > self.data.len() {
// Tried to sift a non-existent index
Err(SiftError::new(i, self.data.len()))
} else {
if let Some(first_child) = self.data.get(i * 2 + 1).cloned() {
let smaller_child_index;
let smaller_child;
} else if let Some(first_child) = self.data.get(i * 2 + 1).cloned() {
let smaller_child_index;
let smaller_child;
// Find the smallest child and its index
if let Some(second_child) = self.data.get(i * 2 + 2).cloned() {
// Both children, use the smaller one
if first_child < second_child {
smaller_child = first_child;
smaller_child_index = i * 2 + 1;
} else {
smaller_child = second_child;
smaller_child_index = i * 2 + 2;
}
} else {
// Only one child, no choice
// Find the smallest child and its index
if let Some(second_child) = self.data.get(i * 2 + 2).cloned() {
// Both children, use the smaller one
if first_child < second_child {
smaller_child = first_child;
smaller_child_index = i * 2 + 1;
}
if smaller_child < self.data[i] {
// Swap parent with child
self.data[smaller_child_index] = self.data[i].clone();
self.indices
.insert(
self.data[smaller_child_index].clone().data(),
smaller_child_index,
)
.unwrap();
self.data[i] = smaller_child.clone();
self.indices.insert(smaller_child.data(), i).unwrap();
// Repeat process with child
self.sift_down(smaller_child_index)
} else {
// Heap property satisfied, we're done
Ok(())
smaller_child = second_child;
smaller_child_index = i * 2 + 2;
}
} else {
// Base case, no children so nothing to do
// Only one child, no choice
smaller_child = first_child;
smaller_child_index = i * 2 + 1;
}
if smaller_child < self.data[i] {
// Swap parent with child
self.data[smaller_child_index] = self.data[i].clone();
self.indices
.insert(
self.data[smaller_child_index].clone().data(),
smaller_child_index,
)
.unwrap();
self.data[i] = smaller_child.clone();
self.indices.insert(smaller_child.data(), i).unwrap();
// Repeat process with child
self.sift_down(smaller_child_index)
} else {
// Heap property satisfied, we're done
Ok(())
}
} else {
// Base case, no children so nothing to do
Ok(())
}
}
@ -147,6 +153,10 @@ impl<D: Hash + Eq + Clone + Send + Sync, P: PartialOrd + Clone + Send + Sync> In
self.data.len()
}
fn is_empty(&self) -> bool {
self.data.is_empty()
}
fn contains(&self, data: &D) -> bool {
self.indices.contains_key(data)
}
@ -164,7 +174,7 @@ impl<D: Hash + Eq + Clone + Send + Sync, P: PartialOrd + Clone + Send + Sync> In
}
} else {
let final_index = self.data.len();
if let Some(_) = self.indices.insert(data.clone(), final_index) {
if self.indices.insert(data.clone(), final_index).is_some() {
panic!("Item was not consistently hashed")
}
self.data.push(Pair::new(data, priority));
@ -174,21 +184,14 @@ impl<D: Hash + Eq + Clone + Send + Sync, P: PartialOrd + Clone + Send + Sync> In
fn remove(&mut self, data: D) -> Option<P> {
if let Some(index) = self.indices.get(&data) {
if let Some(pair) = self.delete_pair(*index) {
Some(pair.get_priority().clone())
} else {
None
}
self.delete_pair(*index)
.map(|pair| pair.get_priority().clone())
} else {
None
}
}
fn pop(&mut self) -> Option<D> {
if let Some(pair) = self.delete_pair(0) {
Some(pair.data())
} else {
None
}
self.delete_pair(0).map(|pair| pair.data())
}
}

View file

@ -9,6 +9,8 @@ pub trait IndexedBacking<D: Clone + Send + Sync, P: PartialOrd + Clone + Send +
{
/// The length of the queue
fn len(&self) -> usize;
/// Whether the queue is empty
fn is_empty(&self) -> bool;
/// 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

View file

@ -8,6 +8,12 @@ pub struct BinaryHeap<T: PartialOrd + Clone + Send + Sync> {
data: Vec<T>,
}
impl<T: PartialOrd + Clone + Send + Sync> Default for BinaryHeap<T> {
fn default() -> Self {
Self::new()
}
}
impl<T: PartialOrd + Clone + Send + Sync> BinaryHeap<T> {
/// Instantiates a new (empty) binary heap
pub fn new() -> Self {
@ -43,42 +49,40 @@ impl<T: PartialOrd + Clone + Send + Sync> BinaryHeap<T> {
if i > self.data.len() {
// Tried to sift a non-existent index
Err(SiftError::new(i, self.data.len()))
} else {
if let Some(first_child) = self.data.get(i * 2 + 1).cloned() {
let smaller_child_index;
let smaller_child;
} else if let Some(first_child) = self.data.get(i * 2 + 1).cloned() {
let smaller_child_index;
let smaller_child;
// Find the smallest child and its index
if let Some(second_child) = self.data.get(i * 2 + 2).cloned() {
// Both children, use the smaller one
if first_child < second_child {
smaller_child = first_child;
smaller_child_index = i * 2 + 1;
} else {
smaller_child = second_child;
smaller_child_index = i * 2 + 2;
}
} else {
// Only one child, no choice
// Find the smallest child and its index
if let Some(second_child) = self.data.get(i * 2 + 2).cloned() {
// Both children, use the smaller one
if first_child < second_child {
smaller_child = first_child;
smaller_child_index = i * 2 + 1;
}
if smaller_child < self.data[i] {
// Swap parent with child
self.data[smaller_child_index] = self.data[i].clone();
self.data[i] = smaller_child;
// Repeat process with child
self.sift_down(smaller_child_index)
} else {
// Heap property satisfied, we're done
Ok(())
smaller_child = second_child;
smaller_child_index = i * 2 + 2;
}
} else {
// Base case, no children so nothing to do
// Only one child, no choice
smaller_child = first_child;
smaller_child_index = i * 2 + 1;
}
if smaller_child < self.data[i] {
// Swap parent with child
self.data[smaller_child_index] = self.data[i].clone();
self.data[i] = smaller_child;
// Repeat process with child
self.sift_down(smaller_child_index)
} else {
// Heap property satisfied, we're done
Ok(())
}
} else {
// Base case, no children so nothing to do
Ok(())
}
}
}
@ -127,4 +131,8 @@ impl<T: PartialOrd + Clone + Send + Sync> PureBacking<T> for BinaryHeap<T> {
fn len(&self) -> usize {
self.data.len()
}
fn is_empty(&self) -> bool {
self.data.is_empty()
}
}

View file

@ -10,4 +10,6 @@ pub trait PureBacking<T: PartialOrd + Send + Sync>: Send + Sync {
fn pop(&mut self) -> Option<T>;
/// The number of items in the queue
fn len(&self) -> usize;
/// Whether the queue is empty
fn is_empty(&self) -> bool;
}

View file

@ -23,10 +23,8 @@ impl IndexedQueue {
#[pyo3(signature = (items=None))]
fn new(items: Option<Py<PyAny>>) -> PyResult<Self> {
if let Some(py_object) = items {
Python::with_gil(|py| Self::from_any(py_object.bind(py))).and_then(|vec| {
Ok(Self {
backing: Box::new(IndexedBinaryHeap::from_iter(vec)),
})
Python::with_gil(|py| Self::from_any(py_object.bind(py))).map(|vec| Self {
backing: Box::new(IndexedBinaryHeap::from_iter(vec)),
})
} else {
Ok(Self {
@ -88,20 +86,18 @@ impl<'py> IndexedQueue {
fn from_any(object: &Bound<'py, PyAny>) -> PyResult<Vec<(PyItem, f64)>> {
if let Ok(vec) = object.extract::<Vec<(Py<PyAny>, f64)>>() {
Ok(Self::from_vec(vec))
} else {
if object.is_instance_of::<PyDict>() {
if let Ok(dict) = object.downcast::<PyDict>() {
Self::from_dict(dict)
} else {
Err(PyErr::new::<PyTypeError, _>(
"Argument claimed to be a dict but wasn't",
))
}
} else if object.is_instance_of::<PyDict>() {
if let Ok(dict) = object.downcast::<PyDict>() {
Self::from_dict(dict)
} else {
Err(PyErr::new::<PyTypeError, _>(
"Argument was not a properly-formed dict, list, or tuple",
"Argument claimed to be a dict but wasn't",
))
}
} else {
Err(PyErr::new::<PyTypeError, _>(
"Argument was not a properly-formed dict, list, or tuple",
))
}
}

View file

@ -26,10 +26,8 @@ impl PairedQueue {
#[pyo3(signature = (items=None))]
fn new(items: Option<Py<PyAny>>) -> PyResult<Self> {
if let Some(py_object) = items {
Python::with_gil(|py| Self::from_any(py_object.bind(py))).and_then(|vec| {
Ok(Self {
backing: Box::new(BinaryHeap::from_iter(vec)),
})
Python::with_gil(|py| Self::from_any(py_object.bind(py))).map(|vec| Self {
backing: Box::new(BinaryHeap::from_iter(vec)),
})
} else {
Ok(Self {
@ -72,20 +70,18 @@ impl<'py> PairedQueue {
fn from_any(object: &Bound<'py, PyAny>) -> PyResult<Vec<Pair<Py<PyAny>, f64>>> {
if let Ok(vec) = object.extract::<Vec<(Py<PyAny>, f64)>>() {
Ok(Self::from_vec(vec))
} else {
if object.is_instance_of::<PyDict>() {
if let Ok(dict) = object.downcast::<PyDict>() {
Self::from_dict(dict)
} else {
Err(PyErr::new::<PyTypeError, _>(
"Argument claimed to be a dict but wasn't",
))
}
} else if object.is_instance_of::<PyDict>() {
if let Ok(dict) = object.downcast::<PyDict>() {
Self::from_dict(dict)
} else {
Err(PyErr::new::<PyTypeError, _>(
"Argument was not a properly-formed dict, list, or tuple",
"Argument claimed to be a dict but wasn't",
))
}
} else {
Err(PyErr::new::<PyTypeError, _>(
"Argument was not a properly-formed dict, list, or tuple",
))
}
}