Skip to content

Commit

Permalink
Exporting deadpool redis, fixing panic on empty arr with binary searches
Browse files Browse the repository at this point in the history
  • Loading branch information
zakstucke committed Jul 8, 2024
1 parent 3f3ae07 commit 57456b2
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 32 deletions.
3 changes: 2 additions & 1 deletion .zetch.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

76 changes: 46 additions & 30 deletions rust/bitbazaar/misc/binary_search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,22 +75,26 @@ impl<K, V> BinarySearchable for indexmap::IndexMap<K, V> {
///
/// Returns:
/// - Some(index) the index of the item in the array.
/// - None if the item is not found.
/// - None if the item is not found or array empty.
pub fn binary_search_exact<Item>(
arr_like: &impl BinarySearchable<Item = Item>,
comparer: impl Fn(&Item) -> Ordering,
) -> Option<usize> {
let mut low = 0;
let mut high = arr_like.len() - 1;
while low <= high {
let mid = (low + high) / 2;
match comparer(arr_like.get(mid)) {
Ordering::Greater => low = mid + 1,
Ordering::Less => high = mid - 1,
Ordering::Equal => return Some(mid),
if arr_like.is_empty() {
None
} else {
let mut low = 0;
let mut high = arr_like.len() - 1;
while low <= high {
let mid = (low + high) / 2;
match comparer(arr_like.get(mid)) {
Ordering::Greater => low = mid + 1,
Ordering::Less => high = mid - 1,
Ordering::Equal => return Some(mid),
}
}
None
}
None
}

/// Binary search for the desired item in the array, but also passes the prior and next items into the comparison function, if they exist.
Expand All @@ -102,32 +106,36 @@ pub fn binary_search_exact<Item>(
///
/// Returns:
/// - Some(index) the index of the item in the array.
/// - None if the item is not found.
/// - None if the item is not found or array empty.
pub fn binary_search_exact_with_siblings<Item>(
arr_like: &impl BinarySearchable<Item = Item>,
comparer: impl Fn(Option<&Item>, &Item, Option<&Item>) -> Ordering,
) -> Option<usize> {
let mut low = 0;
let mut high = arr_like.len() - 1;
while low <= high {
let mid = (low + high) / 2;
let prior = if mid == 0 {
None
} else {
Some(arr_like.get(mid - 1))
};
let next = if mid == arr_like.len() - 1 {
None
} else {
Some(arr_like.get(mid + 1))
};
match comparer(prior, arr_like.get(mid), next) {
Ordering::Greater => low = mid + 1,
Ordering::Less => high = mid - 1,
Ordering::Equal => return Some(mid),
if arr_like.is_empty() {
None
} else {
let mut low = 0;
let mut high = arr_like.len() - 1;
while low <= high {
let mid = (low + high) / 2;
let prior = if mid == 0 {
None
} else {
Some(arr_like.get(mid - 1))
};
let next = if mid == arr_like.len() - 1 {
None
} else {
Some(arr_like.get(mid + 1))
};
match comparer(prior, arr_like.get(mid), next) {
Ordering::Greater => low = mid + 1,
Ordering::Less => high = mid - 1,
Ordering::Equal => return Some(mid),
}
}
None
}
None
}

/// Binary search for the desired item in the array.
Expand Down Expand Up @@ -168,6 +176,14 @@ mod tests {

#[test]
fn test_binary_search() {
// Empty arrays shouldn't panic for any variation:
assert_eq!(binary_search_exact(&[], |x| 5.cmp(x)), None);
assert_eq!(
binary_search_exact_with_siblings(&[], |_, x, _| 5.cmp(x)),
None
);
assert_eq!(binary_search_soft(&[], |x| 5.cmp(x)), None);

// 7 is missing, with exact should be None, with soft should be 5
let arr = [1, 2, 3, 4, 5, 6, 8, 9, 10];
assert_eq!(binary_search_exact(&arr, |x| 5.cmp(x)), Some(4));
Expand Down
3 changes: 2 additions & 1 deletion rust/bitbazaar/redis/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ pub use batch::{RedisBatch, RedisBatchFire, RedisBatchReturningOps};
pub use conn::RedisConn;
pub use dlock::{RedisLock, RedisLockErr};
pub use json::{RedisJson, RedisJsonBorrowed};
// Re-exporting redis to be used outside: (this must also be in scope for the derive macros to work)
// Re-exporting redis and deadpool_redis to be used outside if needed:
pub use deadpool_redis;
pub use redis;
// Re-exporting the json derive utilities to allow redis to take arbitrary json types without the need for the wrapper.
// Both this and the custom wrapper are exported as latter works better for e.g. the temp list.
Expand Down

0 comments on commit 57456b2

Please sign in to comment.