Browse Source

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

David Rose 18 years ago
parent
commit
c52f7d6427

+ 4 - 10
panda/src/egg2pg/load_egg_file.cxx

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

+ 3 - 10
panda/src/pgraph/bamFile.cxx

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

+ 95 - 72
panda/src/pgraph/loader.cxx

@@ -146,95 +146,115 @@ load_file(const Filename &filename, const LoaderOptions &options) const {
     return NULL;
     return NULL;
   }
   }
 
 
-  DSearchPath::Results results;
   bool search = (this_options.get_flags() & LoaderOptions::LF_search) != 0;
   bool search = (this_options.get_flags() & LoaderOptions::LF_search) != 0;
   if (!filename.is_local()) {
   if (!filename.is_local()) {
     // If we have a global filename, we don't search the model path.
     // If we have a global filename, we don't search the model path.
     search = false;
     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();
   VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
-    
+
   if (search) {
   if (search) {
     // Look for the file along the model path.
     // Look for the file along the model path.
-    vfs->find_all_files(this_filename, get_model_path(), results);
+    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 (results.get_num_files() == 0) {
-      if (report_errors) {
+    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()
         loader_cat.error()
-          << "Couldn't load file " << this_filename << ": not found on model path "
-          << "(which is currently: \"" << get_model_path() << "\")\n";
+          << "Couldn't load file " << this_filename
+          << ": not found on model path "
+          << "(currently: \"" << get_model_path() << "\")\n";
       }
       }
-      return NULL;
     }
     }
 
 
   } else {
   } else {
     // Look for the file only where it is.
     // 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()
         loader_cat.error()
           << "Couldn't load file " << this_filename << ": does not exist.\n";
           << "Couldn't load file " << this_filename << ": does not exist.\n";
       }
       }
-      return NULL;
     }
     }
   }
   }
+  return NULL;
+}
 
 
-  // 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);
-
+////////////////////////////////////////////////////////////////////
+//     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();
   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();
-        }
-        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;
-        }
+  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;
     }
     }
+  }
 
 
-    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);
+  bool report_errors = (options.get_flags() & LoaderOptions::LF_report_errors) != 0;
+
+  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";
         }
         }
-
+        PT(PandaNode) result = DCAST(PandaNode, record->extract_data());
         if (premunge_data) {
         if (premunge_data) {
           SceneGraphReducer sgr;
           SceneGraphReducer sgr;
           sgr.premunge(result, RenderState::make_empty());
           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;
   return NULL;
 }
 }
 
 

+ 2 - 1
panda/src/pgraph/loader.h

@@ -88,7 +88,8 @@ PUBLISHED:
 
 
 private:
 private:
   PT(PandaNode) load_file(const Filename &filename, const LoaderOptions &options) const;
   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 void load_file_types();
   static bool _file_types_loaded;
   static bool _file_types_loaded;
 
 

+ 24 - 19
panda/src/pgraph/modelPool.cxx

@@ -48,7 +48,7 @@ ns_has_model(const string &filename) {
   MutexHolder holder(_lock);
   MutexHolder holder(_lock);
   Models::const_iterator ti;
   Models::const_iterator ti;
   ti = _models.find(filename);
   ti = _models.find(filename);
-  if (ti != _models.end()) {
+  if (ti != _models.end() && (*ti).second != (ModelRoot *)NULL) {
     // This model was previously loaded.
     // This model was previously loaded.
     return true;
     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);
   LoaderOptions new_options(options);
   new_options.set_flags((new_options.get_flags() | LoaderOptions::LF_no_ram_cache) &
   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(PandaNode) panda_node = model_loader.load_sync(filename, new_options);
+  PT(ModelRoot) node;
+
   if (panda_node.is_null()) {
   if (panda_node.is_null()) {
     // This model was not found.
     // 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 {
   } 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);
     MutexHolder holder(_lock);
@@ -194,7 +193,8 @@ ns_garbage_collect() {
   Models::iterator ti;
   Models::iterator ti;
   for (ti = _models.begin(); ti != _models.end(); ++ti) {
   for (ti = _models.begin(); ti != _models.end(); ++ti) {
     ModelRoot *node = (*ti).second;
     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()) {
       if (loader_cat.is_debug()) {
         loader_cat.debug()
         loader_cat.debug()
           << "Releasing " << (*ti).first << "\n";
           << "Releasing " << (*ti).first << "\n";
@@ -221,13 +221,18 @@ ns_list_contents(ostream &out) const {
   out << "model pool contents:\n";
   out << "model pool contents:\n";
   
   
   Models::const_iterator ti;
   Models::const_iterator ti;
+  int num_models = 0;
   for (ti = _models.begin(); ti != _models.end(); ++ti) {
   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";
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////