-
Notifications
You must be signed in to change notification settings - Fork 101
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
Adding an ArrayList and HashMap implementation to rcutils #131
Conversation
895cb6a
to
e3347c9
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nburek Awesome contribution! And sorry for the review comments avalanche, it's a big PR.
include/rcutils/types/array_list.h
Outdated
@@ -0,0 +1,208 @@ | |||
// Copyright 2017 Open Source Robotics Foundation, Inc. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added this documentation.
include/rcutils/types/array_list.h
Outdated
rcutils_array_list_t | ||
rcutils_get_zero_initialized_array_list(void); | ||
|
||
/// Initialize an array liast with a given initial capacity. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nburek liast
-> list
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
include/rcutils/types/array_list.h
Outdated
size_t data_size, | ||
const rcutils_allocator_t * allocator); | ||
|
||
/// Finalize a string array, reclaiming all resources. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nburek string array
-> array list
? It looks like there're a bunch of refactor leftovers here and there in this file :).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This data structure started as a more generic copy of the string array and then evolved to its current state (same with the hash_map). Sorry for the leftover cruft, I thought I had already scrubbed the documentation before I pushed but I guess I forgot.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No worries.
* array_list.data[0] = rcutils_strdup("Hello", &allocator); | ||
* array_list.data[1] = rcutils_strdup("World", &allocator); | ||
* ret = rcutils_array_list_fini(&array_list); | ||
* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nburek missing closing code block backticks?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, they got pushed bellow some of the other comments that weren't meant to be code. Fixed.
include/rcutils/types/array_list.h
Outdated
* // ... error handling | ||
* } | ||
* array_list.data[0] = rcutils_strdup("Hello", &allocator); | ||
* array_list.data[1] = rcutils_strdup("World", &allocator); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nburek it looks like this example is out of date.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed this example and a number of others.
HASH_MAP_VALIDATE_ARGUMENT_NOT_NULL(value); | ||
|
||
size_t key_hash = 0, map_index = 0, bucket_index = 0; | ||
bool already_exists = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nburek nit: why not declaring it at the time of first use?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's just grouping declarations near the top. They're all used shortly after.
HASH_MAP_VALIDATE_ARGUMENT_NOT_NULL(key); | ||
|
||
size_t key_hash = 0, map_index = 0, bucket_index = 0; | ||
bool already_exists = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nburek nit: why not declaring it at the time of first use?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above.
rcutils_ret_t ret = RCUTILS_RET_OK; | ||
|
||
if (NULL != previous_key) { | ||
already_exists = hash_map_find(hash_map, key, &key_hash, &map_index, &bucket_index, &entry); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nburek meta^2: iteration looks expensive, I wonder if there's a cheaper way to track where did it left off the last time rcutils_hash_map_get_next_key_and_data
was called.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the case where you're not modifying the map as you iterate through then this shouldn't be that much more expensive. The find should average out to be constant time. There would be some slight benefit in creating an iterator style method for this as it might not need to rehash the key each time. I didn't use the iterator approach for two reasons:
- My primary use case was to use this function when cleaning up the map and I would be modifying it by removing entries as I went. A simple iterator would be invalid if the map was modified in between.
- So far, the other data structures didn't look like they were using an iterator style approach. This function was more in line with what I was seeing from the other data structures. I didn't want to risk add complexity to this review by trying to set a precedent for iterators when it wasn't needed yet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. And I agree with you. Thanks for the detailed reply.
test/test_array_list.cpp
Outdated
@@ -0,0 +1,355 @@ | |||
// Copyright 2017 Open Source Robotics Foundation, Inc. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nburek 2017
-> 2019
?
test/test_hash_map.cpp
Outdated
@@ -0,0 +1,452 @@ | |||
// Copyright 2017 Open Source Robotics Foundation, Inc. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nburek 2017
-> 2019
?
@hidmic Thank you for the thorough review of the documentation. There were a lot of little fixups in there that got past me. I've posted an updated version based on your comments. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM but for a few minor nits and a question. Also pending green CI.
* The order of the keys in the hash_map is arbitrary and if the hash_map is modified | ||
* between calls to this function the behavior is undefined. | ||
* If the hash_map is modifeid then iteration should begin again by passing NULL to | ||
* get the first key again. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nburek hmm, isn't this statement against your use case in rcl?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I'll correct the rcl review.
Co-Authored-By: nburek <[email protected]>
Co-Authored-By: nburek <[email protected]>
Co-Authored-By: nburek <[email protected]>
Fixed the additional typos you pointed out. It looks like the build is failing because the uncrustify linter is detecting that the logging_macros.h file is out of compliance. This file is auto generated from logging_macros.h.em and it looks like the failure may be a result of this PR: #133 Since the failure appears to be unrelated to my PR I would prefer not to fix it here. |
Not sure how could that be the case. IIRC #133 should make In any case, this still needs to go through https://ci.ros2.org. I'll set it up for you. |
Running CI, including this PR and ros2/rcl#350: |
Looking at CI, it looks like this PR by itself only has a few |
Those are due to the upgrade to uncrustify 0.68.1 on master while we released Crystal with 0.67 and they disagree on a few points. We're upgrading Crystal to 0.68.1 in the upcoming patch release and these errors should subside. |
Commented on the other PR as well, but the bug in the changes to rcl that were causing the failures due to double free is now fixed. Can you please run the CI pipeline again when you get a chance? Thank you. |
I take that back, there is one more broken test in rcl related to test_graph because there is now always one extra topic running on the node for rosout. Fixing that now. |
Okay, now it should be ready for retest. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just some very minor comments. LGTM
Can we try to get this PR merged into the next Crystal patch release? |
This is queued for patch release 2. |
Connects to ros2/rcl#350
This change adds an ArrayList and HashMap implementation to rcutils. These data structures were needed for the rosout logging feature so that we could easily map logger names to nodes/publishers.
These changes were made on top of commits being reviewed in pull request #127. Once that pull request is merged on the latest commit that is on top of that will show in this PR.