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
This commit is contained in:
Richard Heck 2008-04-25 20:03:03 +00:00
parent 45eee3cbbb
commit 2193a50605
10 changed files with 84 additions and 81 deletions

View 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());
}

View 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); }

View 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();

View 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;

View 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 \

View 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); }

View File

@ -186,7 +186,7 @@ private:
private:
/// The BibTeX information available to the dialog
BiblioInfo bibkeysInfo_;
BiblioInfo const & bibInfo() const;
};
} // namespace frontend

View 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;

View 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();

View 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);
}
}