commit 88a0666d6c039decfbd0da0dee6c9b4ba4923806
Author: Juergen Spitzmueller <sp...@lyx.org>
Date:   Wed Oct 18 09:20:31 2017 +0200

    Do not scan BibTeX files multiple times in a collectBibKeys() procedure.
    
    Scanning is rather slow, so this improves performance in specific
    situations (multiple inclusion of larger files in master/child or
    chapterbib context)
---
 src/Buffer.cpp              |    7 ++++---
 src/Buffer.h                |    3 ++-
 src/insets/Inset.h          |    3 ++-
 src/insets/InsetBibitem.cpp |    2 +-
 src/insets/InsetBibitem.h   |    2 +-
 src/insets/InsetBibtex.cpp  |   15 +++++++++++----
 src/insets/InsetBibtex.h    |    4 ++--
 src/insets/InsetInclude.cpp |    4 ++--
 src/insets/InsetInclude.h   |    2 +-
 9 files changed, 26 insertions(+), 16 deletions(-)

diff --git a/src/Buffer.cpp b/src/Buffer.cpp
index f6773d5..c564a7d 100644
--- a/src/Buffer.cpp
+++ b/src/Buffer.cpp
@@ -2446,15 +2446,16 @@ void Buffer::reloadBibInfoCache() const
                return;
 
        d->bibinfo_.clear();
-       collectBibKeys();
+       FileNameList checkedFiles;
+       collectBibKeys(checkedFiles);
        d->bibinfo_cache_valid_ = true;
 }
 
 
-void Buffer::collectBibKeys() const
+void Buffer::collectBibKeys(FileNameList & checkedFiles) const
 {
        for (InsetIterator it = inset_iterator_begin(inset()); it; ++it)
-               it->collectBibKeys(it);
+               it->collectBibKeys(it, checkedFiles);
 }
 
 
diff --git a/src/Buffer.h b/src/Buffer.h
index 6d50e70..0bfe18f 100644
--- a/src/Buffer.h
+++ b/src/Buffer.h
@@ -17,6 +17,7 @@
 #include "support/unique_ptr.h"
 #include "support/strfwd.h"
 #include "support/types.h"
+#include "support/FileNameList.h"
 
 #include <map>
 #include <list>
@@ -520,7 +521,7 @@ public:
        /// or just for it, if it isn't a child.
        BiblioInfo const & masterBibInfo() const;
        /// collect bibliography info from the various insets in this buffer.
-       void collectBibKeys() const;
+       void collectBibKeys(support::FileNameList &) const;
        /// add some BiblioInfo to our cache
        void addBiblioInfo(BiblioInfo const & bi) const;
        /// add a single piece of bibliography info to our cache
diff --git a/src/insets/Inset.h b/src/insets/Inset.h
index 578a7f4..94e9d1a 100644
--- a/src/insets/Inset.h
+++ b/src/insets/Inset.h
@@ -23,6 +23,7 @@
 
 #include "support/strfwd.h"
 #include "support/types.h"
+#include "support/FileNameList.h"
 
 #include <climits>
 
@@ -529,7 +530,7 @@ public:
                              UpdateType /* utype*/,
                              TocBackend & /* tocbackend */) const {}
        /// Collect BibTeX information
-       virtual void collectBibKeys(InsetIterator const &) const {}
+       virtual void collectBibKeys(InsetIterator const &, 
support::FileNameList &) const {}
        /// Update the counters of this inset and of its contents.
        /// The boolean indicates whether we are preparing for output, e.g.,
        /// of XHTML.
diff --git a/src/insets/InsetBibitem.cpp b/src/insets/InsetBibitem.cpp
index afc30ae..d5ebaf7 100644
--- a/src/insets/InsetBibitem.cpp
+++ b/src/insets/InsetBibitem.cpp
@@ -285,7 +285,7 @@ docstring bibitemWidest(Buffer const & buffer, OutputParams 
const & runparams)
 }
 
 
