Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 22 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ env:
RUSTC_WRAPPER: "sccache"

jobs:


run-rust-tests:
runs-on: ubuntu-latest

Expand Down Expand Up @@ -69,15 +71,32 @@ jobs:
exit 1
fi

- name: Detect changed rust files in workspace
uses: dorny/paths-filter@v3
id: changes
with:
filters: |
ai:
- 'ahnlich/ai/**'
types:
- 'ahnlich/types/**'

- name: Build and Format Rust Example
working-directory: ./examples/rust/image-search
run: |
cargo b && cargo fmt

- name: Run Test

- name: Run Full Workspace Tests
if: steps.changes.outputs.ai == 'true' || steps.changes.outputs.types == 'true'
working-directory: ./ahnlich
run: |
make test
run: make test

- name: Run Workspace Tests (excluding AI)
if: steps.changes.outputs.ai != 'true' && steps.changes.outputs.types != 'true'
working-directory: ./ahnlich
run: cargo nextest run --workspace --exclude ai --no-capture


- name: Upload Test Results
uses: actions/upload-artifact@v4
Expand Down
Empty file added ahnlich/.gitignore
Empty file.
103 changes: 100 additions & 3 deletions ahnlich/Cargo.lock

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

3 changes: 3 additions & 0 deletions ahnlich/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,12 @@ fallible_collections = "0.4.9"
dirs = "5.0.1"
strum = { version = "0.26", features = ["derive"] }
papaya = { version = "0.2.0", features = ["serde"] }
parking_lot = "0.12"
tonic = "0.12.3"
http = "1.2.0"
prost = "0.13"
pulp = "0.21.4"
smallvec = "1.13"

[profile.release]
lto = true
4 changes: 2 additions & 2 deletions ahnlich/client/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -836,7 +836,7 @@ mod test {
stores: vec![StoreInfo {
name: "Main".to_string(),
len: 2,
size_in_bytes: 1356,
size_in_bytes: 1340,
}]
}
);
Expand Down Expand Up @@ -870,7 +870,7 @@ mod test {
stores: vec![StoreInfo {
name: "Main".to_string(),
len: 1,
size_in_bytes: 1244,
size_in_bytes: 1236,
}]
}
);
Expand Down
2 changes: 1 addition & 1 deletion ahnlich/db/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ async-trait.workspace = true
rayon.workspace = true
log.workspace = true
fallible_collections.workspace = true
pulp = "0.21.4"
pulp.workspace = true
papaya.workspace = true
ahnlich_types = { path = "../types", version = "*" }
tonic.workspace = true
Expand Down
83 changes: 3 additions & 80 deletions ahnlich/db/src/algorithm/heap.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
#![allow(dead_code)]
use super::LinearAlgorithm;
use std::cmp::Reverse;
use std::collections::BinaryHeap;
use std::num::NonZeroUsize;

// Re-export bounded heaps from similarity crate
pub use ahnlich_similarity::heap::{BoundedMaxHeap, BoundedMinHeap};

pub enum HeapOrder {
Min,
Expand All @@ -19,79 +18,3 @@ impl From<&LinearAlgorithm> for HeapOrder {
}
}
}

/// A bounded max heap that maintains at most `capacity` elements.
/// When the heap is full, incoming elements replace the smallest element if they are larger.
pub struct BoundedMaxHeap<T: Ord> {
heap: BinaryHeap<Reverse<T>>,
capacity: usize,
}

impl<T: Ord> BoundedMaxHeap<T> {
pub fn new(capacity: NonZeroUsize) -> Self {
Self {
heap: BinaryHeap::with_capacity(capacity.get()),
capacity: capacity.get(),
}
}

/// Insert an element into the bounded heap.
/// If the heap is at capacity and the new element is larger than the smallest,
/// the smallest element is removed and the new element is added.
pub fn push(&mut self, item: T) {
if self.heap.len() < self.capacity {
self.heap.push(Reverse(item));
} else if let Some(mut smallest) = self.heap.peek_mut() {
// Only insert if the new item is better (larger) than the worst (smallest) item
if item > smallest.0 {
*smallest = Reverse(item);
}
}
}

/// Convert the bounded heap into a Vec, consuming the heap.
/// Elements are returned in descending order (largest first).
pub fn into_sorted_vec(self) -> Vec<T> {
let mut vec: Vec<_> = self.heap.into_iter().map(|r| r.0).collect();
vec.sort_by(|a, b| b.cmp(a)); // Sort descending
vec
}
}

/// A bounded min heap that maintains at most `capacity` elements.
/// When the heap is full, incoming elements replace the largest element if they are smaller.
pub struct BoundedMinHeap<T: Ord> {
heap: BinaryHeap<T>,
capacity: usize,
}

impl<T: Ord> BoundedMinHeap<T> {
pub fn new(capacity: NonZeroUsize) -> Self {
Self {
heap: BinaryHeap::with_capacity(capacity.get()),
capacity: capacity.get(),
}
}

/// Insert an element into the bounded heap.
/// If the heap is at capacity and the new element is smaller than the largest,
/// the largest element is removed and the new element is added.
pub fn push(&mut self, item: T) {
if self.heap.len() < self.capacity {
self.heap.push(item);
} else if let Some(mut largest) = self.heap.peek_mut() {
// Only insert if the new item is better (smaller) than the worst (largest) item
if item < *largest {
*largest = item;
}
}
}

/// Convert the bounded heap into a Vec, consuming the heap.
/// Elements are returned in ascending order (smallest first).
pub fn into_sorted_vec(self) -> Vec<T> {
let mut vec: Vec<_> = self.heap.into_iter().collect();
vec.sort(); // Sort ascending
vec
}
}
Loading
Loading