From 91adfb8894b4b8183c2948712d56a97bb9d93d9f Mon Sep 17 00:00:00 2001 From: John Ericson Date: Wed, 10 Mar 2021 02:20:32 +0000 Subject: Create some type aliases for string Contexts --- src/libexpr/eval-cache.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libexpr/eval-cache.cc') diff --git a/src/libexpr/eval-cache.cc b/src/libexpr/eval-cache.cc index 188223957..7e5b5c9c4 100644 --- a/src/libexpr/eval-cache.cc +++ b/src/libexpr/eval-cache.cc @@ -254,7 +254,7 @@ struct AttrDb return {{rowId, attrs}}; } case AttrType::String: { - std::vector> context; + NixStringContext context; if (!queryAttribute.isNull(3)) for (auto & s : tokenizeString>(queryAttribute.getStr(3), ";")) context.push_back(decodeContext(s)); -- cgit v1.2.3 From 4d6a3806d24b54f06ddc0cf234ac993db028cf29 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Sat, 12 Mar 2022 00:28:00 +0000 Subject: Decode string context straight to using `StorePath`s I gather decoding happens on demand, so I hope don't think this should have any perf implications one way or the other. --- src/libexpr/eval-cache.cc | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'src/libexpr/eval-cache.cc') diff --git a/src/libexpr/eval-cache.cc b/src/libexpr/eval-cache.cc index 7e5b5c9c4..54fa9b741 100644 --- a/src/libexpr/eval-cache.cc +++ b/src/libexpr/eval-cache.cc @@ -21,6 +21,8 @@ struct AttrDb { std::atomic_bool failed{false}; + const Store & cfg; + struct State { SQLite db; @@ -33,8 +35,9 @@ struct AttrDb std::unique_ptr> _state; - AttrDb(const Hash & fingerprint) - : _state(std::make_unique>()) + AttrDb(const Store & cfg, const Hash & fingerprint) + : cfg(cfg) + , _state(std::make_unique>()) { auto state(_state->lock()); @@ -257,7 +260,7 @@ struct AttrDb NixStringContext context; if (!queryAttribute.isNull(3)) for (auto & s : tokenizeString>(queryAttribute.getStr(3), ";")) - context.push_back(decodeContext(s)); + context.push_back(decodeContext(cfg, s)); return {{rowId, string_t{queryAttribute.getStr(2), context}}}; } case AttrType::Bool: @@ -274,10 +277,10 @@ struct AttrDb } }; -static std::shared_ptr makeAttrDb(const Hash & fingerprint) +static std::shared_ptr makeAttrDb(const Store & cfg, const Hash & fingerprint) { try { - return std::make_shared(fingerprint); + return std::make_shared(cfg, fingerprint); } catch (SQLiteError &) { ignoreException(); return nullptr; @@ -288,7 +291,7 @@ EvalCache::EvalCache( std::optional> useCache, EvalState & state, RootLoader rootLoader) - : db(useCache ? makeAttrDb(*useCache) : nullptr) + : db(useCache ? makeAttrDb(*state.store, *useCache) : nullptr) , state(state) , rootLoader(rootLoader) { @@ -546,7 +549,7 @@ string_t AttrCursor::getStringWithContext() if (auto s = std::get_if(&cachedValue->second)) { bool valid = true; for (auto & c : s->second) { - if (!root->state.store->isValidPath(root->state.store->parseStorePath(c.first))) { + if (!root->state.store->isValidPath(c.first)) { valid = false; break; } @@ -563,7 +566,7 @@ string_t AttrCursor::getStringWithContext() auto & v = forceValue(); if (v.type() == nString) - return {v.string.s, v.getContext()}; + return {v.string.s, v.getContext(*root->state.store)}; else if (v.type() == nPath) return {v.path, {}}; else -- cgit v1.2.3 From d89840b103e57e81e5245c3fe9edfbf7c3477ad5 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 14 Apr 2022 14:04:19 +0200 Subject: Make InstallableFlake::toValue() and toDerivation() behave consistently In particular, this means that 'nix eval` (which uses toValue()) no longer auto-calls functions or functors (because AttrCursor::findAlongAttrPath() doesn't). Fixes #6152. Also use ref<> in a few places, and don't return attrpaths from getCursor() because cursors already have a getAttrPath() method. --- src/libexpr/eval-cache.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/libexpr/eval-cache.cc') diff --git a/src/libexpr/eval-cache.cc b/src/libexpr/eval-cache.cc index 54fa9b741..7d3fd01a4 100644 --- a/src/libexpr/eval-cache.cc +++ b/src/libexpr/eval-cache.cc @@ -306,9 +306,9 @@ Value * EvalCache::getRootValue() return *value; } -std::shared_ptr EvalCache::getRoot() +ref EvalCache::getRoot() { - return std::make_shared(ref(shared_from_this()), std::nullopt); + return make_ref(ref(shared_from_this()), std::nullopt); } AttrCursor::AttrCursor( -- cgit v1.2.3 From 8775be33931ec3b1cad97035ff3d5370a97178a1 Mon Sep 17 00:00:00 2001 From: pennae Date: Sat, 5 Mar 2022 14:40:24 +0100 Subject: store Symbols in a table as well, like positions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit this slightly increases the amount of memory used for any given symbol, but this increase is more than made up for if the symbol is referenced more than once in the EvalState that holds it. on average every symbol should be referenced at least twice (once to introduce a binding, once to use it), so we expect no increase in memory on average. symbol tables are limited to 2³² entries like position tables, and similar arguments apply to why overflow is not likely: 2³² symbols would require as many string instances (at 24 bytes each) and map entries (at 24 bytes or more each, assuming that the map holds on average at most one item per bucket as the docs say). a full symbol table would require at least 192GB of memory just for symbols, which is well out of reach. (an ofborg eval of nixpks today creates less than a million symbols!) --- src/libexpr/eval-cache.cc | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) (limited to 'src/libexpr/eval-cache.cc') diff --git a/src/libexpr/eval-cache.cc b/src/libexpr/eval-cache.cc index 7d3fd01a4..0d2160efd 100644 --- a/src/libexpr/eval-cache.cc +++ b/src/libexpr/eval-cache.cc @@ -253,7 +253,7 @@ struct AttrDb std::vector attrs; auto queryAttributes(state->queryAttributes.use()(rowId)); while (queryAttributes.next()) - attrs.push_back(symbols.create(queryAttributes.getStr(0))); + attrs.emplace_back(queryAttributes.getStr(0)); return {{rowId, attrs}}; } case AttrType::String: { @@ -325,7 +325,7 @@ AttrCursor::AttrCursor( AttrKey AttrCursor::getKey() { if (!parent) - return {0, root->state.sEpsilon}; + return {0, {""}}; if (!parent->first->cachedValue) { parent->first->cachedValue = root->db->getAttr( parent->first->getKey(), root->state.symbols); @@ -340,7 +340,7 @@ Value & AttrCursor::getValue() if (parent) { auto & vParent = parent->first->getValue(); root->state.forceAttrs(vParent, noPos); - auto attr = vParent.attrs->get(parent->second); + auto attr = vParent.attrs->get(root->state.symbols.create(parent->second)); if (!attr) throw Error("attribute '%s' is unexpectedly missing", getAttrPathStr()); _value = allocRootValue(attr->value); @@ -419,7 +419,7 @@ Suggestions AttrCursor::getSuggestionsForAttr(Symbol name) return Suggestions::bestMatches(strAttrNames, name); } -std::shared_ptr AttrCursor::maybeGetAttr(Symbol name, bool forceErrors) +std::shared_ptr AttrCursor::maybeGetAttr(std::string_view name, bool forceErrors) { if (root->db) { if (!cachedValue) @@ -461,10 +461,10 @@ std::shared_ptr AttrCursor::maybeGetAttr(Symbol name, bool forceErro for (auto & attr : *v.attrs) { if (root->db) - root->db->setPlaceholder({cachedValue->first, attr.name}); + root->db->setPlaceholder({cachedValue->first, root->state.symbols[attr.name]}); } - auto attr = v.attrs->get(name); + auto attr = v.attrs->get(root->state.symbols.create(name)); if (!attr) { if (root->db) { @@ -486,12 +486,7 @@ std::shared_ptr AttrCursor::maybeGetAttr(Symbol name, bool forceErro root, std::make_pair(shared_from_this(), name), attr->value, std::move(cachedValue2)); } -std::shared_ptr AttrCursor::maybeGetAttr(std::string_view name) -{ - return maybeGetAttr(root->state.symbols.create(name)); -} - -ref AttrCursor::getAttr(Symbol name, bool forceErrors) +ref AttrCursor::getAttr(std::string_view name, bool forceErrors) { auto p = maybeGetAttr(name, forceErrors); if (!p) @@ -499,11 +494,6 @@ ref AttrCursor::getAttr(Symbol name, bool forceErrors) return ref(p); } -ref AttrCursor::getAttr(std::string_view name) -{ - return getAttr(root->state.symbols.create(name)); -} - OrSuggestions> AttrCursor::findAlongAttrPath(const std::vector & attrPath, bool force) { auto res = shared_from_this(); @@ -616,7 +606,7 @@ std::vector AttrCursor::getAttrs() std::vector attrs; for (auto & attr : *getValue().attrs) - attrs.push_back(attr.name); + attrs.push_back(root->state.symbols[attr.name]); std::sort(attrs.begin(), attrs.end(), [](const Symbol & a, const Symbol & b) { return (const std::string &) a < (const std::string &) b; }); @@ -635,7 +625,7 @@ bool AttrCursor::isDerivation() StorePath AttrCursor::forceDerivation() { - auto aDrvPath = getAttr(root->state.sDrvPath, true); + auto aDrvPath = getAttr("drvPath", true); auto drvPath = root->state.store->parseStorePath(aDrvPath->getString()); if (!root->state.store->isValidPath(drvPath) && !settings.readOnlyMode) { /* The eval cache contains 'drvPath', but the actual path has -- cgit v1.2.3 From a385e51a086006c0f7d7c4bc6ed910dbe5375c4d Mon Sep 17 00:00:00 2001 From: pennae Date: Fri, 22 Apr 2022 21:45:39 +0200 Subject: rename SymbolIdx -> Symbol, Symbol -> SymbolStr after #6218 `Symbol` no longer confers a uniqueness invariant on the string it wraps, it is now possible to create multiple symbols that compare equal but whose string contents have different addresses. this guarantee is now only provided by `SymbolIdx`, leaving `Symbol` only as a string wrapper that knows about the intricacies of how symbols need to be formatted for output. this change renames `SymbolIdx` to `Symbol` to restore the previous semantics of `Symbol` to that name. we also keep the wrapper type and rename it to `SymbolStr` instead of returning plain strings from lookups into the symbol table because symbols are formatted for output in many places. theoretically we do not need `SymbolStr`, only a function that formats a string for output as a symbol, but having to wrap every symbol that appears in a message into eg `formatSymbol()` is error-prone and inconvient. --- src/libexpr/eval-cache.cc | 46 ++++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 22 deletions(-) (limited to 'src/libexpr/eval-cache.cc') diff --git a/src/libexpr/eval-cache.cc b/src/libexpr/eval-cache.cc index 0d2160efd..00e80ae3b 100644 --- a/src/libexpr/eval-cache.cc +++ b/src/libexpr/eval-cache.cc @@ -92,6 +92,7 @@ struct AttrDb AttrId setAttrs( AttrKey key, + const SymbolTable & symbols, const std::vector & attrs) { return doSQLite([&]() @@ -110,7 +111,7 @@ struct AttrDb for (auto & attr : attrs) state->insertAttribute.use() (rowId) - (attr) + (symbols[attr]) (AttrType::Placeholder) (0, false).exec(); @@ -253,7 +254,7 @@ struct AttrDb std::vector attrs; auto queryAttributes(state->queryAttributes.use()(rowId)); while (queryAttributes.next()) - attrs.emplace_back(queryAttributes.getStr(0)); + attrs.emplace_back(symbols.create(queryAttributes.getStr(0))); return {{rowId, attrs}}; } case AttrType::String: { @@ -331,7 +332,7 @@ AttrKey AttrCursor::getKey() parent->first->getKey(), root->state.symbols); assert(parent->first->cachedValue); } - return {parent->first->cachedValue->first, parent->second}; + return {parent->first->cachedValue->first, root->state.symbols[parent->second]}; } Value & AttrCursor::getValue() @@ -340,7 +341,7 @@ Value & AttrCursor::getValue() if (parent) { auto & vParent = parent->first->getValue(); root->state.forceAttrs(vParent, noPos); - auto attr = vParent.attrs->get(root->state.symbols.create(parent->second)); + auto attr = vParent.attrs->get(parent->second); if (!attr) throw Error("attribute '%s' is unexpectedly missing", getAttrPathStr()); _value = allocRootValue(attr->value); @@ -369,12 +370,12 @@ std::vector AttrCursor::getAttrPath(Symbol name) const std::string AttrCursor::getAttrPathStr() const { - return concatStringsSep(".", getAttrPath()); + return concatStringsSep(".", root->state.symbols.resolve(getAttrPath())); } std::string AttrCursor::getAttrPathStr(Symbol name) const { - return concatStringsSep(".", getAttrPath(name)); + return concatStringsSep(".", root->state.symbols.resolve(getAttrPath(name))); } Value & AttrCursor::forceValue() @@ -414,9 +415,9 @@ Suggestions AttrCursor::getSuggestionsForAttr(Symbol name) auto attrNames = getAttrs(); std::set strAttrNames; for (auto & name : attrNames) - strAttrNames.insert(std::string(name)); + strAttrNames.insert(root->state.symbols[name]); - return Suggestions::bestMatches(strAttrNames, name); + return Suggestions::bestMatches(strAttrNames, root->state.symbols[name]); } std::shared_ptr AttrCursor::maybeGetAttr(std::string_view name, bool forceErrors) @@ -428,11 +429,11 @@ std::shared_ptr AttrCursor::maybeGetAttr(std::string_view name, bool if (cachedValue) { if (auto attrs = std::get_if>(&cachedValue->second)) { for (auto & attr : *attrs) - if (attr == name) - return std::make_shared(root, std::make_pair(shared_from_this(), name)); + if (root->state.symbols[attr] == name) + return std::make_shared(root, std::make_pair(shared_from_this(), attr)); return nullptr; } else if (std::get_if(&cachedValue->second)) { - auto attr = root->db->getAttr({cachedValue->first, name}, root->state.symbols); + auto attr = root->db->getAttr({cachedValue->first, std::string(name)}, root->state.symbols); if (attr) { if (std::get_if(&attr->second)) return nullptr; @@ -440,10 +441,10 @@ std::shared_ptr AttrCursor::maybeGetAttr(std::string_view name, bool if (forceErrors) debug("reevaluating failed cached attribute '%s'"); else - throw CachedEvalError("cached failure of attribute '%s'", getAttrPathStr(name)); + throw CachedEvalError("cached failure of attribute '%s'", getAttrPathStr(root->state.symbols.create(name))); } else return std::make_shared(root, - std::make_pair(shared_from_this(), name), nullptr, std::move(attr)); + std::make_pair(shared_from_this(), root->state.symbols.create(name)), nullptr, std::move(attr)); } // Incomplete attrset, so need to fall thru and // evaluate to see whether 'name' exists @@ -470,7 +471,7 @@ std::shared_ptr AttrCursor::maybeGetAttr(std::string_view name, bool if (root->db) { if (!cachedValue) cachedValue = {root->db->setPlaceholder(getKey()), placeholder_t()}; - root->db->setMissing({cachedValue->first, name}); + root->db->setMissing({cachedValue->first, std::string(name)}); } return nullptr; } @@ -479,18 +480,18 @@ std::shared_ptr AttrCursor::maybeGetAttr(std::string_view name, bool if (root->db) { if (!cachedValue) cachedValue = {root->db->setPlaceholder(getKey()), placeholder_t()}; - cachedValue2 = {root->db->setPlaceholder({cachedValue->first, name}), placeholder_t()}; + cachedValue2 = {root->db->setPlaceholder({cachedValue->first, std::string(name)}), placeholder_t()}; } return make_ref( - root, std::make_pair(shared_from_this(), name), attr->value, std::move(cachedValue2)); + root, std::make_pair(shared_from_this(), root->state.symbols.create(name)), attr->value, std::move(cachedValue2)); } ref AttrCursor::getAttr(std::string_view name, bool forceErrors) { auto p = maybeGetAttr(name, forceErrors); if (!p) - throw Error("attribute '%s' does not exist", getAttrPathStr(name)); + throw Error("attribute '%s' does not exist", getAttrPathStr(root->state.symbols.create(name))); return ref(p); } @@ -498,7 +499,7 @@ OrSuggestions> AttrCursor::findAlongAttrPath(const std::vectormaybeGetAttr(attr, force); + auto child = res->maybeGetAttr(root->state.symbols[attr], force); if (!child) { auto suggestions = res->getSuggestionsForAttr(attr); return OrSuggestions>::failed(suggestions); @@ -606,13 +607,14 @@ std::vector AttrCursor::getAttrs() std::vector attrs; for (auto & attr : *getValue().attrs) - attrs.push_back(root->state.symbols[attr.name]); - std::sort(attrs.begin(), attrs.end(), [](const Symbol & a, const Symbol & b) { - return (const std::string &) a < (const std::string &) b; + attrs.push_back(attr.name); + std::sort(attrs.begin(), attrs.end(), [&](Symbol a, Symbol b) { + std::string_view sa = root->state.symbols[a], sb = root->state.symbols[b]; + return sa < sb; }); if (root->db) - cachedValue = {root->db->setAttrs(getKey(), attrs), attrs}; + cachedValue = {root->db->setAttrs(getKey(), root->state.symbols, attrs), attrs}; return attrs; } -- cgit v1.2.3 From 474695975dde60f582ca0b2fb72c17f664e22876 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 26 Apr 2022 14:01:21 +0200 Subject: EvalCache: Revert to using symbols in getAttr() --- src/libexpr/eval-cache.cc | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) (limited to 'src/libexpr/eval-cache.cc') diff --git a/src/libexpr/eval-cache.cc b/src/libexpr/eval-cache.cc index 00e80ae3b..e90c9bff5 100644 --- a/src/libexpr/eval-cache.cc +++ b/src/libexpr/eval-cache.cc @@ -420,8 +420,10 @@ Suggestions AttrCursor::getSuggestionsForAttr(Symbol name) return Suggestions::bestMatches(strAttrNames, root->state.symbols[name]); } -std::shared_ptr AttrCursor::maybeGetAttr(std::string_view name, bool forceErrors) +std::shared_ptr AttrCursor::maybeGetAttr(Symbol name, bool forceErrors) { + auto nameS = root->state.symbols[name]; + if (root->db) { if (!cachedValue) cachedValue = root->db->getAttr(getKey(), root->state.symbols); @@ -429,11 +431,11 @@ std::shared_ptr AttrCursor::maybeGetAttr(std::string_view name, bool if (cachedValue) { if (auto attrs = std::get_if>(&cachedValue->second)) { for (auto & attr : *attrs) - if (root->state.symbols[attr] == name) + if (attr == name) return std::make_shared(root, std::make_pair(shared_from_this(), attr)); return nullptr; } else if (std::get_if(&cachedValue->second)) { - auto attr = root->db->getAttr({cachedValue->first, std::string(name)}, root->state.symbols); + auto attr = root->db->getAttr({cachedValue->first, nameS}, root->state.symbols); if (attr) { if (std::get_if(&attr->second)) return nullptr; @@ -441,10 +443,10 @@ std::shared_ptr AttrCursor::maybeGetAttr(std::string_view name, bool if (forceErrors) debug("reevaluating failed cached attribute '%s'"); else - throw CachedEvalError("cached failure of attribute '%s'", getAttrPathStr(root->state.symbols.create(name))); + throw CachedEvalError("cached failure of attribute '%s'", getAttrPathStr(name)); } else return std::make_shared(root, - std::make_pair(shared_from_this(), root->state.symbols.create(name)), nullptr, std::move(attr)); + std::make_pair(shared_from_this(), name), nullptr, std::move(attr)); } // Incomplete attrset, so need to fall thru and // evaluate to see whether 'name' exists @@ -465,13 +467,13 @@ std::shared_ptr AttrCursor::maybeGetAttr(std::string_view name, bool root->db->setPlaceholder({cachedValue->first, root->state.symbols[attr.name]}); } - auto attr = v.attrs->get(root->state.symbols.create(name)); + auto attr = v.attrs->get(name); if (!attr) { if (root->db) { if (!cachedValue) cachedValue = {root->db->setPlaceholder(getKey()), placeholder_t()}; - root->db->setMissing({cachedValue->first, std::string(name)}); + root->db->setMissing({cachedValue->first, nameS}); } return nullptr; } @@ -480,26 +482,36 @@ std::shared_ptr AttrCursor::maybeGetAttr(std::string_view name, bool if (root->db) { if (!cachedValue) cachedValue = {root->db->setPlaceholder(getKey()), placeholder_t()}; - cachedValue2 = {root->db->setPlaceholder({cachedValue->first, std::string(name)}), placeholder_t()}; + cachedValue2 = {root->db->setPlaceholder({cachedValue->first, nameS}), placeholder_t()}; } return make_ref( - root, std::make_pair(shared_from_this(), root->state.symbols.create(name)), attr->value, std::move(cachedValue2)); + root, std::make_pair(shared_from_this(), name), attr->value, std::move(cachedValue2)); +} + +std::shared_ptr AttrCursor::maybeGetAttr(std::string_view name) +{ + return maybeGetAttr(root->state.symbols.create(name)); } -ref AttrCursor::getAttr(std::string_view name, bool forceErrors) +ref AttrCursor::getAttr(Symbol name, bool forceErrors) { auto p = maybeGetAttr(name, forceErrors); if (!p) - throw Error("attribute '%s' does not exist", getAttrPathStr(root->state.symbols.create(name))); + throw Error("attribute '%s' does not exist", getAttrPathStr(name)); return ref(p); } +ref AttrCursor::getAttr(std::string_view name) +{ + return getAttr(root->state.symbols.create(name)); +} + OrSuggestions> AttrCursor::findAlongAttrPath(const std::vector & attrPath, bool force) { auto res = shared_from_this(); for (auto & attr : attrPath) { - auto child = res->maybeGetAttr(root->state.symbols[attr], force); + auto child = res->maybeGetAttr(attr, force); if (!child) { auto suggestions = res->getSuggestionsForAttr(attr); return OrSuggestions>::failed(suggestions); @@ -627,7 +639,7 @@ bool AttrCursor::isDerivation() StorePath AttrCursor::forceDerivation() { - auto aDrvPath = getAttr("drvPath", true); + auto aDrvPath = getAttr(root->state.sDrvPath, true); auto drvPath = root->state.store->parseStorePath(aDrvPath->getString()); if (!root->state.store->isValidPath(drvPath) && !settings.readOnlyMode) { /* The eval cache contains 'drvPath', but the actual path has -- cgit v1.2.3 From b12c33510cb09f7d8300d7f3c762a84b8688780f Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 26 Apr 2022 14:16:20 +0200 Subject: EvalCache AttrKey: Use Symbol instead of std::string --- src/libexpr/eval-cache.cc | 69 ++++++++++++++++++++++++----------------------- 1 file changed, 36 insertions(+), 33 deletions(-) (limited to 'src/libexpr/eval-cache.cc') diff --git a/src/libexpr/eval-cache.cc b/src/libexpr/eval-cache.cc index e90c9bff5..6fb4bf266 100644 --- a/src/libexpr/eval-cache.cc +++ b/src/libexpr/eval-cache.cc @@ -35,9 +35,15 @@ struct AttrDb std::unique_ptr> _state; - AttrDb(const Store & cfg, const Hash & fingerprint) + SymbolTable & symbols; + + AttrDb( + const Store & cfg, + const Hash & fingerprint, + SymbolTable & symbols) : cfg(cfg) , _state(std::make_unique>()) + , symbols(symbols) { auto state(_state->lock()); @@ -92,7 +98,6 @@ struct AttrDb AttrId setAttrs( AttrKey key, - const SymbolTable & symbols, const std::vector & attrs) { return doSQLite([&]() @@ -101,7 +106,7 @@ struct AttrDb state->insertAttribute.use() (key.first) - (key.second) + (symbols[key.second]) (AttrType::FullAttrs) (0, false).exec(); @@ -136,14 +141,14 @@ struct AttrDb } state->insertAttributeWithContext.use() (key.first) - (key.second) + (symbols[key.second]) (AttrType::String) (s) (ctx).exec(); } else { state->insertAttribute.use() (key.first) - (key.second) + (symbols[key.second]) (AttrType::String) (s).exec(); } @@ -162,7 +167,7 @@ struct AttrDb state->insertAttribute.use() (key.first) - (key.second) + (symbols[key.second]) (AttrType::Bool) (b ? 1 : 0).exec(); @@ -178,7 +183,7 @@ struct AttrDb state->insertAttribute.use() (key.first) - (key.second) + (symbols[key.second]) (AttrType::Placeholder) (0, false).exec(); @@ -194,7 +199,7 @@ struct AttrDb state->insertAttribute.use() (key.first) - (key.second) + (symbols[key.second]) (AttrType::Missing) (0, false).exec(); @@ -210,7 +215,7 @@ struct AttrDb state->insertAttribute.use() (key.first) - (key.second) + (symbols[key.second]) (AttrType::Misc) (0, false).exec(); @@ -226,7 +231,7 @@ struct AttrDb state->insertAttribute.use() (key.first) - (key.second) + (symbols[key.second]) (AttrType::Failed) (0, false).exec(); @@ -234,13 +239,11 @@ struct AttrDb }); } - std::optional> getAttr( - AttrKey key, - SymbolTable & symbols) + std::optional> getAttr(AttrKey key) { auto state(_state->lock()); - auto queryAttribute(state->queryAttribute.use()(key.first)(key.second)); + auto queryAttribute(state->queryAttribute.use()(key.first)(symbols[key.second])); if (!queryAttribute.next()) return {}; auto rowId = (AttrType) queryAttribute.getInt(0); @@ -278,10 +281,13 @@ struct AttrDb } }; -static std::shared_ptr makeAttrDb(const Store & cfg, const Hash & fingerprint) +static std::shared_ptr makeAttrDb( + const Store & cfg, + const Hash & fingerprint, + SymbolTable & symbols) { try { - return std::make_shared(cfg, fingerprint); + return std::make_shared(cfg, fingerprint, symbols); } catch (SQLiteError &) { ignoreException(); return nullptr; @@ -292,7 +298,7 @@ EvalCache::EvalCache( std::optional> useCache, EvalState & state, RootLoader rootLoader) - : db(useCache ? makeAttrDb(*state.store, *useCache) : nullptr) + : db(useCache ? makeAttrDb(*state.store, *useCache, state.symbols) : nullptr) , state(state) , rootLoader(rootLoader) { @@ -326,13 +332,12 @@ AttrCursor::AttrCursor( AttrKey AttrCursor::getKey() { if (!parent) - return {0, {""}}; + return {0, root->state.sEpsilon}; if (!parent->first->cachedValue) { - parent->first->cachedValue = root->db->getAttr( - parent->first->getKey(), root->state.symbols); + parent->first->cachedValue = root->db->getAttr(parent->first->getKey()); assert(parent->first->cachedValue); } - return {parent->first->cachedValue->first, root->state.symbols[parent->second]}; + return {parent->first->cachedValue->first, parent->second}; } Value & AttrCursor::getValue() @@ -422,11 +427,9 @@ Suggestions AttrCursor::getSuggestionsForAttr(Symbol name) std::shared_ptr AttrCursor::maybeGetAttr(Symbol name, bool forceErrors) { - auto nameS = root->state.symbols[name]; - if (root->db) { if (!cachedValue) - cachedValue = root->db->getAttr(getKey(), root->state.symbols); + cachedValue = root->db->getAttr(getKey()); if (cachedValue) { if (auto attrs = std::get_if>(&cachedValue->second)) { @@ -435,7 +438,7 @@ std::shared_ptr AttrCursor::maybeGetAttr(Symbol name, bool forceErro return std::make_shared(root, std::make_pair(shared_from_this(), attr)); return nullptr; } else if (std::get_if(&cachedValue->second)) { - auto attr = root->db->getAttr({cachedValue->first, nameS}, root->state.symbols); + auto attr = root->db->getAttr({cachedValue->first, name}); if (attr) { if (std::get_if(&attr->second)) return nullptr; @@ -464,7 +467,7 @@ std::shared_ptr AttrCursor::maybeGetAttr(Symbol name, bool forceErro for (auto & attr : *v.attrs) { if (root->db) - root->db->setPlaceholder({cachedValue->first, root->state.symbols[attr.name]}); + root->db->setPlaceholder({cachedValue->first, attr.name}); } auto attr = v.attrs->get(name); @@ -473,7 +476,7 @@ std::shared_ptr AttrCursor::maybeGetAttr(Symbol name, bool forceErro if (root->db) { if (!cachedValue) cachedValue = {root->db->setPlaceholder(getKey()), placeholder_t()}; - root->db->setMissing({cachedValue->first, nameS}); + root->db->setMissing({cachedValue->first, name}); } return nullptr; } @@ -482,7 +485,7 @@ std::shared_ptr AttrCursor::maybeGetAttr(Symbol name, bool forceErro if (root->db) { if (!cachedValue) cachedValue = {root->db->setPlaceholder(getKey()), placeholder_t()}; - cachedValue2 = {root->db->setPlaceholder({cachedValue->first, nameS}), placeholder_t()}; + cachedValue2 = {root->db->setPlaceholder({cachedValue->first, name}), placeholder_t()}; } return make_ref( @@ -525,7 +528,7 @@ std::string AttrCursor::getString() { if (root->db) { if (!cachedValue) - cachedValue = root->db->getAttr(getKey(), root->state.symbols); + cachedValue = root->db->getAttr(getKey()); if (cachedValue && !std::get_if(&cachedValue->second)) { if (auto s = std::get_if(&cachedValue->second)) { debug("using cached string attribute '%s'", getAttrPathStr()); @@ -547,7 +550,7 @@ string_t AttrCursor::getStringWithContext() { if (root->db) { if (!cachedValue) - cachedValue = root->db->getAttr(getKey(), root->state.symbols); + cachedValue = root->db->getAttr(getKey()); if (cachedValue && !std::get_if(&cachedValue->second)) { if (auto s = std::get_if(&cachedValue->second)) { bool valid = true; @@ -580,7 +583,7 @@ bool AttrCursor::getBool() { if (root->db) { if (!cachedValue) - cachedValue = root->db->getAttr(getKey(), root->state.symbols); + cachedValue = root->db->getAttr(getKey()); if (cachedValue && !std::get_if(&cachedValue->second)) { if (auto b = std::get_if(&cachedValue->second)) { debug("using cached Boolean attribute '%s'", getAttrPathStr()); @@ -602,7 +605,7 @@ std::vector AttrCursor::getAttrs() { if (root->db) { if (!cachedValue) - cachedValue = root->db->getAttr(getKey(), root->state.symbols); + cachedValue = root->db->getAttr(getKey()); if (cachedValue && !std::get_if(&cachedValue->second)) { if (auto attrs = std::get_if>(&cachedValue->second)) { debug("using cached attrset attribute '%s'", getAttrPathStr()); @@ -626,7 +629,7 @@ std::vector AttrCursor::getAttrs() }); if (root->db) - cachedValue = {root->db->setAttrs(getKey(), root->state.symbols, attrs), attrs}; + cachedValue = {root->db->setAttrs(getKey(), attrs), attrs}; return attrs; } -- cgit v1.2.3