Speed up recent session display (for many large sessions)
authorRobin Gareus <robin@gareus.org>
Thu, 8 Dec 2016 09:36:12 +0000 (10:36 +0100)
committerRobin Gareus <robin@gareus.org>
Thu, 8 Dec 2016 09:36:12 +0000 (10:36 +0100)
- don't parse XML into XMLTree
- only read the file, extract relevant elements
- don't read session-template contents, only test file

libs/ardour/ardour/session.h
libs/ardour/ardour/template_utils.h
libs/ardour/session_state.cc
libs/ardour/template_utils.cc

index 924c7c86bb477c1b62769548742686a281b65277..3135e26333b225f8974ca5f021b734f38cab7a47 100644 (file)
@@ -2050,7 +2050,6 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
 
        void save_as_bring_callback (uint32_t, uint32_t, std::string);
 
-       static int get_session_info_from_path (XMLTree& state_tree, const std::string& xmlpath);
        static const uint32_t session_end_shift;
 
        std::string _template_state_dir;
index b2f155ee45f0c05d33e378b748a95d19b64aeb7c..9887ab9cdc9d6148c05809ba32e7cbb25822cb60 100644 (file)
@@ -40,7 +40,7 @@ namespace ARDOUR {
        };
 
        LIBARDOUR_API void find_route_templates (std::vector<TemplateInfo>& template_names);
-       LIBARDOUR_API void find_session_templates (std::vector<TemplateInfo>& template_names);
+       LIBARDOUR_API void find_session_templates (std::vector<TemplateInfo>& template_names, bool read_xml = false);
 
        LIBARDOUR_API std::string session_template_dir_to_file (std::string const &);
 
index f82212345d707aa11a7b43fd9be58f6d48ef771a..c9c687fcdd18a11c35ce54a9e7d413a4b4640f23 100644 (file)
@@ -4354,68 +4354,68 @@ Session::rename (const std::string& new_name)
 }
 
 int
-Session::get_session_info_from_path (XMLTree& tree, const string& xmlpath)
+Session::get_info_from_path (const string& xmlpath, float& sample_rate, SampleFormat& data_format)
 {
+       bool found_sr = false;
+       bool found_data_format = false;
+
        if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
                return -1;
-        }
+       }
 
-       if (!tree.read (xmlpath)) {
+       xmlParserCtxtPtr ctxt = xmlNewParserCtxt();
+       if (ctxt == NULL) {
                return -1;
        }
+       xmlDocPtr doc = xmlCtxtReadFile (ctxt, xmlpath.c_str(), NULL, XML_PARSE_HUGE);
 
-       return 0;
-}
-
-int
-Session::get_info_from_path (const string& xmlpath, float& sample_rate, SampleFormat& data_format)
-{
-       XMLTree tree;
-       bool found_sr = false;
-       bool found_data_format = false;
-
-       if (get_session_info_from_path (tree, xmlpath)) {
+       if (doc == NULL) {
+               xmlFreeParserCtxt(ctxt);
                return -1;
        }
 
-       /* sample rate */
-
-       XMLProperty const * prop;
-       XMLNode const * root (tree.root());
+       xmlNodePtr node = xmlDocGetRootElement(doc);
 
-       if ((prop = root->property (X_("sample-rate"))) != 0) {
-               sample_rate = atoi (prop->value());
-               found_sr = true;
+       if (node == NULL) {
+               xmlFreeParserCtxt(ctxt);
+               return -1;
        }
 
-       const XMLNodeList& children (root->children());
-       for (XMLNodeList::const_iterator c = children.begin(); c != children.end(); ++c) {
-               const XMLNode* child = *c;
-               if (child->name() == "Config") {
-                       const XMLNodeList& options (child->children());
-                       for (XMLNodeList::const_iterator oc = options.begin(); oc != options.end(); ++oc) {
-                               XMLNode const * option = *oc;
-                               XMLProperty const * name = option->property("name");
-
-                               if (!name) {
-                                       continue;
-                               }
+       /* sample rate */
 
-                               if (name->value() == "native-file-data-format") {
-                                       XMLProperty const * value = option->property ("value");
-                                       if (value) {
-                                               SampleFormat fmt = (SampleFormat) string_2_enum (option->property ("value")->value(), fmt);
-                                               data_format = fmt;
-                                               found_data_format = true;
-                                               break;
-                                       }
-                               }
-                       }
-               }
-               if (found_data_format) {
-                       break;
-               }
-       }
+       xmlAttrPtr attr;
+       for (attr = node->properties; attr; attr = attr->next) {
+               if (!strcmp ((const char*)attr->name, "sample-rate") && attr->children) {
+                       sample_rate = atoi ((char*)attr->children->content);
+                       found_sr = true;
+               }
+       }
+
+       node = node->children;
+       while (node != NULL) {
+                if (strcmp((const char*) node->name, "Config")) {
+                        node = node->next;
+                        continue;
+                }
+                for (node = node->children; node; node = node->next) {
+                        xmlChar* pv = xmlGetProp (node, (const xmlChar*)"name");
+                        if (pv && !strcmp ((const char*)pv, "native-file-data-format")) {
+                                xmlFree (pv);
+                                xmlChar* val = xmlGetProp (node, (const xmlChar*)"value");
+                                if (val) {
+                                        SampleFormat fmt = (SampleFormat) string_2_enum (string ((const char*)val), fmt);
+                                        data_format = fmt;
+                                        found_data_format = true;
+                                }
+                                xmlFree (val);
+                                break;
+                        }
+                        xmlFree (pv);
+                }
+                break;
+       }
+
+       xmlFreeParserCtxt(ctxt);
 
        return !(found_sr && found_data_format); // zero if they are both found
 }
index 7797440f0e0a1720e52108e221196ccbcf313422..b2fa703060b7ca56e3473dd51184d14d6f023ab1 100644 (file)
@@ -79,7 +79,7 @@ session_template_dir_to_file (string const & dir)
 
 
 void
-find_session_templates (vector<TemplateInfo>& template_names)
+find_session_templates (vector<TemplateInfo>& template_names, bool read_xml)
 {
        vector<string> templates;
 
@@ -95,10 +95,11 @@ find_session_templates (vector<TemplateInfo>& template_names)
        for (vector<string>::iterator i = templates.begin(); i != templates.end(); ++i) {
                string file = session_template_dir_to_file (*i);
 
-               XMLTree tree;
-
-               if (!tree.read (file.c_str())) {
-                       continue;
+               if (read_xml) {
+                       XMLTree tree;
+                       if (!tree.read (file.c_str())) {
+                               continue;
+                       }
                }
 
                TemplateInfo rti;