Nix 2.26.3
Nix, the purely functional package manager; unstable internal interfaces
 
Loading...
Searching...
No Matches
symbol-table.hh
Go to the documentation of this file.
1#pragma once
3
4#include <list>
5#include <map>
6#include <unordered_map>
7
8#include "types.hh"
9#include "chunked-vector.hh"
10#include "error.hh"
11
12namespace nix {
13
19class SymbolStr
20{
21 friend class SymbolTable;
22
23private:
24 const std::string * s;
25
26 explicit SymbolStr(const std::string & symbol): s(&symbol) {}
27
28public:
29 bool operator == (std::string_view s2) const
30 {
31 return *s == s2;
32 }
33
34 const char * c_str() const
35 {
36 return s->c_str();
37 }
38
39 operator const std::string_view () const
40 {
41 return *s;
42 }
43
44 friend std::ostream & operator <<(std::ostream & os, const SymbolStr & symbol);
45
46 bool empty() const
47 {
48 return s->empty();
49 }
50};
51
57class Symbol
58{
59 friend class SymbolTable;
60
61private:
62 uint32_t id;
63
64 explicit Symbol(uint32_t id): id(id) {}
65
66public:
67 Symbol() : id(0) {}
68
69 explicit operator bool() const { return id > 0; }
70
71 auto operator<=>(const Symbol other) const { return id <=> other.id; }
72 bool operator==(const Symbol other) const { return id == other.id; }
73
74 friend class std::hash<Symbol>;
75};
76
82{
83private:
84 std::unordered_map<std::string_view, std::pair<const std::string *, uint32_t>> symbols;
86
87public:
88
92 Symbol create(std::string_view s)
93 {
94 // Most symbols are looked up more than once, so we trade off insertion performance
95 // for lookup performance.
96 // TODO: could probably be done more efficiently with transparent Hash and Equals
97 // on the original implementation using unordered_set
98 // FIXME: make this thread-safe.
99 auto it = symbols.find(s);
100 if (it != symbols.end()) return Symbol(it->second.second + 1);
101
102 const auto & [rawSym, idx] = store.add(std::string(s));
103 symbols.emplace(rawSym, std::make_pair(&rawSym, idx));
104 return Symbol(idx + 1);
105 }
106
107 std::vector<SymbolStr> resolve(const std::vector<Symbol> & symbols) const
108 {
109 std::vector<SymbolStr> result;
110 result.reserve(symbols.size());
111 for (auto sym : symbols)
112 result.push_back((*this)[sym]);
113 return result;
114 }
115
116 SymbolStr operator[](Symbol s) const
117 {
118 if (s.id == 0 || s.id > store.size())
119 unreachable();
120 return SymbolStr(store[s.id - 1]);
121 }
122
123 size_t size() const
124 {
125 return store.size();
126 }
127
128 size_t totalSize() const;
129
130 template<typename T>
131 void dump(T callback) const
132 {
133 store.forEach(callback);
134 }
135};
136
137}
138
139template<>
140struct std::hash<nix::Symbol>
141{
142 std::size_t operator()(const nix::Symbol & s) const noexcept
143 {
144 return std::hash<decltype(s.id)>{}(s.id);
145 }
146};
Definition chunked-vector.hh:23
friend class SymbolTable
Definition symbol-table.hh:21
Definition symbol-table.hh:82
Symbol create(std::string_view s)
Definition symbol-table.hh:92
Definition symbol-table.hh:58
friend class SymbolTable
Definition symbol-table.hh:59
This file defines two main structs/classes used in nix error handling.
ChunkedVector< std::string, 8192 > store
Definition lexer.l:1011
return s
Definition lexer.l:459
Symbol symbol
Definition lexer.l:5834
std::unordered_map< std::string_view, std::pair< const std::string *, uint32_t > > symbols
Definition lexer.l:1010