Skip to content
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

Merged
merged 1 commit into from
Aug 16, 2023

Conversation

nvmkuruc
Copy link
Collaborator

@nvmkuruc nvmkuruc commented Mar 21, 2023

Description of Change(s)

To reduce the dependency on boost, this converts the StageContainer 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 on StageContainer to ensure the underlying containers don't violate the synchronization invariant.

Fixes Issue(s)

  • I have verified that all unit tests pass with the proposed changes
  • I have submitted a signed Contributor License Agreement

@tallytalwar
Copy link
Contributor

Filed as internal issue #USD-8136

@nvmkuruc nvmkuruc force-pushed the stagecachemulti branch 2 times, most recently from b03cc91 to 2620000 Compare July 3, 2023 18:17
if ( it != _byStage.cend()) {
return std::make_pair(it->second, false);
}
const Id id = GetNextId();
Copy link

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:

  1. 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)
  2. 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.
  3. Do we need axioms/verifies here at all?

Copy link
Collaborator Author

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);
Copy link

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);
Copy link

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; }

Copy link

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.

Copy link
Collaborator Author

@nvmkuruc nvmkuruc Jul 5, 2023

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.

@@ -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())
Copy link

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();
Copy link

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.

@nvmkuruc
Copy link
Collaborator Author

nvmkuruc commented Jul 5, 2023

Thanks for taking a look. I've updated the PR to address the notes.

@nvmkuruc nvmkuruc force-pushed the stagecachemulti branch 5 times, most recently from efa27a7 to b1e2ba4 Compare July 10, 2023 22:25
// function
for (auto it = range.first; it != range.second;) {
if (conditionFn(it->second)) {
const auto byStageIt = _byStage.find(it->second);
Copy link

@crevilla crevilla Jul 10, 2023

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;

Copy link
Collaborator Author

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).

@pixar-oss pixar-oss merged commit 64dbeb4 into PixarAnimationStudios:dev Aug 16, 2023
@nvmkuruc nvmkuruc deleted the stagecachemulti branch December 29, 2023 03:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants