/* * Souffle - A Datalog Compiler * Copyright (c) 2022, The Souffle Developers. All rights reserved * Licensed under the Universal Permissive License v 1.0 as shown at: * - https://opensource.org/licenses/UPL * - /licenses/SOUFFLE-UPL.txt */ /** * @file SymbolTableImpl.h * * SymbolTable definition */ #pragma once #include "souffle/SymbolTable.h" #include "souffle/datastructure/ConcurrentFlyweight.h" #include "souffle/utility/MiscUtil.h" #include "souffle/utility/ParallelUtil.h" #include "souffle/utility/StreamUtil.h" #include #include #include #include #include #include #include #include #include #include namespace souffle { /** * @class SymbolTableImpl * * Implementation of the symbol table. */ class SymbolTableImpl : public SymbolTable, protected FlyweightImpl { private: using Base = FlyweightImpl; public: class IteratorImpl : public SymbolTableIteratorInterface, private Base::iterator { public: IteratorImpl(Base::iterator&& it) : Base::iterator(it) {} IteratorImpl(const Base::iterator& it) : Base::iterator(it) {} const std::pair& get() const { return **this; } bool equals(const SymbolTableIteratorInterface& other) { return (*this) == static_cast(other); } SymbolTableIteratorInterface& incr() { ++(*this); return *this; } std::unique_ptr copy() const { return std::make_unique(*this); } }; using iterator = SymbolTable::Iterator; /** @brief Construct a symbol table with the given number of concurrent access lanes. */ SymbolTableImpl(const std::size_t LaneCount = 1) : Base(LaneCount) {} /** @brief Construct a symbol table with the given initial symbols. */ SymbolTableImpl(std::initializer_list symbols) : Base(1, symbols.size()) { for (const auto& symbol : symbols) { findOrInsert(symbol); } } /** @brief Construct a symbol table with the given number of concurrent access lanes and initial symbols. */ SymbolTableImpl(const std::size_t LaneCount, std::initializer_list symbols) : Base(LaneCount, symbols.size()) { for (const auto& symbol : symbols) { findOrInsert(symbol); } } /** * @brief Set the number of concurrent access lanes. * This function is not thread-safe, do not call when other threads are using the datastructure. */ void setNumLanes(const std::size_t NumLanes) { Base::setNumLanes(NumLanes); } iterator begin() const override { return SymbolTable::Iterator(std::make_unique(Base::begin())); } iterator end() const override { return SymbolTable::Iterator(std::make_unique(Base::end())); } bool weakContains(const std::string& symbol) const override { return Base::weakContains(symbol); } RamDomain encode(const std::string& symbol) override { return Base::findOrInsert(symbol).first; } const std::string& decode(const RamDomain index) const override { return Base::fetch(index); } RamDomain unsafeEncode(const std::string& symbol) override { return encode(symbol); } const std::string& unsafeDecode(const RamDomain index) const override { return decode(index); } std::pair findOrInsert(const std::string& symbol) override { auto Res = Base::findOrInsert(symbol); return std::make_pair(static_cast(Res.first), Res.second); } }; } // namespace souffle