wave11: 488/227 — ROS2/OpenCV/Open3D/metaflow/kubeflow/optuna/openssl/mbedtls/wolfssl + Kafka Streams/Pulsar
This commit is contained in:
parent
6276aea2e5
commit
19333b378e
36 changed files with 4634 additions and 5 deletions
166
defects/ros2/unit/ListParametersAlgorithm.java
Normal file
166
defects/ros2/unit/ListParametersAlgorithm.java
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
package unit;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Unit test for ros2-0002: NodeParameters::list_parameters() O(P²) → O(P)
|
||||
*
|
||||
* Simulates prefix deduplication in NodeParameters::list_parameters():
|
||||
* Defective: std::find on result.prefixes (grows to P) inside loop over P parameters
|
||||
* Fixed: unordered_set deduplication O(1) insert
|
||||
*
|
||||
* Compile: javac -d . ListParametersAlgorithm.java
|
||||
* Run: java -ea unit.ListParametersAlgorithm
|
||||
*/
|
||||
public class ListParametersAlgorithm {
|
||||
|
||||
static class Result {
|
||||
final List<String> names = new ArrayList<>();
|
||||
final List<String> prefixes = new ArrayList<>();
|
||||
}
|
||||
|
||||
// ── defective implementation ──────────────────────────────────────────────
|
||||
|
||||
static Result defectiveListParameters(List<String> parameterNames) {
|
||||
Result result = new Result();
|
||||
final char separator = '.';
|
||||
|
||||
for (String name : parameterNames) {
|
||||
result.names.add(name);
|
||||
int lastSep = name.lastIndexOf(separator);
|
||||
if (lastSep != -1) {
|
||||
String prefix = name.substring(0, lastSep);
|
||||
// O(P) linear scan to deduplicate prefixes
|
||||
boolean found = false;
|
||||
for (String p : result.prefixes) {
|
||||
if (p.equals(prefix)) { found = true; break; }
|
||||
}
|
||||
if (!found) result.prefixes.add(prefix);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// ── fixed implementation ──────────────────────────────────────────────────
|
||||
|
||||
static Result fixedListParameters(List<String> parameterNames) {
|
||||
Result result = new Result();
|
||||
final char separator = '.';
|
||||
Set<String> seenPrefixes = new HashSet<>();
|
||||
|
||||
for (String name : parameterNames) {
|
||||
result.names.add(name);
|
||||
int lastSep = name.lastIndexOf(separator);
|
||||
if (lastSep != -1) {
|
||||
String prefix = name.substring(0, lastSep);
|
||||
if (seenPrefixes.add(prefix)) { // O(1) insert + dedup
|
||||
result.prefixes.add(prefix);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// ── tests ─────────────────────────────────────────────────────────────────
|
||||
|
||||
static int pass = 0, total = 0;
|
||||
|
||||
static void assertTrue(String name, boolean cond) {
|
||||
total++;
|
||||
if (cond) { pass++; System.out.println("PASS " + name); }
|
||||
else System.out.println("FAIL " + name);
|
||||
}
|
||||
|
||||
// Build nav2-style parameter names: namespace.group.param
|
||||
static List<String> buildNav2Params(int namespaces, int groups, int paramsPerGroup) {
|
||||
List<String> names = new ArrayList<>();
|
||||
for (int ns = 0; ns < namespaces; ns++) {
|
||||
for (int g = 0; g < groups; g++) {
|
||||
for (int p = 0; p < paramsPerGroup; p++) {
|
||||
names.add("ns" + ns + ".group" + g + ".param" + p);
|
||||
}
|
||||
}
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
// Test 1: empty parameters → empty result
|
||||
{
|
||||
Result d = defectiveListParameters(Collections.emptyList());
|
||||
Result f = fixedListParameters(Collections.emptyList());
|
||||
assertTrue("empty-defective", d.names.isEmpty() && d.prefixes.isEmpty());
|
||||
assertTrue("empty-fixed", f.names.isEmpty() && f.prefixes.isEmpty());
|
||||
}
|
||||
|
||||
// Test 2: parameters with no separator → no prefixes
|
||||
{
|
||||
List<String> params = Arrays.asList("foo", "bar", "baz");
|
||||
Result d = defectiveListParameters(params);
|
||||
Result f = fixedListParameters(params);
|
||||
assertTrue("no-sep-defective", d.prefixes.isEmpty() && d.names.size() == 3);
|
||||
assertTrue("no-sep-fixed", f.prefixes.isEmpty() && f.names.size() == 3);
|
||||
}
|
||||
|
||||
// Test 3: all same prefix → only one prefix entry
|
||||
{
|
||||
List<String> params = Arrays.asList("nav2.speed", "nav2.timeout", "nav2.max_vel");
|
||||
Result d = defectiveListParameters(params);
|
||||
Result f = fixedListParameters(params);
|
||||
assertTrue("same-prefix-dedup-defective", d.prefixes.size() == 1 && d.prefixes.get(0).equals("nav2"));
|
||||
assertTrue("same-prefix-dedup-fixed", f.prefixes.size() == 1 && f.prefixes.get(0).equals("nav2"));
|
||||
}
|
||||
|
||||
// Test 4: multiple distinct prefixes
|
||||
{
|
||||
List<String> params = Arrays.asList(
|
||||
"nav2.speed", "nav2.timeout",
|
||||
"moveit.planning_time", "moveit.max_vel",
|
||||
"slam.resolution");
|
||||
Result d = defectiveListParameters(params);
|
||||
Result f = fixedListParameters(params);
|
||||
assertTrue("multi-prefix-defective", d.prefixes.size() == 3);
|
||||
assertTrue("multi-prefix-fixed", f.prefixes.size() == 3);
|
||||
assertTrue("multi-prefix-names-match", d.names.equals(f.names));
|
||||
// prefixes sets must be equal (order may differ)
|
||||
assertTrue("multi-prefix-sets-match",
|
||||
new HashSet<>(d.prefixes).equals(new HashSet<>(f.prefixes)));
|
||||
}
|
||||
|
||||
// Test 5: nav2-style — 3 namespaces, 10 groups, 5 params each = 150 params, 30 unique prefixes
|
||||
{
|
||||
List<String> params = buildNav2Params(3, 10, 5);
|
||||
Result d = defectiveListParameters(params);
|
||||
Result f = fixedListParameters(params);
|
||||
assertTrue("nav2-names-count-defective", d.names.size() == 150);
|
||||
assertTrue("nav2-names-count-fixed", f.names.size() == 150);
|
||||
// Each ns.group is a unique "ns_X.group_Y" prefix → 3*10 = 30 unique prefixes
|
||||
assertTrue("nav2-prefix-count-defective", d.prefixes.size() == 30);
|
||||
assertTrue("nav2-prefix-count-fixed", f.prefixes.size() == 30);
|
||||
assertTrue("nav2-prefix-sets-match",
|
||||
new HashSet<>(d.prefixes).equals(new HashSet<>(f.prefixes)));
|
||||
}
|
||||
|
||||
// Test 6: performance at P=500 (500 unique prefixes worst case)
|
||||
{
|
||||
List<String> params = new ArrayList<>();
|
||||
for (int i = 0; i < 500; i++) params.add("group" + i + ".param" + i);
|
||||
|
||||
long t0 = System.nanoTime();
|
||||
for (int r = 0; r < 200; r++) defectiveListParameters(params);
|
||||
long tDef = System.nanoTime() - t0;
|
||||
|
||||
t0 = System.nanoTime();
|
||||
for (int r = 0; r < 200; r++) fixedListParameters(params);
|
||||
long tFix = System.nanoTime() - t0;
|
||||
|
||||
double ratio = (double) tDef / tFix;
|
||||
System.out.printf(" Perf P=500 unique: defective=%.1fms fixed=%.1fms ratio=%.1fx%n",
|
||||
tDef / 1e6, tFix / 1e6, ratio);
|
||||
assertTrue("perf-speedup", ratio > 3.0);
|
||||
}
|
||||
|
||||
System.out.println(pass + "/" + total + " PASS");
|
||||
assert pass == total : pass + "/" + total + " passed";
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue