-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Replace boost::multi_index_container
with custom container in stageCache.cpp
#2349
Conversation
Filed as internal issue #USD-8136 |
f045dc9
to
0c8239c
Compare
b03cc91
to
2620000
Compare
if ( it != _byStage.cend()) { | ||
return std::make_pair(it->second, false); | ||
} | ||
const Id id = GetNextId(); |
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.
Notes about all the uses of TF_AXIOM:
- We definitely do not want TF_AXIOM wrapping any statements with a side effect like the emplace statements here. The docs for TF_AXIOM state that these statements are allowed to be converted to no-ops in an optimized build (even though we don't do that in any builds currently)
- We prefer to use TF_VERIFY around an expression that is required to return true or even a normal if conditional that produces a TF_CODING_ERROR it the condition is not true.
- Do we need axioms/verifies here at all?
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.
emplace
returning false would be a red flag that the class's invariants have been violated. I think some sort of unlikely failure assertion would be helpful. I can switch this to a TF_VERIFY
.
struct ByStage {}; | ||
// Return true if the stage was successfully erased | ||
bool Erase(const UsdStageRefPtr& stage) { | ||
const auto it = _byStage.find(stage); |
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 preferred that the return false;
is on a separate line and wrapped in curly braces.
return entry.stage->GetRootLayer(); | ||
// Return true if the stage was successfully erased | ||
bool Erase(const Id id) { | ||
const auto it = _byId.find(id); |
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 comment as above.
@@ -143,15 +220,11 @@ struct DebugHelper | |||
|
|||
bool IsEnabled() const { return _enabled; } | |||
|
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.
Is the variadic template necessary here?
It looks like all callers of AddEntry pass the same UsdStageRefPtr, Id parameters.
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 not necessary. It may have been useful in an earlier version of the code, but AddEntry
should now just take the Ptr / Id parameters.
pxr/usd/usd/stageCache.cpp
Outdated
@@ -553,11 +627,10 @@ UsdStageCache::Insert(const UsdStageRefPtr &stage) | |||
Id ret; | |||
|
|||
{ LockGuard lock(_mutex); | |||
StagesByStage &byStage = _impl->stages.get<ByStage>(); | |||
auto iresult = byStage.insert(Entry(stage, GetNextId())); | |||
auto iresult = _impl->stages.Insert(stage); | |||
if (iresult.second && debug.IsEnabled()) |
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.
Can we add the braces around this debug.AddEntry too
if (request.IsSatisfiedBy(entry.stage)) | ||
return std::make_pair(entry.stage, false); | ||
{ | ||
const IdsByStage &byStage = _impl->stages.ByStage(); |
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.
While we're here, can we add braces around these nested statements.
Thanks for taking a look. I've updated the PR to address the notes. |
efa27a7
to
b1e2ba4
Compare
// function | ||
for (auto it = range.first; it != range.second;) { | ||
if (conditionFn(it->second)) { | ||
const auto byStageIt = _byStage.find(it->second); |
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.
Sorry for nitpicking, but the only issue here is that it this verify does happen to fail, this will loop infinitely since the iterator doesn't get updated. Maybe starting at 200, the code should be
it = _byRootLayer.erase(it);
++erasedCount;
continue;
}
}
++it;
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 restructured the loop to avoid the need for a continue
in the spirit of avoiding in non-trivial loops (https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Res-continue).
b1e2ba4
to
0bfc6cb
Compare
0bfc6cb
to
38a4985
Compare
Description of Change(s)
To reduce the dependency on
boost
, this converts theStageContainer
into a class containing three synchronized unordered maps for each lookup type. For many operations that are read only, the underlying maps can simply be exposed. For insertion / erasure operations, explicit methods are provided onStageContainer
to ensure the underlying containers don't violate the synchronization invariant.Fixes Issue(s)