| 1 | /*
|
| 2 | * Souffle - A Datalog Compiler
|
| 3 | * Copyright (c) 2020, 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 | *
|
| 11 | * @file SerialisationStream.h
|
| 12 | *
|
| 13 | * Defines a common base class for relation serialisation streams.
|
| 14 | *
|
| 15 | ***********************************************************************/
|
| 16 |
|
| 17 | #pragma once
|
| 18 |
|
| 19 | #include "souffle/RamTypes.h"
|
| 20 | #include "souffle/utility/ContainerUtil.h"
|
| 21 | #include "souffle/utility/StringUtil.h"
|
| 22 | #include "souffle/utility/json11.h"
|
| 23 | #include <cassert>
|
| 24 | #include <cstddef>
|
| 25 | #include <map>
|
| 26 | #include <string>
|
| 27 | #include <utility>
|
| 28 | #include <vector>
|
| 29 |
|
| 30 | namespace souffle {
|
| 31 |
|
| 32 | class RecordTable;
|
| 33 | class SymbolTable;
|
| 34 |
|
| 35 | using json11::Json;
|
| 36 |
|
| 37 | template <bool readOnlyTables>
|
| 38 | class SerialisationStream {
|
| 39 | public:
|
| 40 | virtual ~SerialisationStream() = default;
|
| 41 |
|
| 42 | protected:
|
| 43 | template <typename A>
|
| 44 | using RO = std::conditional_t<readOnlyTables, const A, A>;
|
| 45 |
|
| 46 | SerialisationStream(RO<SymbolTable>& symTab, RO<RecordTable>& recTab, Json types,
|
| 47 | std::vector<std::string> relTypes, std::size_t auxArity = 0)
|
| 48 | : symbolTable(symTab), recordTable(recTab), types(std::move(types)),
|
| 49 | typeAttributes(std::move(relTypes)), arity(typeAttributes.size() - auxArity),
|
| 50 | auxiliaryArity(auxArity) {}
|
| 51 |
|
| 52 | SerialisationStream(RO<SymbolTable>& symTab, RO<RecordTable>& recTab, Json types)
|
| 53 | : symbolTable(symTab), recordTable(recTab), types(std::move(types)) {
|
| 54 | setupFromJson();
|
| 55 | }
|
| 56 |
|
| 57 | SerialisationStream(RO<SymbolTable>& symTab, RO<RecordTable>& recTab,
|
| 58 | const std::map<std::string, std::string>& rwOperation)
|
| 59 | : symbolTable(symTab), recordTable(recTab) {
|
| 60 | std::string parseErrors;
|
| 61 | types = Json::parse(rwOperation.at("types"), parseErrors);
|
| 62 | assert(parseErrors.size() == 0 && "Internal JSON parsing failed.");
|
| 63 | if (rwOperation.count("params") > 0) {
|
| 64 | params = Json::parse(rwOperation.at("params"), parseErrors);
|
| 65 | assert(parseErrors.size() == 0 && "Internal JSON parsing failed.");
|
| 66 | } else {
|
| 67 | params = Json::object();
|
| 68 | }
|
| 69 |
|
| 70 | auxiliaryArity = RamSignedFromString(getOr(rwOperation, "auxArity", "0"));
|
| 71 |
|
| 72 | setupFromJson();
|
| 73 | }
|
| 74 |
|
| 75 | RO<SymbolTable>& symbolTable;
|
| 76 | RO<RecordTable>& recordTable;
|
| 77 | Json types;
|
| 78 | Json params;
|
| 79 | std::vector<std::string> typeAttributes;
|
| 80 |
|
| 81 | std::size_t arity = 0;
|
| 82 | std::size_t auxiliaryArity = 0;
|
| 83 |
|
| 84 | private:
|
| 85 | void setupFromJson() {
|
| 86 | auto&& relInfo = types["relation"];
|
| 87 | arity = static_cast<std::size_t>(relInfo["arity"].long_value());
|
| 88 |
|
| 89 | assert(relInfo["types"].is_array());
|
| 90 | auto&& relTypes = relInfo["types"].array_items();
|
| 91 | assert(relTypes.size() == arity);
|
| 92 |
|
| 93 | for (const auto& jsonType : relTypes) {
|
| 94 | const auto& typeString = jsonType.string_value();
|
| 95 | assert(!typeString.empty() && "malformed types tag");
|
| 96 | typeAttributes.push_back(typeString);
|
| 97 | }
|
| 98 |
|
| 99 | for (std::size_t i = 0; i < auxiliaryArity; i++) {
|
| 100 | typeAttributes.push_back("i:number");
|
| 101 | }
|
| 102 | }
|
| 103 | };
|
| 104 |
|
| 105 | } // namespace souffle
|