Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incremental object search #109

Closed

Conversation

jhagborgftx
Copy link
Contributor

This PR implements #106. It also adds tests for both new and old-style object searches, and changes find_objects to use this new API internally.

As it is, find_next(0) returns Some(vec![]), which is I think the least surprising thing to do? It shouldn't return None, since there may be more objects remaining. I think it would also make sense if it panicked. Let me know what you think.

wiktor-k
wiktor-k previously approved these changes Dec 1, 2022
Copy link
Collaborator

@wiktor-k wiktor-k left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. It kind of bothers me that None and Some(vec![]) are basically the same state but using Option has the advantage of nice while let Some(...) loops on the client side 🤔

Passing 0 to the function is indeed unfortunate. On one hand it's good when the library never panics, on the other some projects (like rust-openssl) panic left and right on bad programmer-supplied data 🤷‍♂️

@jhagborgftx
Copy link
Contributor Author

jhagborgftx commented Dec 1, 2022 via email

Add a method `Session::find_objects_init`, which returns an
iterator-like object representing an ongoing object search.  This
allows for more flexibility than the existing `Session::find_objects`,
which returns a vector of all objects.

Signed-off-by: James Hagborg <[email protected]>
Signed-off-by: James Hagborg <[email protected]>
Change find_objects to use the new incremental object search functions
internally, instead of calling the FFI directly.

Signed-off-by: James Hagborg <[email protected]>
@jhagborgftx
Copy link
Contributor Author

Updated to return just a vector, rather than an option of vector.

@wiktor-k
Copy link
Collaborator

wiktor-k commented Dec 2, 2022

Thanks for the updates! I did take some time to add the iterator API on top of it: wiktor-k@1c00f37

Edit: I've added the no-compile test to test for the case of two searches in parallel that should be forbidden and adjusted muts here and there for the iterator API to work (it still prohibits two search to be open at the same time).

I'm still thinking about the API ease of use from the perspective of the API clients 🤔

For the time being maybe let's wait until @ionut-arm voices his opinion (since he's the most senior here along with @hug-dev)? Sorry that this takes a little bit of time but it's the end of year and everyone is super busy...

@jhagborgftx
Copy link
Contributor Author

Neat. I was thinking that an iterator interface would be a separate struct that wraps a FindObjects, created from a separate method like Session::find_objects_iter(). That way the user doesn't need to bother with a default batch size if they aren't using it. This would also make it possible to make an iterator in more than one way: as an iterator over chunks or as an iterator over individual objects, with batching under the hood.

There's no rush to get this merged immediately. I'm going to be using a patched version for a while anyway, and I'm trying to upstream what I can.

Copy link
Member

@ionut-arm ionut-arm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the patch, looks pretty good, thanks for all the tests in particular!

Comment on lines +150 to +176
/// ```no_run
/// use cryptoki::error::Result;
/// use cryptoki::object::{Attribute, AttributeType};
/// use cryptoki::session::Session;
///
/// const BATCH_SIZE: usize = 10;
///
/// fn print_object_labels(session: &mut Session, template: &[Attribute]) -> Result<()> {
/// // Initiate the search.
/// let mut search = session.find_objects_init(template)?;
///
/// // Iterate over batches of results, while find_next returns a non-empty batch
/// while let ref objects @ [_, ..] = search.find_next(BATCH_SIZE)?[..] {
/// // Iterate over objects in the batch.
/// for &object in objects {
/// // Look up the label for the object. We can't use `session` directly here,
/// // since it's mutably borrowed by search. Instead, use `search.session()`.
/// let attrs = search.session().get_attributes(object, &[AttributeType::Label])?;
/// if let Some(Attribute::Label(label)) = attrs.get(0) {
/// println!("Found object: {}", String::from_utf8_lossy(&label));
/// }
/// }
/// }
///
/// Ok(())
/// }
/// ```
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent, thanks for adding an example.

Comment on lines +95 to +96
// Search 10 elements at a time
const MAX_OBJECT_COUNT: usize = 10;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason for this choice? Just curious

let mut search = session.find_objects_init(&[])?;
let objects = search.find_next(10)?;
assert!(search.find_next(10)?.is_empty());
drop(search);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmmmm... Would it be possible to add a method to FindObjects, something like finalize, that just takes ownership of the value and lets it drop? It seems suboptimal to have to drop the object manually to achieve this, and an empty method isn't too bad.

@ionut-arm
Copy link
Member

I also like Wiktor's iterator addition, seems quite handy for this operation - I'd be quite happy if you managed to incorporate something like that in the patch! 😄

@jhagborgftx
Copy link
Contributor Author

jhagborgftx commented Dec 7, 2022 via email

@jhagborgftx
Copy link
Contributor Author

jhagborgftx commented Dec 7, 2022 via email

@ionut-arm
Copy link
Member

Either way, I don't think manual dropping is that strange. The docs
for MutexGuard from std have an example. The same could also be
acheived by just adding some curly braces around the search.

Sure, we've had cases before where dropping something was the way to go, but since we know this is a potential use-case, it seems quite straight-forward to add something to do it "natively". But I get your point!

One question I wanted to raise is: how much time do you have/are you willing to put into resolving comments on these PRs? Because if you only want to get them in as is, we could review the changes here, raise issues for what's left (like this new method), and fix those afterwards in separate PRs. Asking only because I don't want to pressure you into putting in more effort.

@jhagborgftx
Copy link
Contributor Author

jhagborgftx commented Dec 8, 2022 via email

@hug-dev
Copy link
Member

hug-dev commented Sep 13, 2024

#223 fixed the upstream issue, so this could probably be closed if you agree!

@wiktor-k
Copy link
Collaborator

Closing, as this has already been implemented. Thanks for your time! 👋

@wiktor-k wiktor-k closed this Oct 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants