From 89ac0fa232112ee3bf4b61e545b0a823b9ffbfe0 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 21 Jun 2012 11:43:18 +0200 Subject: [PATCH] Issue #312: Implemented ID-search caching to speed up some badly written scripts --- apps/openmw/mwworld/cells.cpp | 42 +++++++++++++++++++++++++++++------ apps/openmw/mwworld/cells.hpp | 4 ++++ 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwworld/cells.cpp b/apps/openmw/mwworld/cells.cpp index 990a4cc4a3..3d6042e466 100644 --- a/apps/openmw/mwworld/cells.cpp +++ b/apps/openmw/mwworld/cells.cpp @@ -70,8 +70,26 @@ void MWWorld::Cells::fillContainers (Ptr::CellStore& cellStore) } } +MWWorld::Ptr MWWorld::Cells::getPtrAndCache (const std::string& name, Ptr::CellStore& cellStore) +{ + Ptr ptr = getPtr (name, cellStore); + + if (!ptr.isEmpty()) + { + mIdCache[mIdCacheIndex].first = name; + mIdCache[mIdCacheIndex].second = &cellStore; + if (++mIdCacheIndex>=mIdCache.size()) + mIdCacheIndex = 0; + } + + return ptr; +} + MWWorld::Cells::Cells (const ESMS::ESMStore& store, ESM::ESMReader& reader, MWWorld::World& world) -: mStore (store), mReader (reader), mWorld (world) {} +: mStore (store), mReader (reader), mWorld (world), + mIdCache (20, std::pair ("", 0)), /// \todo make cache size configurable + mIdCacheIndex (0) +{} MWWorld::Ptr::CellStore *MWWorld::Cells::getExterior (int x, int y) { @@ -215,19 +233,29 @@ MWWorld::Ptr MWWorld::Cells::getPtr (const std::string& name, Ptr::CellStore& ce MWWorld::Ptr MWWorld::Cells::getPtr (const std::string& name) { - // First check cells that are already listed + // First check the cache + for (std::vector >::iterator iter (mIdCache.begin()); + iter!=mIdCache.end(); ++iter) + if (iter->first==name && iter->second) + { + Ptr ptr = getPtr (name, *iter->second); + if (!ptr.isEmpty()) + return ptr; + } + + // Then check cells that are already listed for (std::map::iterator iter = mInteriors.begin(); iter!=mInteriors.end(); ++iter) { - Ptr ptr = getPtr (name, iter->second); + Ptr ptr = getPtrAndCache (name, iter->second); if (!ptr.isEmpty()) - return ptr; + return ptr; } for (std::map, Ptr::CellStore>::iterator iter = mExteriors.begin(); iter!=mExteriors.end(); ++iter) { - Ptr ptr = getPtr (name, iter->second); + Ptr ptr = getPtrAndCache (name, iter->second); if (!ptr.isEmpty()) return ptr; } @@ -238,7 +266,7 @@ MWWorld::Ptr MWWorld::Cells::getPtr (const std::string& name) { Ptr::CellStore *cellStore = getCellStore (iter->second); - Ptr ptr = getPtr (name, *cellStore); + Ptr ptr = getPtrAndCache (name, *cellStore); if (!ptr.isEmpty()) return ptr; @@ -249,7 +277,7 @@ MWWorld::Ptr MWWorld::Cells::getPtr (const std::string& name) { Ptr::CellStore *cellStore = getCellStore (iter->second); - Ptr ptr = getPtr (name, *cellStore); + Ptr ptr = getPtrAndCache (name, *cellStore); if (!ptr.isEmpty()) return ptr; diff --git a/apps/openmw/mwworld/cells.hpp b/apps/openmw/mwworld/cells.hpp index 42aa1050c0..05367138f2 100644 --- a/apps/openmw/mwworld/cells.hpp +++ b/apps/openmw/mwworld/cells.hpp @@ -28,6 +28,8 @@ namespace MWWorld std::map mInteriors; std::map, Ptr::CellStore> mExteriors; MWWorld::World& mWorld; + std::vector > mIdCache; + std::size_t mIdCacheIndex; Cells (const Cells&); Cells& operator= (const Cells&); @@ -36,6 +38,8 @@ namespace MWWorld void fillContainers (Ptr::CellStore& cellStore); + Ptr getPtrAndCache (const std::string& name, Ptr::CellStore& cellStore); + public: Cells (const ESMS::ESMStore& store, ESM::ESMReader& reader, MWWorld::World& world);