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>, 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> impl<D: Hash + Eq + Clone + Send + Sync, P: PartialOrd + Clone + Send + Sync>
IndexedBinaryHeap<D, P> IndexedBinaryHeap<D, P>
{ {
@ -54,49 +62,47 @@ impl<D: Hash + Eq + Clone + Send + Sync, P: PartialOrd + Clone + Send + Sync>
if i > self.data.len() { if i > self.data.len() {
// Tried to sift a non-existent index // Tried to sift a non-existent index
Err(SiftError::new(i, self.data.len())) Err(SiftError::new(i, self.data.len()))
} else { } else if let Some(first_child) = self.data.get(i * 2 + 1).cloned() {
if let Some(first_child) = self.data.get(i * 2 + 1).cloned() { let smaller_child_index;
let smaller_child_index; let smaller_child;
let smaller_child;
// Find the smallest child and its index // Find the smallest child and its index
if let Some(second_child) = self.data.get(i * 2 + 2).cloned() { if let Some(second_child) = self.data.get(i * 2 + 2).cloned() {
// Both children, use the smaller one // Both children, use the smaller one
if first_child < second_child { 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
smaller_child = first_child; smaller_child = first_child;
smaller_child_index = i * 2 + 1; 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 { } else {
// Heap property satisfied, we're done smaller_child = second_child;
Ok(()) smaller_child_index = i * 2 + 2;
} }
} else { } 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(()) 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() self.data.len()
} }
fn is_empty(&self) -> bool {
self.data.is_empty()
}
fn contains(&self, data: &D) -> bool { fn contains(&self, data: &D) -> bool {
self.indices.contains_key(data) self.indices.contains_key(data)
} }
@ -164,7 +174,7 @@ impl<D: Hash + Eq + Clone + Send + Sync, P: PartialOrd + Clone + Send + Sync> In
} }
} else { } else {
let final_index = self.data.len(); 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") panic!("Item was not consistently hashed")
} }
self.data.push(Pair::new(data, priority)); 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> { fn remove(&mut self, data: D) -> Option<P> {
if let Some(index) = self.indices.get(&data) { if let Some(index) = self.indices.get(&data) {
if let Some(pair) = self.delete_pair(*index) { self.delete_pair(*index)
Some(pair.get_priority().clone()) .map(|pair| pair.get_priority().clone())
} else {
None
}
} else { } else {
None None
} }
} }
fn pop(&mut self) -> Option<D> { fn pop(&mut self) -> Option<D> {
if let Some(pair) = self.delete_pair(0) { self.delete_pair(0).map(|pair| pair.data())
Some(pair.data())
} else {
None
}
} }
} }

View file

@ -9,6 +9,8 @@ pub trait IndexedBacking<D: Clone + Send + Sync, P: PartialOrd + Clone + Send +
{ {
/// The length of the queue /// The length of the queue
fn len(&self) -> usize; fn len(&self) -> usize;
/// Whether the queue is empty
fn is_empty(&self) -> 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 /// 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>, 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> { impl<T: PartialOrd + Clone + Send + Sync> BinaryHeap<T> {
/// Instantiates a new (empty) binary heap /// Instantiates a new (empty) binary heap
pub fn new() -> Self { pub fn new() -> Self {
@ -43,42 +49,40 @@ impl<T: PartialOrd + Clone + Send + Sync> BinaryHeap<T> {
if i > self.data.len() { if i > self.data.len() {
// Tried to sift a non-existent index // Tried to sift a non-existent index
Err(SiftError::new(i, self.data.len())) Err(SiftError::new(i, self.data.len()))
} else { } else if let Some(first_child) = self.data.get(i * 2 + 1).cloned() {
if let Some(first_child) = self.data.get(i * 2 + 1).cloned() { let smaller_child_index;
let smaller_child_index; let smaller_child;
let smaller_child;
// Find the smallest child and its index // Find the smallest child and its index
if let Some(second_child) = self.data.get(i * 2 + 2).cloned() { if let Some(second_child) = self.data.get(i * 2 + 2).cloned() {
// Both children, use the smaller one // Both children, use the smaller one
if first_child < second_child { 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
smaller_child = first_child; smaller_child = first_child;
smaller_child_index = i * 2 + 1; 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 { } else {
// Heap property satisfied, we're done smaller_child = second_child;
Ok(()) smaller_child_index = i * 2 + 2;
} }
} else { } 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(()) 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 { fn len(&self) -> usize {
self.data.len() 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>; fn pop(&mut self) -> Option<T>;
/// The number of items in the queue /// The number of items in the queue
fn len(&self) -> usize; 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))] #[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 {
Python::with_gil(|py| Self::from_any(py_object.bind(py))).and_then(|vec| { Python::with_gil(|py| Self::from_any(py_object.bind(py))).map(|vec| Self {
Ok(Self { backing: Box::new(IndexedBinaryHeap::from_iter(vec)),
backing: Box::new(IndexedBinaryHeap::from_iter(vec)),
})
}) })
} else { } else {
Ok(Self { Ok(Self {
@ -88,20 +86,18 @@ impl<'py> IndexedQueue {
fn from_any(object: &Bound<'py, PyAny>) -> PyResult<Vec<(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 if object.is_instance_of::<PyDict>() {
if object.is_instance_of::<PyDict>() { if let Ok(dict) = object.downcast::<PyDict>() {
if let Ok(dict) = object.downcast::<PyDict>() { Self::from_dict(dict)
Self::from_dict(dict)
} else {
Err(PyErr::new::<PyTypeError, _>(
"Argument claimed to be a dict but wasn't",
))
}
} else { } else {
Err(PyErr::new::<PyTypeError, _>( 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))] #[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 {
Python::with_gil(|py| Self::from_any(py_object.bind(py))).and_then(|vec| { Python::with_gil(|py| Self::from_any(py_object.bind(py))).map(|vec| Self {
Ok(Self { backing: Box::new(BinaryHeap::from_iter(vec)),
backing: Box::new(BinaryHeap::from_iter(vec)),
})
}) })
} else { } else {
Ok(Self { Ok(Self {
@ -72,20 +70,18 @@ impl<'py> PairedQueue {
fn from_any(object: &Bound<'py, PyAny>) -> PyResult<Vec<Pair<Py<PyAny>, f64>>> { fn from_any(object: &Bound<'py, PyAny>) -> PyResult<Vec<Pair<Py<PyAny>, 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 if object.is_instance_of::<PyDict>() {
if object.is_instance_of::<PyDict>() { if let Ok(dict) = object.downcast::<PyDict>() {
if let Ok(dict) = object.downcast::<PyDict>() { Self::from_dict(dict)
Self::from_dict(dict)
} else {
Err(PyErr::new::<PyTypeError, _>(
"Argument claimed to be a dict but wasn't",
))
}
} else { } else {
Err(PyErr::new::<PyTypeError, _>( 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",
))
} }
} }