libexpr/symbol-table: introduce InternedSymbol
The backing storage for symbols becomes a class storing a Value and a string. The Value is itself a string which contents points to the owned string. Recovering a `SymbolStr` is still possible. Change-Id: I171151abc3c0a513f2150c4b54edd61dea256cce Signed-off-by: Raito Bezarius <raito@lix.systems>
This commit is contained in:
@@ -19,6 +19,12 @@ std::ostream & operator <<(std::ostream & str, const SymbolStr & symbol)
|
||||
return printIdentifier(str, s);
|
||||
}
|
||||
|
||||
std::ostream & operator<<(std::ostream & str, const InternedSymbol & symbol)
|
||||
{
|
||||
str << SymbolStr(symbol);
|
||||
return str;
|
||||
}
|
||||
|
||||
AttrName::AttrName(PosIdx pos, Symbol s) : pos(pos), symbol(s)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -810,7 +810,7 @@ drvName, Bindings * attrs, Value & v)
|
||||
|
||||
for (auto & i : attrs->lexicographicOrder(state.ctx.symbols)) {
|
||||
if (i->name == state.ctx.s.ignoreNulls) continue;
|
||||
const std::string & key = state.ctx.symbols[i->name];
|
||||
auto & key = state.ctx.symbols[i->name];
|
||||
vomit("processing attribute '%1%'", key);
|
||||
|
||||
auto handleHashMode = [&](const std::string_view s, NeverAsync = {}) {
|
||||
@@ -1539,7 +1539,7 @@ static void prim_path(EvalState & state, Value * * args, Value & v)
|
||||
state.forceAttrs(*args[0], noPos, "while evaluating the argument passed to 'builtins.path'");
|
||||
|
||||
for (auto & attr : *args[0]->attrs) {
|
||||
auto n = state.ctx.symbols[attr.name];
|
||||
auto & n = state.ctx.symbols[attr.name];
|
||||
if (n == "path")
|
||||
path.emplace(state.coerceToPath(attr.pos, *attr.value, context, "while evaluating the 'path' attribute passed to 'builtins.path'"));
|
||||
else if (attr.name == state.ctx.s.name)
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
#include "lix/libutil/types.hh"
|
||||
#include "lix/libutil/chunked-vector.hh"
|
||||
|
||||
#include "lix/libexpr/value.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
/**
|
||||
@@ -16,6 +18,7 @@ namespace nix {
|
||||
class SymbolStr
|
||||
{
|
||||
friend class SymbolTable;
|
||||
friend class InternedSymbol;
|
||||
|
||||
private:
|
||||
const std::string * s;
|
||||
@@ -41,6 +44,59 @@ public:
|
||||
friend std::ostream & operator <<(std::ostream & os, const SymbolStr & symbol);
|
||||
};
|
||||
|
||||
class InternedSymbol
|
||||
{
|
||||
private:
|
||||
/*
|
||||
* The type that actually stores the string contained inside of the Value.
|
||||
*/
|
||||
std::string contents;
|
||||
|
||||
/*
|
||||
* A value containing a string that can be immediately passed to the evaluator.
|
||||
*/
|
||||
Value underlyingValue;
|
||||
|
||||
public:
|
||||
explicit InternedSymbol(std::string_view s)
|
||||
: contents(s)
|
||||
, underlyingValue(NewValueAs::string, contents.c_str(), nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
InternedSymbol(InternedSymbol &&) = default;
|
||||
InternedSymbol & operator=(InternedSymbol &&) = default;
|
||||
|
||||
KJ_DISALLOW_COPY(InternedSymbol);
|
||||
|
||||
operator SymbolStr() const
|
||||
{
|
||||
return SymbolStr(contents);
|
||||
}
|
||||
|
||||
bool operator==(std::string_view s2) const
|
||||
{
|
||||
return contents == s2;
|
||||
}
|
||||
|
||||
operator const std::string &() const
|
||||
{
|
||||
return contents;
|
||||
}
|
||||
|
||||
operator std::string_view() const
|
||||
{
|
||||
return contents;
|
||||
}
|
||||
|
||||
const Value * toValuePtr() const
|
||||
{
|
||||
return &underlyingValue;
|
||||
}
|
||||
|
||||
friend std::ostream & operator<<(std::ostream & os, const InternedSymbol & symbol);
|
||||
};
|
||||
|
||||
/**
|
||||
* Symbols have the property that they can be compared efficiently
|
||||
* (using an equality test), because the symbol table stores only one
|
||||
@@ -77,7 +133,7 @@ private:
|
||||
* ChunkedVector references are never invalidated.
|
||||
*/
|
||||
std::unordered_map<std::string_view, uint32_t> symbols;
|
||||
ChunkedVector<std::string, 8192> store{16};
|
||||
ChunkedVector<InternedSymbol, 8192> store{16};
|
||||
|
||||
public:
|
||||
|
||||
@@ -101,11 +157,11 @@ public:
|
||||
return Symbol(idx + 1);
|
||||
}
|
||||
|
||||
SymbolStr operator[](Symbol s) const
|
||||
const InternedSymbol & operator[](Symbol s) const
|
||||
{
|
||||
if (s.id == 0 || s.id > store.size())
|
||||
abort();
|
||||
return SymbolStr(store[s.id - 1]);
|
||||
return store[s.id - 1];
|
||||
}
|
||||
|
||||
size_t size() const
|
||||
|
||||
Reference in New Issue
Block a user