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
|