don't hit the disk so much when loading already-loaded files

This commit is contained in:
David Rose 2007-05-27 01:38:05 +00:00
parent bf43d9fb7d
commit c52f7d6427
5 changed files with 134 additions and 118 deletions

View File

@ -76,14 +76,6 @@ load_egg_file(const string &filename, CoordinateSystem cs,
BamCacheRecord *record) {
Filename egg_filename = Filename::text_filename(filename);
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
if (!vfs->exists(egg_filename)) {
egg2pg_cat.error()
<< "Could not find " << egg_filename << "\n";
return NULL;
}
egg2pg_cat.info()
<< "Reading " << egg_filename << "\n";
if (record != (BamCacheRecord *)NULL) {
record->add_dependent_file(egg_filename);
@ -98,10 +90,12 @@ load_egg_file(const string &filename, CoordinateSystem cs,
bool okflag;
istream *istr = vfs->open_read_file(egg_filename, true);
if (istr == (istream *)NULL) {
egg2pg_cat.error()
<< "Could not open " << egg_filename << " for reading.\n";
return NULL;
}
egg2pg_cat.info()
<< "Reading " << egg_filename << "\n";
okflag = loader._data->read(*istr);
vfs->close_read_file(istr);

View File

@ -61,20 +61,14 @@ open_read(const Filename &bam_filename, bool report_errors) {
close();
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
if (!vfs->exists(bam_filename)) {
if (report_errors) {
loader_cat.error() << "Could not find " << bam_filename << "\n";
}
return false;
}
loader_cat.info() << "Reading " << bam_filename << "\n";
if (!_din.open(bam_filename)) {
loader_cat.error() << "Could not open " << bam_filename << "\n";
return false;
}
loader_cat.info()
<< "Reading " << bam_filename << "\n";
return continue_open_read(bam_filename, report_errors);
}
@ -90,7 +84,6 @@ open_read(istream &in, const string &bam_filename, bool report_errors) {
close();
if (!_din.open(in)) {
loader_cat.error() << "Could not read bam: " << bam_filename << "\n";
return false;
}

View File

@ -146,95 +146,115 @@ load_file(const Filename &filename, const LoaderOptions &options) const {
return NULL;
}
DSearchPath::Results results;
bool search = (this_options.get_flags() & LoaderOptions::LF_search) != 0;
if (!filename.is_local()) {
// If we have a global filename, we don't search the model path.
search = false;
}
bool cache_only = (this_options.get_flags() & LoaderOptions::LF_cache_only) != 0;
// Now that we've decided whether to search for the file, don't try
// to search again.
this_options.set_flags(this_options.get_flags() & ~LoaderOptions::LF_search);
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
if (search) {
// Look for the file along the model path.
vfs->find_all_files(this_filename, get_model_path(), results);
if (results.get_num_files() == 0) {
if (report_errors) {
loader_cat.error()
<< "Couldn't load file " << this_filename << ": not found on model path "
<< "(which is currently: \"" << get_model_path() << "\")\n";
int num_dirs = model_path.get_num_directories();
for (int i = 0; i < num_dirs; ++i) {
Filename pathname(model_path.get_directory(i), this_filename);
PT(PandaNode) result = try_load_file(pathname, this_options,
requested_type);
if (result != (PandaNode *)NULL) {
return result;
}
}
if (report_errors) {
bool any_exist = false;
for (int i = 0; i < num_dirs; ++i) {
Filename pathname(model_path.get_directory(i), this_filename);
if (vfs->exists(pathname)) {
any_exist = true;
break;
}
}
if (any_exist) {
loader_cat.error()
<< "Couldn't load file " << this_filename
<< ": all matching files on model path invalid "
<< "(the model path is currently: \"" << get_model_path() << "\")\n";
} else {
loader_cat.error()
<< "Couldn't load file " << this_filename
<< ": not found on model path "
<< "(currently: \"" << get_model_path() << "\")\n";
}
return NULL;
}
} else {
// Look for the file only where it is.
if (vfs->exists(this_filename)) {
results.add_file(this_filename);
} else {
if (report_errors) {
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
PT(PandaNode) result = try_load_file(this_filename, this_options, requested_type);
if (result != (PandaNode *)NULL) {
return result;
}
if (report_errors) {
if (vfs->exists(this_filename)) {
loader_cat.error()
<< "Couldn't load file " << this_filename << ": invalid.\n";
} else {
loader_cat.error()
<< "Couldn't load file " << this_filename << ": does not exist.\n";
}
return NULL;
}
}
return NULL;
}
////////////////////////////////////////////////////////////////////
// Function: Loader::try_load_file
// Access: Private
// Description: The implementatin of load_file(), this tries a single
// possible file without searching further along the
// path.
////////////////////////////////////////////////////////////////////
PT(PandaNode) Loader::
try_load_file(const Filename &pathname, const LoaderOptions &options,
LoaderFileType *requested_type) const {
BamCache *cache = BamCache::get_global_ptr();
bool cache_only = (options.get_flags() & LoaderOptions::LF_cache_only) != 0;
if (requested_type->get_allow_ram_cache(options)) {
// If we're allowing a RAM cache, use the ModelPool to load the
// file.
if (!cache_only || ModelPool::has_model(pathname)) {
PT(PandaNode) node = ModelPool::load_model(pathname, options);
if (node != (PandaNode *)NULL &&
(options.get_flags() & LoaderOptions::LF_allow_instance) == 0) {
// But return a deep copy of the shared model.
node = node->copy_subgraph();
}
return node;
}
}
// Now that we've searched for the file, don't try to search again.
this_options.set_flags(this_options.get_flags() & ~LoaderOptions::LF_search);
bool report_errors = (options.get_flags() & LoaderOptions::LF_report_errors) != 0;
BamCache *cache = BamCache::get_global_ptr();
int num_files = results.get_num_files();
for (int i = 0; i < num_files; ++i) {
const Filename &path = results.get_file(i);
if (requested_type->get_allow_ram_cache(this_options)) {
// If we're allowing a RAM cache, use the ModelPool to load the
// file.
if (!cache_only || ModelPool::has_model(path)) {
PT(PandaNode) node = ModelPool::load_model(path, this_options);
if (node != (PandaNode *)NULL &&
(this_options.get_flags() & LoaderOptions::LF_allow_instance) == 0) {
// But return a deep copy of the shared model.
node = node->copy_subgraph();
PT(BamCacheRecord) record;
if (cache->get_active() && requested_type->get_allow_disk_cache(options)) {
// See if the model can be found in the on-disk cache, if it is
// active.
record = cache->lookup(pathname, "bam");
if (record != (BamCacheRecord *)NULL) {
if (record->has_data()) {
if (report_errors) {
loader_cat.info()
<< "Model " << pathname << " found in disk cache.\n";
}
return node;
}
}
PT(BamCacheRecord) record;
if (cache->get_active() && requested_type->get_allow_disk_cache(this_options)) {
// See if the model can be found in the on-disk cache, if it is
// active.
record = cache->lookup(path, "bam");
if (record != (BamCacheRecord *)NULL) {
if (record->has_data()) {
if (report_errors) {
loader_cat.info()
<< "Model " << path << " found in disk cache.\n";
}
PT(PandaNode) result = DCAST(PandaNode, record->extract_data());
if (premunge_data) {
SceneGraphReducer sgr;
sgr.premunge(result, RenderState::make_empty());
}
return result;
}
}
}
if (!cache_only) {
PT(PandaNode) result = requested_type->load_file(path, this_options, record);
if (result != (PandaNode *)NULL){
if (record != (BamCacheRecord *)NULL) {
record->set_data(result, false);
cache->store(record);
}
PT(PandaNode) result = DCAST(PandaNode, record->extract_data());
if (premunge_data) {
SceneGraphReducer sgr;
sgr.premunge(result, RenderState::make_empty());
@ -243,20 +263,23 @@ load_file(const Filename &filename, const LoaderOptions &options) const {
}
}
}
if (report_errors) {
// None of the matching files could be loaded. Oh well.
if (num_files > 1) {
loader_cat.error()
<< "Couldn't load file " << this_filename
<< ": all matching files on model path invalid "
<< "(the model path is currently: \"" << get_model_path() << "\")\n";
} else {
loader_cat.error()
<< "Couldn't load file " << this_filename
<< ": invalid.\n";
if (!cache_only) {
PT(PandaNode) result = requested_type->load_file(pathname, options, record);
if (result != (PandaNode *)NULL){
if (record != (BamCacheRecord *)NULL) {
record->set_data(result, false);
cache->store(record);
}
if (premunge_data) {
SceneGraphReducer sgr;
sgr.premunge(result, RenderState::make_empty());
}
return result;
}
}
return NULL;
}

View File

@ -88,7 +88,8 @@ PUBLISHED:
private:
PT(PandaNode) load_file(const Filename &filename, const LoaderOptions &options) const;
PT(PandaNode) try_load_file(const Filename &pathname, const LoaderOptions &options,
LoaderFileType *requested_type) const;
static void load_file_types();
static bool _file_types_loaded;

View File

@ -48,7 +48,7 @@ ns_has_model(const string &filename) {
MutexHolder holder(_lock);
Models::const_iterator ti;
ti = _models.find(filename);
if (ti != _models.end()) {
if (ti != _models.end() && (*ti).second != (ModelRoot *)NULL) {
// This model was previously loaded.
return true;
}
@ -73,28 +73,27 @@ ns_load_model(const string &filename, const LoaderOptions &options) {
}
}
loader_cat.info()
<< "Loading model " << filename << "\n";
LoaderOptions new_options(options);
new_options.set_flags((new_options.get_flags() | LoaderOptions::LF_no_ram_cache) &
~LoaderOptions::LF_search);
~(LoaderOptions::LF_search | LoaderOptions::LF_report_errors));
PT(PandaNode) panda_node = model_loader.load_sync(filename, new_options);
PT(ModelRoot) node;
if (panda_node.is_null()) {
// This model was not found.
return (ModelRoot *)NULL;
}
PT(ModelRoot) node;
if (panda_node->is_of_type(ModelRoot::get_class_type())) {
node = DCAST(ModelRoot, panda_node);
} else {
// We have to construct a ModelRoot node to put it under.
node = new ModelRoot(filename);
node->add_child(panda_node);
if (panda_node->is_of_type(ModelRoot::get_class_type())) {
node = DCAST(ModelRoot, panda_node);
} else {
// We have to construct a ModelRoot node to put it under.
node = new ModelRoot(filename);
node->add_child(panda_node);
}
node->set_fullpath(filename);
}
node->set_fullpath(filename);
{
MutexHolder holder(_lock);
@ -194,7 +193,8 @@ ns_garbage_collect() {
Models::iterator ti;
for (ti = _models.begin(); ti != _models.end(); ++ti) {
ModelRoot *node = (*ti).second;
if (node->get_model_ref_count() == 1) {
if (node == (ModelRoot *)NULL ||
node->get_model_ref_count() == 1) {
if (loader_cat.is_debug()) {
loader_cat.debug()
<< "Releasing " << (*ti).first << "\n";
@ -221,13 +221,18 @@ ns_list_contents(ostream &out) const {
out << "model pool contents:\n";
Models::const_iterator ti;
int num_models = 0;
for (ti = _models.begin(); ti != _models.end(); ++ti) {
out << (*ti).first << "\n"
<< " (count = " << (*ti).second->get_model_ref_count()
<< ")\n";
if ((*ti).second != NULL) {
++num_models;
out << (*ti).first << "\n"
<< " (count = " << (*ti).second->get_model_ref_count()
<< ")\n";
}
}
out << "total number of models: " << _models.size() << "\n";
out << "total number of models: " << num_models << " (plus "
<< _models.size() - num_models << " entries for nonexistent files)\n";
}
////////////////////////////////////////////////////////////////////