wave11: 488/227 — ROS2/OpenCV/Open3D/metaflow/kubeflow/optuna/openssl/mbedtls/wolfssl + Kafka Streams/Pulsar

This commit is contained in:
russell@unturf.com 2026-03-27 17:31:52 -04:00
parent 6276aea2e5
commit 19333b378e
36 changed files with 4634 additions and 5 deletions

View file

@ -0,0 +1,77 @@
# ros2-0001: ParameterEventsFilter — O(N×P) std::find on names vector inside parameter loop
## Location
`rclcpp/src/rclcpp/parameter_events_filter.cpp` lines 3557
Repository: https://github.com/ros2/rclcpp
## Severity
**HIGH** — Called every time a parameter event arrives on a ROS2 node. With N filter names and P parameters per event type, each event dispatch is O(N×P×3). Large parameter servers (e.g. nav2, MoveIt) publish batched events with dozens of parameters.
## Complexity
- Before: O(N×P) per event type, O(3×N×P) total
- After: O(N) build + O(P) dispatch = O(N+P) total
## Defective Code
```cpp
// parameter_events_filter.cpp:34-57
if (std::find(types.begin(), types.end(), EventType::NEW) != types.end()) {
for (auto & new_parameter : event_->new_parameters) {
if (std::find(names.begin(), names.end(), new_parameter.name) != names.end()) {
result_.push_back(EventPair(EventType::NEW, &new_parameter));
}
}
}
if (std::find(types.begin(), types.end(), EventType::CHANGED) != types.end()) {
for (auto & changed_parameter : event_->changed_parameters) {
if (std::find(names.begin(), names.end(), changed_parameter.name) != names.end()) {
result_.push_back(EventPair(EventType::CHANGED, &changed_parameter));
}
}
}
if (std::find(types.begin(), types.end(), EventType::DELETED) != types.end()) {
for (auto & deleted_parameter : event_->deleted_parameters) {
if (std::find(names.begin(), names.end(), deleted_parameter.name) != names.end()) {
result_.push_back(EventPair(EventType::DELETED, &deleted_parameter));
}
}
}
```
**Problem:** `std::find(names.begin(), names.end(), ...)` is O(N) linear scan inside each
inner loop over event parameters. Three independent O(N×P) blocks = O(3×N×P) total.
Also `std::find` on `types` is O(T) but T≤3 so negligible.
## Fixed Code
```cpp
// Build O(1)-lookup set from names once
std::unordered_set<std::string> names_set(names.begin(), names.end());
std::unordered_set<int> types_set;
for (auto t : types) types_set.insert(static_cast<int>(t));
if (types_set.count(static_cast<int>(EventType::NEW))) {
for (auto & new_parameter : event_->new_parameters) {
if (names_set.count(new_parameter.name)) {
result_.push_back(EventPair(EventType::NEW, &new_parameter));
}
}
}
if (types_set.count(static_cast<int>(EventType::CHANGED))) {
for (auto & changed_parameter : event_->changed_parameters) {
if (names_set.count(changed_parameter.name)) {
result_.push_back(EventPair(EventType::CHANGED, &changed_parameter));
}
}
}
if (types_set.count(static_cast<int>(EventType::DELETED))) {
for (auto & deleted_parameter : event_->deleted_parameters) {
if (names_set.count(deleted_parameter.name)) {
result_.push_back(EventPair(EventType::DELETED, &deleted_parameter));
}
}
}
```
## CWE
CWE-407: Inefficient Algorithmic Complexity — O(N×P) → O(N+P)

View file

@ -0,0 +1,57 @@
# ros2-0002: NodeParameters::list_parameters() — O(P²) std::find on result.prefixes inside parameter loop
## Location
`rclcpp/src/rclcpp/node_interfaces/node_parameters.cpp` lines 10981133
Repository: https://github.com/ros2/rclcpp
## Severity
**MEDIUM** — Called when listing parameters, e.g. during node startup introspection, parameter dump, or `ros2 param list`. With P parameters and up to P unique prefixes, the deduplication loop is O(P²). Large ROS2 nodes (nav2 has 100+ parameters) call this during lifecycle transitions.
## Complexity
- Before: O(P²) — std::find on result.prefixes (grows to P) inside outer loop over parameters_ (size P)
- After: O(P) — unordered_set tracks seen prefixes in O(1)
## Defective Code
```cpp
// node_parameters.cpp:1098-1133
for (const std::pair<const std::string, ParameterInfo> & kv : parameters_) {
// ... prefix matching logic ...
result.names.push_back(kv.first);
size_t last_separator = kv.first.find_last_of(separator);
if (std::string::npos != last_separator) {
std::string prefix = kv.first.substr(0, last_separator);
if (
std::find(result.prefixes.cbegin(), result.prefixes.cend(), prefix) == // O(P) per iteration
result.prefixes.cend())
{
result.prefixes.push_back(prefix);
}
}
}
```
**Problem:** `std::find` on `result.prefixes` is O(|result.prefixes|) which grows up to P
as parameters are processed. This makes the entire loop O(P²).
## Fixed Code
```cpp
std::unordered_set<std::string> seen_prefixes;
for (const std::pair<const std::string, ParameterInfo> & kv : parameters_) {
// ... prefix matching logic (unchanged) ...
result.names.push_back(kv.first);
size_t last_separator = kv.first.find_last_of(separator);
if (std::string::npos != last_separator) {
std::string prefix = kv.first.substr(0, last_separator);
if (seen_prefixes.insert(prefix).second) { // O(1) insert+dedup
result.prefixes.push_back(prefix);
}
}
}
```
## CWE
CWE-407: Inefficient Algorithmic Complexity — O(P²) → O(P)