From: Richard Heck Date: Fri, 25 Apr 2008 20:03:03 +0000 (+0000) Subject: Implement a cache for BibTeX data. There was a cache of sorts already in InsetCitatio... X-Git-Tag: 1.6.10~4993 X-Git-Url: https://git.lyx.org/gitweb/?a=commitdiff_plain;h=2193a506052002f66bd6c2929e208ba795549cf1;p=features.git Implement a cache for BibTeX data. There was a cache of sorts already in InsetCitation, but that was being used only to cache the labels. So that has been moved to Buffer, and everything else that needs access to BibTeX data should call either Buffer::localBibInfo(), which gives you the BiblioInfo for this Buffer, or Buffer::masterBibInfo(), which gives you the BiblioInfo for the Buffer's master, if it has one, or for it, otherwise. Normally, what you want is masterBibInfo(). 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 --- diff --git a/src/BiblioInfo.cpp b/src/BiblioInfo.cpp index 2d05c4911f..d83be514b5 100644 --- a/src/BiblioInfo.cpp +++ b/src/BiblioInfo.cpp @@ -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 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()); } diff --git a/src/BiblioInfo.h b/src/BiblioInfo.h index 66252e712e..11a6361da8 100644 --- a/src/BiblioInfo.h +++ b/src/BiblioInfo.h @@ -44,9 +44,11 @@ class BibTeXInfo { public: /// typedef std::map::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 const getFields() const; /// Returns a sorted vector of BibTeX entry types in use std::vector 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); } diff --git a/src/Buffer.cpp b/src/Buffer.cpp index 6ecdacf9b4..2caf701774 100644 --- a/src/Buffer.cpp +++ b/src/Buffer.cpp @@ -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 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 labels; string paramName; - BiblioInfo keys; - keys.fillWithBibKeys(this); + BiblioInfo const & keys = masterBibInfo(); BiblioInfo::const_iterator bit = keys.begin(); BiblioInfo::const_iterator bend = keys.end(); diff --git a/src/Buffer.h b/src/Buffer.h index 8d0e66a097..95d1386866 100644 --- a/src/Buffer.h +++ b/src/Buffer.h @@ -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 &) const; diff --git a/src/Makefile.am b/src/Makefile.am index 16614f76dc..f88b2f64dc 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 \ diff --git a/src/frontends/qt4/GuiCitation.cpp b/src/frontends/qt4/GuiCitation.cpp index bb9f0897b6..c70b7c5938 100644 --- a/src/frontends/qt4/GuiCitation.cpp +++ b/src/frontends/qt4/GuiCitation.cpp @@ -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 GuiCitation::availableKeys() const { - return bibkeysInfo_.getKeys(); + return bibInfo().getKeys(); } vector GuiCitation::availableFields() const { - return bibkeysInfo_.getFields(); + return bibInfo().getFields(); } vector GuiCitation::availableEntries() const { - return bibkeysInfo_.getEntries(); + return bibInfo().getEntries(); } @@ -662,8 +660,8 @@ void GuiCitation::filterByEntryType( vector 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 GuiCitation::searchKeys( vector::const_iterator it = keys_to_search.begin(); vector::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); } diff --git a/src/frontends/qt4/GuiCitation.h b/src/frontends/qt4/GuiCitation.h index 9c8b504444..a3f6351024 100644 --- a/src/frontends/qt4/GuiCitation.h +++ b/src/frontends/qt4/GuiCitation.h @@ -186,7 +186,7 @@ private: private: /// The BibTeX information available to the dialog - BiblioInfo bibkeysInfo_; + BiblioInfo const & bibInfo() const; }; } // namespace frontend diff --git a/src/insets/InsetBibitem.cpp b/src/insets/InsetBibitem.cpp index e2195fe596..93015395e0 100644 --- a/src/insets/InsetBibitem.cpp +++ b/src/insets/InsetBibitem.cpp @@ -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 bibkeys = keys.getKeys(); + vector bibkeys = buffer().masterBibInfo().getKeys(); int i = 1; diff --git a/src/insets/InsetCitation.cpp b/src/insets/InsetCitation.cpp index 33298c827b..dbc68316fc 100644 --- a/src/insets/InsetCitation.cpp +++ b/src/insets/InsetCitation.cpp @@ -137,37 +137,7 @@ docstring complexLabel(Buffer const & buffer, if (!buffer.isFullyLoaded()) return docstring(); - // Cache the labels - typedef map CachedMap; - static CachedMap cached_keys; - - // and cache the timestamp of the bibliography files. - static map 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(); diff --git a/src/insets/InsetInclude.cpp b/src/insets/InsetInclude.cpp index d56f97dc50..d22db7c5df 100644 --- a/src/insets/InsetInclude.cpp +++ b/src/insets/InsetInclude.cpp @@ -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); } }