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

Take the field index, not name, in the feature getters and setters #581

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

lnicola
Copy link
Member

@lnicola lnicola commented Oct 29, 2024

  • I agree to follow the project's code of conduct.
  • I added an entry to CHANGES.md if knowledge of this change could be valuable to users.

Field access by name tends to be very slow (I've seen it take 30% of the time in some programs), but beginners are unlikely to realize that they're doing a number of expensive lookups per feature.

Summary of changes:

  • drop field getters that take a field name
  • change the field setters to take an index instead of a name (the index versions were missing)
  • make field_count return usize for consistency
  • add Defn::field_index and make Feature::field_index public
  • drop LayerAccess::create_feature_fields (it could be updated, but it's a bit weird)

@lnicola
Copy link
Member Author

lnicola commented Oct 29, 2024

r? @metasim, @ChristianBeilschmidt, @jdroenner since this is a relatively big change
r? @latot since you said you wanted to get involved

Hopefully I'll be able to get rid of this thing soon:

image

(it goes on and on)

Comment on lines +72 to +74
/// If the field is missing, returns [`GdalError::InvalidFieldName`].
///
pub fn field_index<S: AsRef<str>>(&self, field_name: S) -> Result<usize> {
Copy link
Contributor

Choose a reason for hiding this comment

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

To consider: Some of these retrieval functions return Result<Option<T>>. Should that convention be used here? I'm on the fence. It arguably adds more friction but is more precise. At the other end of the spectrum is just Option<usize>, which has nicer ergonomics, but basically swallows FFI-related errors.

Copy link
Member Author

Choose a reason for hiding this comment

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

The Option there is meant for null (or unset, but I'm not sure how well we support those) fields. For the getters, I think the "simple" ones are infallible and return some kind of 0 for invalid indexes, while the ones returning lists are fallible.

So Result<Option<T>> sounds right for the getters and setters. field_index could return Option<usize>, but that's less nice to use (because it won't mix with Result and ?), and it does swallow the FFI errors.

@latot
Copy link

latot commented Oct 29, 2024

I think this is nice, some questions... can we actually change the fields in any way that could broke the field id?

From where is the image? I can see some transformations from isize to i32 with as.

@lnicola
Copy link
Member Author

lnicola commented Oct 29, 2024

can we actually change the fields in any way that could broke the field id?

You can delete fields from the Defn of a layer, but it won't reflect in the fields of the features, and I don't think we even expose that.

From where is the image? I can see some transformations from isize to i32 with as.

From usize, maybe, but most of those are checked (I think layer iteration is the exception). GDAL fields are 32-bit and positive (-1 means a missing field), but Rust uses probably expect usize. We do a similar thing for raster dimensions. But it's a small change and can be reverted easily (either now or in the future).

Or we could go the other way around and introduce a FieldIdx type that wraps an i32.

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.

3 participants