1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-25 14:51:16 +02:00

libexpr: Remove unused field from SymbolTable::symbols and emplace into the ChunkedVector

Remove outdated and no longer relevant TODO. It's more confusing
now, since symbol table must now be addressed by uint32_t indices
in order to keep Attr size down to 16 bytes on 64 bit machines.
This commit is contained in:
Sergei Zimmerman 2025-05-02 20:42:47 +00:00
parent a976a46ee8
commit 161c5dbf39
No known key found for this signature in database
GPG key ID: A9B0B557CA632325
2 changed files with 20 additions and 11 deletions

View file

@ -81,26 +81,29 @@ public:
class SymbolTable class SymbolTable
{ {
private: private:
std::unordered_map<std::string_view, std::pair<const std::string *, uint32_t>> symbols; /**
* Map from string view (backed by ChunkedVector) -> offset into the store.
* ChunkedVector references are never invalidated.
*/
std::unordered_map<std::string_view, uint32_t> symbols;
ChunkedVector<std::string, 8192> store{16}; ChunkedVector<std::string, 8192> store{16};
public: public:
/** /**
* converts a string into a symbol. * Converts a string into a symbol.
*/ */
Symbol create(std::string_view s) Symbol create(std::string_view s)
{ {
// Most symbols are looked up more than once, so we trade off insertion performance // Most symbols are looked up more than once, so we trade off insertion performance
// for lookup performance. // for lookup performance.
// TODO: could probably be done more efficiently with transparent Hash and Equals
// on the original implementation using unordered_set
// FIXME: make this thread-safe. // FIXME: make this thread-safe.
auto it = symbols.find(s); auto it = symbols.find(s);
if (it != symbols.end()) return Symbol(it->second.second + 1); if (it != symbols.end())
return Symbol(it->second + 1);
const auto & [rawSym, idx] = store.add(std::string(s)); const auto & [rawSym, idx] = store.add(s);
symbols.emplace(rawSym, std::make_pair(&rawSym, idx)); symbols.emplace(rawSym, idx);
return Symbol(idx + 1); return Symbol(idx + 1);
} }

View file

@ -45,9 +45,10 @@ public:
addChunk(); addChunk();
} }
uint32_t size() const { return size_; } uint32_t size() const noexcept { return size_; }
std::pair<T &, uint32_t> add(T value) template <typename... Args>
std::pair<T &, uint32_t> add(Args &&... args)
{ {
const auto idx = size_++; const auto idx = size_++;
auto & chunk = [&] () -> auto & { auto & chunk = [&] () -> auto & {
@ -55,11 +56,16 @@ public:
return back; return back;
return addChunk(); return addChunk();
}(); }();
auto & result = chunk.emplace_back(std::move(value)); auto & result = chunk.emplace_back(std::forward<Args>(args)...);
return {result, idx}; return {result, idx};
} }
const T & operator[](uint32_t idx) const /**
* Unchecked subscript operator.
* @pre add must have been called at least idx + 1 times.
* @throws nothing
*/
const T & operator[](uint32_t idx) const noexcept
{ {
return chunks[idx / ChunkSize][idx % ChunkSize]; return chunks[idx / ChunkSize][idx % ChunkSize];
} }