souffle  2.0.2-371-g6315b36
symbol_table_test.cpp
Go to the documentation of this file.
1 /*
2  * Souffle - A Datalog Compiler
3  * Copyright (c) 2013, 2015, Oracle and/or its affiliates. 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 symbol_table_test.cpp
12  *
13  * Tests souffle's symbol table.
14  *
15  ***********************************************************************/
16 
17 #include "tests/test.h"
18 
19 #include "souffle/SymbolTable.h"
21 #include <algorithm>
22 #include <cstddef>
23 #include <iostream>
24 #include <string>
25 #include <vector>
26 
27 namespace souffle::test {
28 
29 TEST(SymbolTable, Basics) {
30  SymbolTable table;
31 
32  table.insert("Hello");
33 
34  EXPECT_STREQ("Hello", table.resolve(table.lookup(table.resolve(table.lookup("Hello")))));
35 
36  EXPECT_EQ(table.lookup("Hello"), table.lookup(table.resolve(table.lookup("Hello"))));
37 
38  EXPECT_STREQ("Hello", table.resolve(table.lookup(table.resolve(table.lookup("Hello")))));
39 
40  EXPECT_EQ(table.lookup("Hello"),
41  table.lookup(table.resolve(table.lookup(table.resolve(table.lookup("Hello"))))));
42 }
43 
44 TEST(SymbolTable, Copy) {
45  auto* a = new SymbolTable();
46  a->insert("Hello");
47 
48  auto* b = new SymbolTable(*a);
49 
50  size_t a_idx = a->lookup("Hello");
51  size_t b_idx = b->lookup("Hello");
52 
53  // hash should be the same
54  EXPECT_EQ(a_idx, b_idx);
55 
56  EXPECT_STREQ("Hello", a->resolve(a_idx));
57  EXPECT_STREQ("Hello", b->resolve(b_idx));
58 
59  // should be the same actual string
60  EXPECT_STREQ(a->resolve(a_idx), b->resolve(b_idx));
61 
62  // b should survive
63  delete a;
64  EXPECT_STREQ("Hello", b->resolve(b_idx));
65 
66  delete b;
67 }
68 
69 TEST(SymbolTable, Assign) {
70  auto* a = new SymbolTable();
71  a->insert("Hello");
72 
73  SymbolTable b = *a;
74  SymbolTable c;
75 
76  c = *a;
77 
78  size_t a_idx = a->lookup("Hello");
79  size_t b_idx = b.lookup("Hello");
80  size_t c_idx = c.lookup("Hello");
81 
82  // hash should be the same
83  EXPECT_EQ(a_idx, b_idx);
84  EXPECT_EQ(b_idx, c_idx);
85 
86  EXPECT_STREQ("Hello", a->resolve(a_idx));
87  EXPECT_STREQ("Hello", b.resolve(b_idx));
88  EXPECT_STREQ("Hello", c.resolve(c_idx));
89 
90  // b and c should survive
91  delete a;
92  EXPECT_STREQ("Hello", b.resolve(b_idx));
93  EXPECT_STREQ("Hello", c.resolve(c_idx));
94 }
95 
96 TEST(SymbolTable, Inserts) {
97  // whether to print the recorded times to stdout
98  // should be false unless developing
99  const bool ECHO_TIME = false;
100 
101  // type for very big number
102  using T = unsigned long long;
103  time_point start;
104  time_point end;
105 
106  T n = 0; // counter
107  T N = 1000000; // number of symbols to insert
108  // T N = 10000000; // larger tables for debugging/timing
109  // T N = 100000000; // larger tables for debugging/timing
110 
111  SymbolTable X;
112  std::string x;
113 
114  std::vector<std::string> A;
115  A.reserve(N);
116 
117  for (T i = 0; i < N; ++i) {
118  x = std::to_string(i) + "string";
119  A.push_back(x);
120  }
121  start = now();
122  for (T i = 0; i < N; ++i) {
123  X.insert(A[i]); // insert one at a time
124  }
125  end = now();
126  n = duration_in_ns(start, end); // record the time
127 
128  if (ECHO_TIME) {
129  std::cout << "Time to insert " << N << " new elements: " << n << " ns" << std::endl;
130  }
131 
132  // try inserting all the elements that were just inserted
133  start = now();
134  X.insert(A);
135  end = now();
136  n = duration_in_ns(start, end);
137 
138  if (ECHO_TIME) {
139  std::cout << "Time to insert " << N << " existing elements: " << n << " ns" << std::endl;
140  }
141 }
142 
143 } // namespace souffle::test
souffle::SymbolTable::insert
void insert(const std::vector< std::string > &symbols)
Bulk insert symbols into the table, note that this operation is more efficient than repeated inserts ...
Definition: SymbolTable.h:179
souffle::SymbolTable::resolve
const std::string & resolve(const RamDomain index) const
Find a symbol in the table by its index, note that this gives an error if the index is out of bounds.
Definition: SymbolTable.h:154
SymbolTable.h
souffle::test::now
time_point now()
Definition: btree_multiset_test.cpp:402
EXPECT_EQ
#define EXPECT_EQ(a, b)
Definition: test.h:191
MiscUtil.h
souffle::test::time_point
std::chrono::high_resolution_clock::time_point time_point
Definition: btree_multiset_test.cpp:400
n
var n
Definition: htmlJsChartistMin.h:15
souffle::SymbolTable::lookup
RamDomain lookup(const std::string &symbol)
Find the index of a symbol in the table, inserting a new symbol if it does not exist there already.
Definition: SymbolTable.h:124
i
size_t i
Definition: json11.h:663
souffle::test
Definition: binary_relation_test.cpp:43
souffle::SymbolTable
Definition: SymbolTable.h:48
souffle::duration_in_ns
long duration_in_ns(const time_point &start, const time_point &end)
Definition: MiscUtil.h:99
test.h
b
l j a showGridBackground &&c b raw series this eventEmitter b
Definition: htmlJsChartistMin.h:15
EXPECT_STREQ
#define EXPECT_STREQ(a, b)
Definition: test.h:203
souffle::test::TEST
TEST(EqRelTest, Scoping)
Definition: binary_relation_test.cpp:51