Added support for limited resizing of the online profile cache

if too many search results are found. Print warning (instead of
assert) to console if search results should be missing (because of
cache eviction).
This commit is contained in:
hiker
2014-03-03 16:32:05 +11:00
parent 7cdc064640
commit c1afacfc38
4 changed files with 70 additions and 20 deletions

View File

@@ -39,7 +39,7 @@ ProfileManager* ProfileManager::m_profile_manager = NULL;
*/
ProfileManager::ProfileManager()
{
assert(m_max_cache_size > 1);
m_max_cache_size = 2;
m_currently_visiting = NULL;
} // ProfileManager
@@ -55,6 +55,29 @@ ProfileManager::~ProfileManager()
}
} // ~ProfileManager
// ------------------------------------------------------------------------
/** Makes sure that the cache can store at least max_num entries. This is
* used by the online search screen to make sure all results found can
* be cached at the same time.
* \param min_num Minimum number of entries the chache should be able to
* store.
*/
int ProfileManager::guaranteeCacheSize(unsigned int min_num)
{
return m_max_cache_size;
if (m_max_cache_size < min_num)
{
// Avoid that the cache can grow too big by setting an
// upper limit.
if (min_num > 100)
min_num = 100;
m_max_cache_size = min_num;
}
return m_max_cache_size;
} // guaranteeCacheSize
// ------------------------------------------------------------------------
/** Search for a given profile in the set of persistent and cached
* entries. If the profile does not exist, a NULL is returned.

View File

@@ -64,8 +64,10 @@ private:
* e.g. its data is shown in a gui. */
Profile* m_currently_visiting;
/** The max size of the m_profiles cache. */
static const unsigned int m_max_cache_size = 20;
/** The max size of the m_profiles cache. Its default size can be
* inrceased when necessary (e.g. when too many search results are
* loaded, to make sure they can be all stored). */
unsigned int m_max_cache_size;
void updateCacheBits(Profile * profile);
void addDirectToCache(Profile * profile);
@@ -101,7 +103,7 @@ public:
void deleteFromPersistent(const uint32_t id);
void clearPersistent();
void moveToCache(const uint32_t id);
int guaranteeCacheSize(unsigned int max_num);
bool isInCache(const uint32_t id);
bool inPersistent(const uint32_t id);
Profile* getProfileByID(const uint32_t id);

View File

@@ -17,30 +17,30 @@
#include "states_screens/online_user_search.hpp"
#include <iostream>
#include <assert.h>
#include "audio/sfx_manager.hpp"
#include "guiengine/modaldialog.hpp"
#include "online/current_user.hpp"
#include "online/messages.hpp"
#include "states_screens/dialogs/user_info_dialog.hpp"
#include "states_screens/state_manager.hpp"
#include "states_screens/dialogs/message_dialog.hpp"
#include "states_screens/state_manager.hpp"
#include "utils/translation.hpp"
#include "utils/string_utils.hpp"
#include "online/messages.hpp"
#include "online/current_user.hpp"
#include "audio/sfx_manager.hpp"
using namespace Online;
#include <assert.h>
#include <iostream>
DEFINE_SCREEN_SINGLETON( OnlineUserSearch );
// ----------------------------------------------------------------------------
OnlineUserSearch::OnlineUserSearch() : Screen("online/user_search.stkgui")
{
m_selected_index = -1;
m_search_request = NULL;
m_search_string = "";
m_selected_index = -1;
m_search_request = NULL;
m_search_string = "";
m_last_search_string = "";
} // OnlineUserSearch
@@ -60,19 +60,35 @@ void OnlineUserSearch::tearDown()
// ----------------------------------------------------------------------------
/** Adds the results of the query to the ProfileManager cache.
* \param input The XML node with all user data.
*/
void OnlineUserSearch::parseResult(const XMLNode * input)
{
m_users.clear();
const XMLNode * users_xml = input->getNode("users");
for (unsigned int i = 0; i < users_xml->getNumNodes(); i++)
// Try to reserve enough cache space for all found entries.
unsigned int n = ProfileManager::get()
->guaranteeCacheSize(users_xml->getNumNodes());
if (n >= users_xml->getNumNodes())
n = users_xml->getNumNodes();
else
{
Log::warn("OnlineSearch",
"Too many results found, only %d will be displayed.", n);
}
for (unsigned int i = 0; i < n; i++)
{
Profile * profile = new Profile(users_xml->getNode(i));
ProfileManager::get()->addToCache(profile);
// The id must be pushed before adding it to the cache, since
// the cache might merge the new data with an existing entry
m_users.push_back(profile->getID());
ProfileManager::get()->addToCache(profile);
}
}
} // parseResult
// ----------------------------------------------------------------------------
void OnlineUserSearch::showList()
{
m_user_list_widget->clear();
@@ -80,11 +96,17 @@ void OnlineUserSearch::showList()
{
std::vector<GUIEngine::ListWidget::ListCell> row;
Profile * profile = ProfileManager::get()->getProfileByID(m_users[i]);
assert(profile != NULL);
// This could still happen if something pushed results out of the cache.
if (!profile)
{
Log::warn("OnlineSearch", "User %d not in cache anymore, ignored.",
m_users[i]);
continue;
}
row.push_back(GUIEngine::ListWidget::ListCell(profile->getUserName(),-1,3));
m_user_list_widget->addItem("user", row);
}
}
} // showList
// ----------------------------------------------------------------------------

View File

@@ -49,7 +49,10 @@ private:
int m_selected_index;
irr::core::stringw m_search_string;
irr::core::stringw m_last_search_string;
/** The list of all IDs found. */
Online::Profile::IDList m_users;
const Online::XMLRequest * m_search_request;
bool m_fake_refresh;