From c4776189242fc834eb4f5edee60b847c8c9479ff Mon Sep 17 00:00:00 2001 From: Zygo Blaxell Date: Wed, 1 Feb 2017 23:09:40 -0500 Subject: [PATCH] crucible: resource: optimize map cleanup We were holding weak refs until the next time the resource ID was used. This is a bad thing if resource IDs are sparse (e.g. pointers or hashes) because we'll never see an ID twice. To fix, determine whether we released the last instance of a resource, and if so, free its weak ref immediately. Signed-off-by: Zygo Blaxell --- include/crucible/resource.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/include/crucible/resource.h b/include/crucible/resource.h index 18659e4..bdccf62 100644 --- a/include/crucible/resource.h +++ b/include/crucible/resource.h @@ -273,12 +273,19 @@ namespace crucible { } // Save key so we can clean the map auto key = s_traits.get_key(*m_ptr); - // Drop pointer early + // Save a weak_ptr so we can tell if we need to clean the map + weak_ptr_type wp = m_ptr; + // Drop shared_ptr m_ptr.reset(); + // If there are still other references to the shared_ptr, we can stop now + if (!wp.expired()) { + return; + } // Remove weak_ptr from map if it has expired // (and not been replaced in the meantime) unique_lock lock_map(s_map_mutex); auto found = s_map.find(key); + // Map entry may have been replaced, so check for expiry again if (found != s_map.end() && found->second.expired()) { s_map.erase(key); }