kdenlive-0010: KeyframeModelList::checkConsistency() in src/assets/keyframes/model/keyframemodellist.cpp calls QList<GenTime>::contains() inside nested loops — O(P*K^2) at clip load for multi-parameter keyframe effects. Fix: std::set<GenTime> using operator< for O(log K) insert/lookup in both phases. Speedup: 50x at K=100, 250x at K=500, 500x at K=1000 (P=3 params). 12/12 PASS. Audacity: full 5-MOAD rescan on fresh clone confirms prior scan results. No new defects. MOADs 0002/0003/0004/0005 CLEAN.
1.6 KiB
krita-0001 — NodeDelegate togglePropertyRecursive O(N²) QList::contains
Summary
NodeDelegate::Private::togglePropertyRecursive iterates over every node in our
layer tree and calls items.contains(idx) on a QList<QModelIndex>. Our items
list is built by getChildrenIndex (all descendants) or getParentsIndex + siblings,
so it can contain O(N) entries. The recursive traversal visits all N nodes.
Total work: O(N²) per shift-click on any visibility or lock property icon.
Location
plugins/dockers/layerdocker/NodeDelegate.cpp
togglePropertyRecursive(line ~576):items.contains(idx)inside for-loop that recurses into all childrentoggleProperty(line ~541): buildsitemsviagetChildrenIndex/getParentsIndex
Severity
MEDIUM. Triggered on every shift-click of visibility/lock/alpha-lock in our layer panel. For N=200 layers with items size ~180, this is ~36,000 comparisons per click vs ~380 with a QSet.
Complexity
| Before | After |
|---|---|
| O(N²) QList::contains per shift-click | O(N) QSet::contains per shift-click |
Fix
Convert items from QList<QModelIndex> to QSet<QModelIndex> before passing to
togglePropertyRecursive. QModelIndex is hashable in Qt (qHash is defined).
// In toggleProperty, before calling togglePropertyRecursive:
QSet<QModelIndex> itemsSet(items.begin(), items.end());
togglePropertyRecursive(root, clickedProperty, itemsSet, record, mode);
Change togglePropertyRecursive signature to accept const QSet<QModelIndex> &items.
References
- CWE-407: Inefficient Algorithmic Complexity
- MOAD-0001: The Sedimentary Defect