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

Expose list_find in the c api #5848

Merged
merged 10 commits into from
Sep 14, 2022
Merged

Expose list_find in the c api #5848

merged 10 commits into from
Sep 14, 2022

Conversation

nicola-cab
Copy link
Member

What, How & Why?

Fixes: #5842

☑️ ToDos

  • 📝 Changelog update
  • 🚦 Tests (or not relevant)
  • C-API, if public C++ API changed.

@cla-bot cla-bot bot added the cla: yes label Sep 13, 2022
@@ -2624,6 +2664,13 @@ TEST_CASE("C API", "[c_api]") {
size_t size;
CHECK(checked(realm_list_size(bars.get(), &size)));
CHECK(size == 2);

Copy link
Member Author

Choose a reason for hiding this comment

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

@ironage @jedelbo I noticed for all the CollectionBase objects we don't allow searching with, type type_TypedLink . Is this still wanted? Or it is something we should enable?

Copy link
Contributor

Choose a reason for hiding this comment

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

A list of TypedLink is not officially supported. But there should be some way to find a destination object in a list of links. In C++ we support finding by ObjKey, but it looks like the C-API doesn't expose this type in a realm_value_t for some reason. We should either convert TypedLink to ObjKey in realm_list_find or we should support LnkLst::find_any given a Mixed of type TypedLink. In either case, when converting from TypedLink to ObjKey, we'd need to check that the destination table matches.

Copy link
Member Author

Choose a reason for hiding this comment

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

I think probably we should file a separate issue and add support for this stuff at some stage in C API too.

Copy link
Contributor

Choose a reason for hiding this comment

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

I just added a small fix, I think it is OK to sneak in here.

Copy link
Member Author

Choose a reason for hiding this comment

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

OK, then we need to do this also for Sets and Dictionaries, right?

Copy link
Member Author

Choose a reason for hiding this comment

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

I think we need to do nothing for Dictionaries. I added the implementation for Sets

src/realm.h Outdated
/**
* Find the value in the list passed as parameter.
* @param value to search in the list
* @param out_index the index where the value has been found
Copy link
Member

Choose a reason for hiding this comment

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

What is this set to if the value hasn't been found?

Copy link
Member Author

Choose a reason for hiding this comment

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

realm::not_found;

Copy link
Member

Choose a reason for hiding this comment

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

I think we should document the actual value here to make it easier for consumers or alternatively, define it as a constant somewhere so that it can be referenced.

Copy link
Member Author

Choose a reason for hiding this comment

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

I can add a comment, but this is in line with all the other find APIs

found = real2virtual(found);

auto find_obj_key = [this](ObjKey objkey) {
size_t found = find(objkey);
Copy link
Contributor

Choose a reason for hiding this comment

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

This find method makes the translation to virtual index. Just use it directly below. This seems to have been an error before as well. Do we actually have a test involving this? I played around to verify my assumptions - may as well push my findings.

* @param out_found boolean that indicates whether the value is found or not
* @return true if no exception occurred.
*/
RLM_API bool realm_list_find(const realm_list_t*, const realm_value_t* value, size_t* out_index, bool* out_found);
Copy link
Member

Choose a reason for hiding this comment

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

Do we need out_found - seems like we can easily infer that from out_index.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes we do and I disagree on this proposal. For 2 reasons:

  1. finds for set has the same signature (and also most of the find APIs we have in the C API)
  2. out_index is of type size_t this means it can never be negative. If you assign -1 to signal that the value was not found, this index might be MAX_LIMIT(std::size_t) which can be a valid index.
    I would leave it as it is.

Copy link
Member Author

Choose a reason for hiding this comment

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

Actually, realm::not_found is std::size{-1}. So in theory, we could get rid of the boolean. However, I would rather keep it as it is to keep it consistent.

src/realm.h Outdated
/**
* Find the value in the list passed as parameter.
* @param value to search in the list
* @param out_index the index where the value has been found
Copy link
Member

Choose a reason for hiding this comment

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

I think we should document the actual value here to make it easier for consumers or alternatively, define it as a constant somewhere so that it can be referenced.


size_t out_index = -1;
bool found;
CHECK(checked(realm_list_find(strings.get(), &a2, &out_index, &found)));
Copy link
Member

Choose a reason for hiding this comment

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

These tests only seem to test the case where a value is found. Can we add a test where find is called with a value that doesn't exist in the list?

Copy link
Member Author

Choose a reason for hiding this comment

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

This was actually a test that was exercising the "not found" path, but we are sneaking in Mixed Links support as well. Let me add a test.

Copy link
Contributor

@jedelbo jedelbo left a comment

Choose a reason for hiding this comment

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

LGTM

@nirinchev
Copy link
Member

I noticed we're also missing results_find - not sure if you prefer to add it in this PR or we could do a separate issue for it.

@nicola-cab
Copy link
Member Author

nicola-cab commented Sep 14, 2022

I noticed we're also missing results_find - not sure if you prefer to add it in this PR or we could do a separate issue for it.

There are 2 versions of realm_results_get.
realm_results_get and realm_results_get_object one is for links and the other one is for objects, which is a little bit odd, but the 2 APIs, although they do the same thing, they have different signatures. Probably we should just reform these APIs a little bit. Do we want to add two types of realm_results_find? Maybe this is worth another issue.

@nirinchev
Copy link
Member

Good point - it's weird we have two of those. I'll file a new ticket to address that and add a single results_find method.

@nicola-cab nicola-cab merged commit 4d21f9a into master Sep 14, 2022
@nicola-cab nicola-cab deleted the nc/add_realm_list_find branch September 14, 2022 19:51
tgoyne added a commit that referenced this pull request Sep 16, 2022
…nification

* origin/master:
  Stop forcing enums to be 64 bits unnecessarily
  clean up documentation of internal fields in config structs
  SyncConfig should be default constructible
  Traversal functions use IteratorControl values rather than true/false which is more expressive (#5857)
  Fix handling of 4-byte UTF8 values on Windows (#5803)
  Encode links in a way the server can understand (#5835)
  expose `Group::remove_table` in the C API (#5860)
  Disable auto refresh for old realm during migration (#5856)
  Expose `list_find` in the c api (#5848)
  Do not allow asymmetric tables in pbs (#5853)
  Refactor link tracing code (#5796)
  Expose `Obj::get_parent_object` in the C API (#5851)
  Update app.hpp (#5854)
  Fix appending to list ignores existing query (#5850)
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 21, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[C-API] Expose realm_list_find
4 participants