-void InsetBibitem::collectBibKeys(InsetIterator const & it) const
+void InsetBibitem::collectBibKeys(InsetIterator const & it, FileNameList & 
/*checkedFiles*/) const
 {
        docstring const key = getParam("key");
        docstring const label = getParam("label");
diff --git a/src/insets/InsetBibitem.h b/src/insets/InsetBibitem.h
index 41497e1..ba33732 100644
--- a/src/insets/InsetBibitem.h
+++ b/src/insets/InsetBibitem.h
@@ -60,7 +60,7 @@ public:
        ///
        docstring xhtml(XHTMLStream &, OutputParams const &) const;
        ///
-       void collectBibKeys(InsetIterator const &) const;
+       void collectBibKeys(InsetIterator const &, support::FileNameList &) 
const;
        /// update the counter of this inset
        void updateBuffer(ParIterator const &, UpdateType);
        ///@}
diff --git a/src/insets/InsetBibtex.cpp b/src/insets/InsetBibtex.cpp
index a905110..30b169a 100644
--- a/src/insets/InsetBibtex.cpp
+++ b/src/insets/InsetBibtex.cpp
@@ -645,13 +645,13 @@ namespace {
 } // namespace
 
 
-void InsetBibtex::collectBibKeys(InsetIterator const & /*di*/) const
+void InsetBibtex::collectBibKeys(InsetIterator const & /*di*/, FileNameList & 
checkedFiles) const
 {
-       parseBibTeXFiles();
+       parseBibTeXFiles(checkedFiles);
 }
 
 
-void InsetBibtex::parseBibTeXFiles() const
+void InsetBibtex::parseBibTeXFiles(FileNameList & checkedFiles) const
 {
        // This bibtex parser is a first step to parse bibtex files
        // more precisely.
@@ -678,7 +678,14 @@ void InsetBibtex::parseBibTeXFiles() const
        support::FileNamePairList::const_iterator it = files.begin();
        support::FileNamePairList::const_iterator en = files.end();
        for (; it != en; ++ it) {
-               ifdocstream ifs(it->second.toFilesystemEncoding().c_str(),
+               FileName const bibfile = it->second;
+               if (find(checkedFiles.begin(), checkedFiles.end(), bibfile) != 
checkedFiles.end())
+                       // already checked this one. Skip.
+                       continue;
+               else
+                       // record that we check this.
+                       checkedFiles.push_back(bibfile);
+               ifdocstream ifs(bibfile.toFilesystemEncoding().c_str(),
                        ios_base::in, 
buffer().masterParams().encoding().iconvName());
 
                char_type ch;
diff --git a/src/insets/InsetBibtex.h b/src/insets/InsetBibtex.h
index 3ba96a2..2d03346 100644
--- a/src/insets/InsetBibtex.h
+++ b/src/insets/InsetBibtex.h
@@ -57,7 +57,7 @@ public:
        int plaintext(odocstringstream & ods, OutputParams const & op,
                      size_t max_length = INT_MAX) const;
        ///
-       void collectBibKeys(InsetIterator const &) const;
+       void collectBibKeys(InsetIterator const &, support::FileNameList &) 
const;
        ///
        void validate(LaTeXFeatures &) const;
        ///
@@ -84,7 +84,7 @@ private:
        ///
        void editDatabases() const;
        ///
-       void parseBibTeXFiles() const;
+       void parseBibTeXFiles(support::FileNameList &) const;
        ///
        bool usingBiblatex() const;
 
diff --git a/src/insets/InsetInclude.cpp b/src/insets/InsetInclude.cpp
index 6af715f..d6e3ae2 100644
--- a/src/insets/InsetInclude.cpp
+++ b/src/insets/InsetInclude.cpp
@@ -1072,7 +1072,7 @@ void InsetInclude::validate(LaTeXFeatures & features) 
const
 }
 
 
-void InsetInclude::collectBibKeys(InsetIterator const & /*di*/) const
+void InsetInclude::collectBibKeys(InsetIterator const & /*di*/, FileNameList & 
checkedFiles) const
 {
        Buffer * child = loadIfNeeded();
        if (!child)
@@ -1082,7 +1082,7 @@ void InsetInclude::collectBibKeys(InsetIterator const & 
/*di*/) const
        // But it'll have to do for now.
        if (child == &buffer())
                return;
-       child->collectBibKeys();
+       child->collectBibKeys(checkedFiles);
 }
 
 
diff --git a/src/insets/InsetInclude.h b/src/insets/InsetInclude.h
index 7be5f78..009b49e 100644
--- a/src/insets/InsetInclude.h
+++ b/src/insets/InsetInclude.h
@@ -92,7 +92,7 @@ public:
         *  \param keys the list of bibkeys in the child buffer.
         *  \param it not used here
         */
-       void collectBibKeys(InsetIterator const &) const;
+       void collectBibKeys(InsetIterator const &, support::FileNameList &) 
const;
        ///
        bool hasSettings() const { return true; }
        ///

Reply via email to