OILS / vendor / souffle / datastructure / SymbolTableImpl.h View on Github | oilshell.org

133 lines, 64 significant
1/*
2 * Souffle - A Datalog Compiler
3 * Copyright (c) 2022, The Souffle Developers. All rights reserved
4 * Licensed under the Universal Permissive License v 1.0 as shown at:
5 * - https://opensource.org/licenses/UPL
6 * - <souffle root>/licenses/SOUFFLE-UPL.txt
7 */
8
9/**
10 * @file SymbolTableImpl.h
11 *
12 * SymbolTable definition
13 */
14
15#pragma once
16
17#include "souffle/SymbolTable.h"
18#include "souffle/datastructure/ConcurrentFlyweight.h"
19#include "souffle/utility/MiscUtil.h"
20#include "souffle/utility/ParallelUtil.h"
21#include "souffle/utility/StreamUtil.h"
22
23#include <algorithm>
24#include <cstdlib>
25#include <deque>
26#include <initializer_list>
27#include <iostream>
28#include <memory>
29#include <string>
30#include <unordered_map>
31#include <utility>
32#include <vector>
33
34namespace souffle {
35
36/**
37 * @class SymbolTableImpl
38 *
39 * Implementation of the symbol table.
40 */
41class SymbolTableImpl : public SymbolTable, protected FlyweightImpl<std::string> {
42private:
43 using Base = FlyweightImpl<std::string>;
44
45public:
46 class IteratorImpl : public SymbolTableIteratorInterface, private Base::iterator {
47 public:
48 IteratorImpl(Base::iterator&& it) : Base::iterator(it) {}
49
50 IteratorImpl(const Base::iterator& it) : Base::iterator(it) {}
51
52 const std::pair<const std::string, const std::size_t>& get() const {
53 return **this;
54 }
55
56 bool equals(const SymbolTableIteratorInterface& other) {
57 return (*this) == static_cast<const IteratorImpl&>(other);
58 }
59
60 SymbolTableIteratorInterface& incr() {
61 ++(*this);
62 return *this;
63 }
64
65 std::unique_ptr<SymbolTableIteratorInterface> copy() const {
66 return std::make_unique<IteratorImpl>(*this);
67 }
68 };
69
70 using iterator = SymbolTable::Iterator;
71
72 /** @brief Construct a symbol table with the given number of concurrent access lanes. */
73 SymbolTableImpl(const std::size_t LaneCount = 1) : Base(LaneCount) {}
74
75 /** @brief Construct a symbol table with the given initial symbols. */
76 SymbolTableImpl(std::initializer_list<std::string> symbols) : Base(1, symbols.size()) {
77 for (const auto& symbol : symbols) {
78 findOrInsert(symbol);
79 }
80 }
81
82 /** @brief Construct a symbol table with the given number of concurrent access lanes and initial symbols.
83 */
84 SymbolTableImpl(const std::size_t LaneCount, std::initializer_list<std::string> symbols)
85 : Base(LaneCount, symbols.size()) {
86 for (const auto& symbol : symbols) {
87 findOrInsert(symbol);
88 }
89 }
90
91 /**
92 * @brief Set the number of concurrent access lanes.
93 * This function is not thread-safe, do not call when other threads are using the datastructure.
94 */
95 void setNumLanes(const std::size_t NumLanes) {
96 Base::setNumLanes(NumLanes);
97 }
98
99 iterator begin() const override {
100 return SymbolTable::Iterator(std::make_unique<IteratorImpl>(Base::begin()));
101 }
102
103 iterator end() const override {
104 return SymbolTable::Iterator(std::make_unique<IteratorImpl>(Base::end()));
105 }
106
107 bool weakContains(const std::string& symbol) const override {
108 return Base::weakContains(symbol);
109 }
110
111 RamDomain encode(const std::string& symbol) override {
112 return Base::findOrInsert(symbol).first;
113 }
114
115 const std::string& decode(const RamDomain index) const override {
116 return Base::fetch(index);
117 }
118
119 RamDomain unsafeEncode(const std::string& symbol) override {
120 return encode(symbol);
121 }
122
123 const std::string& unsafeDecode(const RamDomain index) const override {
124 return decode(index);
125 }
126
127 std::pair<RamDomain, bool> findOrInsert(const std::string& symbol) override {
128 auto Res = Base::findOrInsert(symbol);
129 return std::make_pair(static_cast<RamDomain>(Res.first), Res.second);
130 }
131};
132
133} // namespace souffle