|
55 | 55 | _IsPrunedImpl( |
56 | 56 | const SdfPath &primPath, const SdfPathVector &sortedExcludePaths) |
57 | 57 | { |
58 | | - // Since the exclude paths are sorted and stripped of descendents, |
59 | | - // it suffices to check the lower bound for equality and optionally just |
60 | | - // the previous element for a prefix match. |
61 | | - // The previous element can be: |
62 | | - // (a) a sibling or a sibling descendent prim |
63 | | - // (b) an ancestor prim |
64 | | - // (c) a prim from a disjoint subtree |
| 58 | + // Recall that sortedExcludePaths is sorted and stripped of descendents. |
| 59 | + // For primPath to be pruned, sortedExcludePaths must either contain |
| 60 | + // primPath or a prefix of primPath. |
65 | 61 | // |
66 | | - // Only (b) prunes the primPath. |
| 62 | + // If a prefix of primPath exists, it will be the first element |
| 63 | + // that is less-than primPath. Thus, what we want here is the first |
| 64 | + // element that is less-than-or-equal-to primPath. |
67 | 65 | // |
68 | | - auto it = std::lower_bound( |
69 | | - sortedExcludePaths.begin(), sortedExcludePaths.end(), primPath); |
70 | | - |
71 | | - if (it != sortedExcludePaths.end() && *it == primPath) { |
72 | | - return true; |
73 | | - } |
74 | | - |
75 | | - if (it != sortedExcludePaths.begin()) { |
76 | | - --it; |
77 | | - if (primPath.HasPrefix(*it)) { |
78 | | - return true; |
79 | | - } |
80 | | - } |
81 | | - |
82 | | - return false; |
| 66 | + // With the default std::less_than comparator, |
| 67 | + // lower_bound gives us the first element that is not less than |
| 68 | + // (i.e. greater-than-or-equal-to) primPath, and |
| 69 | + // upper_bound gives us the first element that is greater than |
| 70 | + // (i.e. not less-than-or-equal-to) primPath. |
| 71 | + // |
| 72 | + // We would need to inspect the element(s) before the returned iterator |
| 73 | + // to determine if primPath is pruned. |
| 74 | + // |
| 75 | + // Using lower_bound with reverse iterators and the std::greater_than |
| 76 | + // comparator gives us the first element that is not greater than |
| 77 | + // (i.e. less-than-or-equal-to) primPath, which is what we want. |
| 78 | + // |
| 79 | + auto rit = std::lower_bound( |
| 80 | + sortedExcludePaths.rbegin(), sortedExcludePaths.rend(), primPath, |
| 81 | + std::greater<SdfPath>()); |
| 82 | + |
| 83 | + return rit != sortedExcludePaths.rend() && primPath.HasPrefix(*rit); |
83 | 84 | } |
84 | 85 |
|
85 | 86 | /// Returns prefix paths in \p a that are not covered by prefix paths in \p b. |
|
0 commit comments