added lru

This commit is contained in:
Dave Schuyler 2002-01-18 03:40:20 +00:00
parent 7b979177f1
commit 2539af6bb0
2 changed files with 82 additions and 5 deletions

View File

@ -24,6 +24,7 @@
#include "milesAudioManager.h" #include "milesAudioManager.h"
#include "config_audio.h" #include "config_audio.h"
#include "config_util.h" #include "config_util.h"
#include <algorithm>
int MilesAudioManager::_active_managers; int MilesAudioManager::_active_managers;
HDLSFILEID MilesAudioManager::_dls_field; HDLSFILEID MilesAudioManager::_dls_field;
@ -103,6 +104,7 @@ MilesAudioManager() {
// either way. // either way.
++_active_managers; ++_active_managers;
audio_debug(" _active_managers="<<_active_managers); audio_debug(" _active_managers="<<_active_managers);
assert(is_valid());
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -140,7 +142,22 @@ MilesAudioManager::
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool MilesAudioManager:: bool MilesAudioManager::
is_valid() { is_valid() {
return _is_valid; bool check=true;
if (_sounds.size() != _lru.size()) {
audio_debug("--sizes--");
check=false;
} else {
LRU::const_iterator i=_lru.begin();
for (; i != _lru.end(); ++i) {
SoundMap::const_iterator smi=_sounds.find(**i);
if (smi == _sounds.end()) {
audio_debug("--"<<**i<<"--");
check=false;
break;
}
}
}
return _is_valid && check;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -167,6 +184,7 @@ load(Filename file_name) {
PT(AudioSound) MilesAudioManager:: PT(AudioSound) MilesAudioManager::
get_sound(const string& file_name) { get_sound(const string& file_name) {
audio_debug("MilesAudioManager::get_sound(file_name=\""<<file_name<<"\")"); audio_debug("MilesAudioManager::get_sound(file_name=\""<<file_name<<"\")");
assert(is_valid());
Filename path = file_name; Filename path = file_name;
path.resolve_filename(get_sound_path()); path.resolve_filename(get_sound_path());
audio_debug(" resolved file_name is '"<<path<<"'"); audio_debug(" resolved file_name is '"<<path<<"'");
@ -193,6 +211,7 @@ get_sound(const string& file_name) {
if (!ib.second) { if (!ib.second) {
// The insert failed. // The insert failed.
audio_debug(" failed map insert of "<<path); audio_debug(" failed map insert of "<<path);
assert(is_valid());
return 0; return 0;
} }
// Set si, so that we can get a reference to the path // Set si, so that we can get a reference to the path
@ -200,6 +219,7 @@ get_sound(const string& file_name) {
si=ib.first; si=ib.first;
} }
} }
most_recently_used((*si).first);
// Create an AudioSound from the sound: // Create an AudioSound from the sound:
PT(AudioSound) audioSound = 0; PT(AudioSound) audioSound = 0;
if (audio) { if (audio) {
@ -211,6 +231,7 @@ get_sound(const string& file_name) {
audioSound=milesAudioSound; audioSound=milesAudioSound;
} }
audio_debug(" returning 0x" << (void*)audioSound); audio_debug(" returning 0x" << (void*)audioSound);
assert(is_valid());
return audioSound; return audioSound;
} }
@ -223,14 +244,20 @@ void MilesAudioManager::
uncache_sound(const string& file_name) { uncache_sound(const string& file_name) {
audio_debug("MilesAudioManager::uncache_sound(file_name=\"" audio_debug("MilesAudioManager::uncache_sound(file_name=\""
<<file_name<<"\")"); <<file_name<<"\")");
assert(is_valid());
Filename path = file_name; Filename path = file_name;
path.resolve_filename(get_sound_path()); path.resolve_filename(get_sound_path());
audio_debug(" path=\""<<path<<"\""); audio_debug(" path=\""<<path<<"\"");
SoundMap::iterator i=_sounds.find(path); SoundMap::iterator i=_sounds.find(path);
if (i != _sounds.end()) { if (i != _sounds.end()) {
assert(_lru.size()>0);
LRU::iterator lru_i=find(_lru.begin(), _lru.end(), &(i->first));
assert(lru_i != _lru.end());
_lru.erase(lru_i);
AIL_quick_unload(i->second); AIL_quick_unload(i->second);
_sounds.erase(i); _sounds.erase(i);
} }
assert(is_valid());
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -241,11 +268,52 @@ uncache_sound(const string& file_name) {
void MilesAudioManager:: void MilesAudioManager::
uncache_a_sound() { uncache_a_sound() {
audio_debug("MilesAudioManager::uncache_a_sound()"); audio_debug("MilesAudioManager::uncache_a_sound()");
SoundMap::iterator i = _sounds.begin(); assert(is_valid());
SoundMap::iterator i;
// Pick a caching scheme:
if (0) {
// uncache arbitrarily:
i = _sounds.begin();
} else if (0) {
// uncache randomly:
// (I may implement this later, along with run-time selection
// of caching mechanisms).
//i = _sounds[random from 0 to _sounds.size()-1];
} else {
// uncache least recently used:
assert(_lru.size()>0);
LRU::reference path=_lru.front();
i = _sounds.find(*path);
assert(i != _sounds.end());
_lru.pop_front();
}
if (i != _sounds.end()) { if (i != _sounds.end()) {
audio_debug(" uncaching \""<<i->first<<"\""); audio_debug(" uncaching \""<<i->first<<"\"");
AIL_quick_unload(i->second);
_sounds.erase(i); _sounds.erase(i);
} }
assert(is_valid());
}
////////////////////////////////////////////////////////////////////
// Function: MilesAudioManager::most_recently_used
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void MilesAudioManager::
most_recently_used(const string& path) {
audio_debug("MilesAudioManager::most_recently_used(path=\""
<<path<<"\")");
LRU::iterator i=find(_lru.begin(), _lru.end(), &path);
if (i != _lru.end()) {
_lru.erase(i);
}
// At this point, path should not exist in the _lru:
assert(find(_lru.begin(), _lru.end(), &path) == _lru.end());
_lru.push_back(&path);
assert(is_valid());
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -256,11 +324,14 @@ uncache_a_sound() {
void MilesAudioManager:: void MilesAudioManager::
clear_cache() { clear_cache() {
audio_debug("MilesAudioManager::clear_cache()"); audio_debug("MilesAudioManager::clear_cache()");
assert(is_valid());
SoundMap::iterator i=_sounds.begin(); SoundMap::iterator i=_sounds.begin();
for (; i!=_sounds.end(); ++i) { for (; i!=_sounds.end(); ++i) {
AIL_quick_unload(i->second); AIL_quick_unload(i->second);
} }
_sounds.clear(); _sounds.clear();
_lru.clear();
assert(is_valid());
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -272,11 +343,12 @@ void MilesAudioManager::
set_cache_limit(int count) { set_cache_limit(int count) {
audio_debug("MilesAudioManager::set_cache_limit(count=" audio_debug("MilesAudioManager::set_cache_limit(count="
<<count<<")"); <<count<<")");
while (count < _cache_limit) { assert(is_valid());
while (_lru.size() > count) {
uncache_a_sound(); uncache_a_sound();
--_cache_limit;
} }
_cache_limit=count; _cache_limit=count;
assert(is_valid());
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -27,6 +27,7 @@
#include "mss.h" #include "mss.h"
#include "pset.h" #include "pset.h"
#include "pmap.h" #include "pmap.h"
#include "pdeque.h"
class MilesAudioSound; class MilesAudioSound;
@ -52,9 +53,12 @@ public:
bool get_active(); bool get_active();
private: private:
// The sound cache/pool: // The sound cache:
typedef pmap<string, HAUDIO > SoundMap; typedef pmap<string, HAUDIO > SoundMap;
SoundMap _sounds; SoundMap _sounds;
// The Least Recently Used mechanism:
typedef pdeque<const string* > LRU;
LRU _lru;
// The offspring of this manager: // The offspring of this manager:
typedef pset<MilesAudioSound* > AudioSet; typedef pset<MilesAudioSound* > AudioSet;
AudioSet _soundsOnLoan; AudioSet _soundsOnLoan;
@ -73,6 +77,7 @@ private:
// Tell the manager that the sound dtor was called. // Tell the manager that the sound dtor was called.
void release_sound(MilesAudioSound* audioSound); void release_sound(MilesAudioSound* audioSound);
void most_recently_used(const string& path);
void uncache_a_sound(); void uncache_a_sound();
// utility function that should be moved to another class: // utility function that should be moved to another class: