]> git.lyx.org Git - features.git/commitdiff
Implement a cache for BibTeX data. There was a cache of sorts already in InsetCitatio...
authorRichard Heck <rgheck@comcast.net>
Fri, 25 Apr 2008 20:03:03 +0000 (20:03 +0000)
committerRichard Heck <rgheck@comcast.net>
Fri, 25 Apr 2008 20:03:03 +0000 (20:03 +0000)
Thanks to Andre for help with linking problems.

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@24505 a592a061-630c-0410-9148-cb99ea01b6c8

src/BiblioInfo.cpp
src/BiblioInfo.h
src/Buffer.cpp
src/Buffer.h
src/Makefile.am
src/frontends/qt4/GuiCitation.cpp
src/frontends/qt4/GuiCitation.h
src/insets/InsetBibitem.cpp
src/insets/InsetCitation.cpp
src/insets/InsetInclude.cpp

index 2d05c4911f2a5e10168e04a1d019dd89ce8fa0da..d83be514b5e5354450ec2eafb6f7555ed70ee0fd 100644 (file)
@@ -43,16 +43,11 @@ namespace lyx {
 //
 //////////////////////////////////////////////////////////////////////
 
-BibTeXInfo::BibTeXInfo(bool ib)
-       : is_bibtex_(ib)
-{}
-
-       
 BibTeXInfo::BibTeXInfo(docstring const & key, docstring const & type)
        : is_bibtex_(true), bib_key_(key), entry_type_(type)
 {}
 
-       
+
 bool BibTeXInfo::hasField(docstring const & field) const
 {
        return count(field) == 1;
@@ -75,7 +70,7 @@ docstring const & BibTeXInfo::getValueForField(string const & field) const
 }
 
 
-static docstring familyName(docstring const & name)
+docstring familyName(docstring const & name)
 {
        if (name.empty())
                return docstring();
@@ -416,19 +411,9 @@ vector<docstring> const BiblioInfo::getAuthorYearStrings(
 }
 
 
-void BiblioInfo::fillWithBibKeys(Buffer const * const buf)
-{      
-       /// if this is a child document and the parent is already loaded
-       /// use the parent's list instead  [ale990412]
-       Buffer const * const tmp = buf->masterBuffer();
-       LASSERT(tmp, return);
-       if (tmp != buf) {
-               this->fillWithBibKeys(tmp);
-               return;
-       }
-
-       for (InsetIterator it = inset_iterator_begin(buf->inset()); it; ++it)
-               it->fillWithBibKeys(*this, it);
+void BiblioInfo::mergeBiblioInfo(BiblioInfo const & info)
+{
+       bimap_.insert(info.begin(), info.end());
 }
 
 
index 66252e712e407ab11868db7d5335b50c13f874ea..11a6361da807387fead5b94929295f8b0a38a972 100644 (file)
@@ -44,9 +44,11 @@ class BibTeXInfo {
 public:
        ///
        typedef std::map<docstring, docstring>::const_iterator const_iterator;
+       ///
+       BibTeXInfo() : is_bibtex_(true) {}
        /// argument sets isBibTeX_, so should be false only if it's coming
        /// from a bibliography environment
-       BibTeXInfo(bool ib = true);
+       BibTeXInfo(bool ib) : is_bibtex_(ib) {}
        /// constructor that sets the entryType
        BibTeXInfo(docstring const & key, docstring const & type);
        /// Search for the given field and return the associated info.
@@ -106,9 +108,6 @@ public:
        std::vector<docstring> const getFields() const;
        /// Returns a sorted vector of BibTeX entry types in use
        std::vector<docstring> const getEntries() const;
-       /// Fills keys with BibTeX information derived from the various insets
-       /// in a given buffer, in its master document.
-       void fillWithBibKeys(Buffer const * const buf);
        /// return the short form of an authorlist
        docstring const getAbbreviatedAuthor(docstring const & key) const;
        /// return the year from the bibtex data record
@@ -157,6 +156,8 @@ public:
        ///
        const_iterator find(docstring const & f) const { return bimap_.find(f); }
        ///
+       void mergeBiblioInfo(BiblioInfo const & info);
+       ///
        BibTeXInfo & operator[](docstring const & f) { return bimap_[f]; }
        ///
        void addFieldName(docstring const & f) { field_names_.insert(f); }
index 6ecdacf9b42c579ebd219d63fcf791e840b77128..2caf701774cb5387551f997ec1e8da9c3a84e940 100644 (file)
@@ -204,6 +204,9 @@ public:
        /// documents), needed for appropriate update of natbib labels.
        mutable support::FileNameList bibfilesCache_;
 
+       /// A cache for bibliography info
+       mutable BiblioInfo bibinfo_;
+
        mutable RefCache ref_cache_;
 
        /// our Text that should be wrapped in an InsetText
@@ -233,8 +236,8 @@ static FileName createBufferTmpDir()
 Buffer::Impl::Impl(Buffer & parent, FileName const & file, bool readonly_)
        : parent_buffer(0), lyx_clean(true), bak_clean(true), unnamed(false),
          read_only(readonly_), filename(file), file_fully_loaded(false),
-         toc_backend(&parent), macro_lock(false),
-         timestamp_(0), checksum_(0), wa_(0), undo_(parent)
+         toc_backend(&parent), macro_lock(false), timestamp_(0), 
+         checksum_(0), wa_(0), undo_(parent)
 {
        temppath = createBufferTmpDir();
        lyxvc.setBuffer(&parent);
@@ -1343,6 +1346,45 @@ support::FileNameList const & Buffer::getBibfilesCache() const
 }
 
 
+BiblioInfo const & Buffer::masterBibInfo() const
+{      
+       // if this is a child document and the parent is already loaded
+       // use the parent's list instead  [ale990412]
+       Buffer const * const tmp = masterBuffer();
+       LASSERT(tmp, /**/);
+       if (tmp != this)
+               return tmp->masterBibInfo();
+       return localBibInfo();
+}
+
+
+BiblioInfo const & Buffer::localBibInfo() const
+{      
+       // cache the timestamp of the bibliography files.
+       static map<FileName, time_t> bibfileStatus;
+
+       support::FileNameList const & bibfilesCache = getBibfilesCache();
+       // compare the cached timestamps with the actual ones.
+       bool changed = false;
+       support::FileNameList::const_iterator ei = bibfilesCache.begin();
+       support::FileNameList::const_iterator en = bibfilesCache.end();
+       for (; ei != en; ++ ei) {
+               time_t lastw = ei->lastModified();
+               if (lastw != bibfileStatus[*ei]) {
+                       changed = true;
+                       bibfileStatus[*ei] = lastw;
+                       break;
+               }
+       }
+
+       if (changed) {
+               for (InsetIterator it = inset_iterator_begin(inset()); it; ++it)
+                       it->fillWithBibKeys(d->bibinfo_, it);
+       }
+       return d->bibinfo_;
+}
+
+
 bool Buffer::isDepClean(string const & name) const
 {
        DepClean::const_iterator const it = d->dep_clean.find(name);
@@ -1978,8 +2020,7 @@ void Buffer::changeRefsIfUnique(docstring const & from, docstring const & to,
        // Check if the label 'from' appears more than once
        vector<docstring> labels;
        string paramName;
-       BiblioInfo keys;
-       keys.fillWithBibKeys(this);
+       BiblioInfo const & keys = masterBibInfo();
        BiblioInfo::const_iterator bit  = keys.begin();
        BiblioInfo::const_iterator bend = keys.end();
 
index 8d0e66a097e842f84558e1ee02bac3ec1cc27786..95d1386866874f118628f1d95f768a6b93072600 100644 (file)
@@ -24,6 +24,7 @@
 
 namespace lyx {
 
+class BiblioInfo;
 class BufferParams;
 class DocIterator;
 class ErrorItem;
@@ -308,6 +309,11 @@ public:
        /// Return the cache with all bibfiles in use (including bibfiles
        /// of loaded child documents).
        support::FileNameList const & getBibfilesCache() const;
+       /// \return the bibliography information for this buffer's master,
+       /// or just for it, if it isn't a child.
+       BiblioInfo const & masterBibInfo() const;
+       /// \return the bibliography information for this buffer ONLY.
+       BiblioInfo const & localBibInfo() const;
        ///
        void getLabelList(std::vector<docstring> &) const;
 
index 16614f76dc8d178cba2eda3c7c7fec849e32556c..f88b2f64dce6b54ba5088b2e0d72700b2adb81a7 100644 (file)
@@ -61,6 +61,8 @@ endif
 lyx_SOURCES = \
        main.cpp \
        $(ASPELL) $(PSPELL) $(ISPELL) SpellBase.cpp \
+       BiblioInfo.h \
+       BiblioInfo.cpp \
        Box.cpp \
        Box.h \
        Dimension.cpp \
@@ -76,7 +78,6 @@ endif
 
 SOURCEFILESCORE = \
        Author.cpp \
-       BiblioInfo.cpp \
        Bidi.cpp \
        boost.cpp \
        BranchList.cpp \
@@ -169,7 +170,6 @@ SOURCEFILESCORE = \
 
 HEADERFILESCORE = \
        Author.h \
-       BiblioInfo.h \
        Bidi.h \
        BranchList.h \
        buffer_funcs.h \
index bb9f0897b6a97cea85df37655844eed572fbda19..c70b7c5938eeac5d2478677e10ba33eb823f5805 100644 (file)
@@ -599,7 +599,7 @@ QStringList GuiCitation::getEntriesAsQStringList()
 QStringList GuiCitation::citationStyles(int sel)
 {
        docstring const key = qstring_to_ucs4(cited_keys_[sel]);
-       return to_qstring_list(bibkeysInfo_.getCiteStrings(key, buffer()));
+       return to_qstring_list(bibInfo().getCiteStrings(key, buffer()));
 }
 
 
@@ -619,7 +619,6 @@ bool GuiCitation::initialiseParams(string const & data)
 {
        InsetCommand::string2params("citation", data, params_);
        CiteEngine const engine = buffer().params().citeEngine();
-       bibkeysInfo_.fillWithBibKeys(&buffer());
        citeStyles_ = citeStyles(engine);
        return true;
 }
@@ -628,25 +627,24 @@ bool GuiCitation::initialiseParams(string const & data)
 void GuiCitation::clearParams()
 {
        params_.clear();
-       bibkeysInfo_.clear();
 }
 
 
 vector<docstring> GuiCitation::availableKeys() const
 {
-       return bibkeysInfo_.getKeys();
+       return bibInfo().getKeys();
 }
 
 
 vector<docstring> GuiCitation::availableFields() const
 {
-       return bibkeysInfo_.getFields();
+       return bibInfo().getFields();
 }
 
 
 vector<docstring> GuiCitation::availableEntries() const
 {
-       return bibkeysInfo_.getEntries();
+       return bibInfo().getEntries();
 }
 
 
@@ -662,8 +660,8 @@ void GuiCitation::filterByEntryType(
        vector<docstring> result;
        for (; it != end; ++it) {
                docstring const key = *it;
-               BiblioInfo::const_iterator cit = bibkeysInfo_.find(key);
-               if (cit == bibkeysInfo_.end())
+               BiblioInfo::const_iterator cit = bibInfo().find(key);
+               if (cit == bibInfo().end())
                        continue;
                if (cit->second.entryType() == entry_type)
                        result.push_back(key);
@@ -680,10 +678,10 @@ CiteEngine GuiCitation::citeEngine() const
 
 docstring GuiCitation::getInfo(docstring const & key) const
 {
-       if (bibkeysInfo_.empty())
+       if (bibInfo().empty())
                return docstring();
 
-       return bibkeysInfo_.getInfo(key);
+       return bibInfo().getInfo(key);
 }
 
 
@@ -740,8 +738,8 @@ vector<docstring> GuiCitation::searchKeys(
        vector<docstring>::const_iterator it = keys_to_search.begin();
        vector<docstring>::const_iterator end = keys_to_search.end();
        for (; it != end; ++it ) {
-               BiblioInfo::const_iterator info = bibkeysInfo_.find(*it);
-               if (info == bibkeysInfo_.end())
+               BiblioInfo::const_iterator info = bibInfo().find(*it);
+               if (info == bibInfo().end())
                        continue;
                
                BibTeXInfo const & kvm = info->second;
@@ -776,6 +774,12 @@ void GuiCitation::dispatchParams()
 }
 
 
+BiblioInfo const & GuiCitation::bibInfo() const
+{
+       return buffer().masterBibInfo();
+}
+
+
 Dialog * createGuiCitation(GuiView & lv) { return new GuiCitation(lv); }
 
 
index 9c8b504444260a3fc306e611d11d17f0af2c0cdf..a3f6351024e2444bded1debf1f38bcf3bc9305c0 100644 (file)
@@ -186,7 +186,7 @@ private:
 
 private:
        /// The BibTeX information available to the dialog
-       BiblioInfo bibkeysInfo_;
+       BiblioInfo const & bibInfo() const;
 };
 
 } // namespace frontend
index e2195fe5968992c264425c68b7d58295e5a6d8bc..93015395e0697d00029fe271bc3dbf488856f5e7 100644 (file)
@@ -66,9 +66,7 @@ void InsetBibitem::updateCommand(docstring const & new_key, bool)
        docstring const old_key = getParam("key");
        docstring key = new_key;
 
-       BiblioInfo keys;
-       keys.fillWithBibKeys(&buffer());
-       vector<docstring> bibkeys = keys.getKeys();
+       vector<docstring> bibkeys = buffer().masterBibInfo().getKeys();
 
        int i = 1;
 
index 33298c827b4ce738404a019a129216b2452af6b0..dbc68316fcc97e0efb79255caaee257cef9b33d9 100644 (file)
@@ -137,37 +137,7 @@ docstring complexLabel(Buffer const & buffer,
        if (!buffer.isFullyLoaded())
                return docstring();
 
-       // Cache the labels
-       typedef map<Buffer const *, BiblioInfo> CachedMap;
-       static CachedMap cached_keys;
-
-       // and cache the timestamp of the bibliography files.
-       static map<FileName, time_t> bibfileStatus;
-
-       BiblioInfo biblist;
-
-       support::FileNameList const & bibfilesCache = buffer.getBibfilesCache();
-       // compare the cached timestamps with the actual ones.
-       bool changed = false;
-       support::FileNameList::const_iterator ei = bibfilesCache.begin();
-       support::FileNameList::const_iterator en = bibfilesCache.end();
-       for (; ei != en; ++ ei) {
-               time_t lastw = ei->lastModified();
-               if (lastw != bibfileStatus[*ei]) {
-                       changed = true;
-                       bibfileStatus[*ei] = lastw;
-               }
-       }
-
-       // build the list only if the bibfiles have been changed
-       if (cached_keys[&buffer].empty() || bibfileStatus.empty() || changed) {
-               biblist.fillWithBibKeys(&buffer);
-               cached_keys[&buffer] = biblist;
-       } else {
-               // use the cached keys
-               biblist = cached_keys[&buffer];
-       }
-
+       BiblioInfo const & biblist = buffer.masterBibInfo();
        if (biblist.empty())
                return docstring();
 
index d56f97dc50c3b3c96e7d8c910efeb337e06542de..d22db7c5df3349e1225864a3b3b2a7c752533415 100644 (file)
@@ -685,10 +685,8 @@ void InsetInclude::fillWithBibKeys(BiblioInfo & keys,
        if (loadIfNeeded(buffer(), params())) {
                string const included_file = includedFilename(buffer(), params()).absFilename();
                Buffer * tmp = theBufferList().getBuffer(included_file);
-               //FIXME This is kind of a dirty hack and should be made reasonable.
-               tmp->setParent(0);
-               keys.fillWithBibKeys(tmp);
-               tmp->setParent(&buffer());
+               BiblioInfo const & newkeys = tmp->localBibInfo();
+               keys.mergeBiblioInfo(newkeys);
        }
 }