Skip to content

Commit c20bf78

Browse files
committed
Add DiagnosticStream to QueryPlanner & ByteCodeInterpreter.
1 parent da5bbd2 commit c20bf78

14 files changed

+213
-37
lines changed

inc/BitFunnel/Plan/Factories.h

+5-3
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,12 @@ namespace BitFunnel
5656

5757
// TODO: get rid of these convenience methods?
5858
std::vector<DocId> RunQueryPlanner(TermMatchNode const & tree,
59-
ISimpleIndex const & index,
60-
IDiagnosticStream* diagnosticStream);
59+
ISimpleIndex const & index,
60+
IDiagnosticStream & diagnosticStream);
6161

62-
std::vector<DocId> RunSimplePlanner(TermMatchNode const & tree, ISimpleIndex const & index);
62+
std::vector<DocId> RunSimplePlanner(TermMatchNode const & tree,
63+
ISimpleIndex const & index,
64+
IDiagnosticStream & diagnosticStream);
6365

6466
}
6567
}

inc/BitFunnel/Utilities/Factories.h

+3
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
namespace BitFunnel
3333
{
3434
class IBlockAllocator;
35+
class IDiagnosticStream;
3536
class IObjectFormatter;
3637
class ITaskProcessor;
3738
class ITokenManager;
@@ -41,6 +42,8 @@ namespace BitFunnel
4142
std::unique_ptr<IBlockAllocator>
4243
CreateBlockAllocator(size_t blockSize, size_t totalBlockCount);
4344

45+
std::unique_ptr<IDiagnosticStream> CreateDiagnosticStream(std::ostream& stream);
46+
4447
// TODO: return unique_ptr.
4548
IObjectFormatter* CreateObjectFormatter(std::ostream& output);
4649

src/Common/Utilities/src/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ set(CPPFILES
55
Allocator.cpp
66
BlockAllocator.cpp
77
ConsoleLogger.cpp
8+
DiagnosticStream.cpp
89
Exceptions.cpp
910
FileHeader.cpp
1011
Logging.cpp
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#include "DiagnosticStream.h"
2+
#include "BitFunnel/Utilities/Factories.h"
3+
4+
5+
namespace BitFunnel
6+
{
7+
std::unique_ptr<IDiagnosticStream> Factories::CreateDiagnosticStream(std::ostream& stream)
8+
{
9+
return std::unique_ptr<IDiagnosticStream>(new DiagnosticStream(stream));
10+
}
11+
12+
13+
DiagnosticStream::DiagnosticStream(std::ostream& stream)
14+
: m_stream(stream)
15+
{
16+
}
17+
18+
19+
void DiagnosticStream::Enable(char const * diagnostic)
20+
{
21+
// TODO: REVIEW: check for duplicates?
22+
m_enabled.push_back(diagnostic);
23+
}
24+
25+
26+
void DiagnosticStream::Disable(char const * diagnostic)
27+
{
28+
// TODO: REVIEW: check for mismatch?
29+
for (unsigned i = 0 ; i < m_enabled.size(); ++i)
30+
{
31+
if (m_enabled[i].compare(diagnostic) == 0)
32+
{
33+
m_enabled.erase(m_enabled.begin() + i);
34+
35+
// TODO: REVIEW: Assuming there is only one to remove.
36+
break;
37+
}
38+
}
39+
}
40+
41+
42+
// Returns true if text starts with prefix.
43+
bool StartsWith(char const * text, std::string const & prefix)
44+
{
45+
for (unsigned i = 0 ; i < prefix.size(); ++i)
46+
{
47+
if (*text != prefix[i])
48+
{
49+
return false;
50+
}
51+
++text;
52+
}
53+
return true;
54+
}
55+
56+
57+
bool DiagnosticStream::IsEnabled(char const * diagnostic) const
58+
{
59+
for (unsigned i = 0; i < m_enabled.size(); ++i)
60+
{
61+
if (StartsWith(diagnostic, m_enabled[i]))
62+
{
63+
return true;
64+
}
65+
}
66+
return false;
67+
}
68+
69+
70+
std::ostream& DiagnosticStream::GetStream()
71+
{
72+
return m_stream;
73+
}
74+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#pragma once
2+
3+
#include <string> // Embeds std::string.
4+
#include <vector> // Embeds std::vector.
5+
6+
#include "BitFunnel/IDiagnosticStream.h" // Inherits from IDiagnosticStream.
7+
#include "BitFunnel/NonCopyable.h" // Inherits from NonCopyable.
8+
9+
10+
namespace BitFunnel
11+
{
12+
//*************************************************************************
13+
//
14+
// DiagnosticStream implements the IDiagnosticStream interface to provice
15+
// an std::ostream used to output diagnostic information.
16+
//
17+
// DiagnosticStream maintains a list of diagnostic keyword prefixes that
18+
// enable diagnostics for various parts of the system. Code with the
19+
// ability to emit diagnostic information should use the IsEnabled() method
20+
// to determine whether to actually write to the diagnostic stream.
21+
//
22+
//*************************************************************************
23+
class DiagnosticStream : public IDiagnosticStream, NonCopyable
24+
{
25+
public:
26+
// Constructs a DiagnosticStream that outputs to the specified stream.
27+
DiagnosticStream(std::ostream& stream);
28+
29+
// Adds the diagnostic keyword prefix to the list of prefixes that
30+
// enable diagnostics.
31+
void Enable(char const * diagnostic);
32+
33+
// Removes the diagnostic keyword prefix from the list of prefixes
34+
// that enable diagnostics.
35+
void Disable(char const * diagnostic);
36+
37+
// Returns true if the diagnostic keyword begins with one of the
38+
// prefixes.
39+
bool IsEnabled(char const * diagnostic) const;
40+
41+
// Returns a reference to the stream used for diagnostic output.
42+
std::ostream& GetStream();
43+
44+
private:
45+
std::ostream& m_stream;
46+
47+
std::vector<std::string> m_enabled;
48+
};
49+
}

src/Plan/src/ByteCodeInterpreter.cpp

+17-2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <limits>
2525

2626
#include "BitFunnel/Exceptions.h"
27+
#include "BitFunnel/IDiagnosticStream.h"
2728
#include "BitFunnel/Plan/IResultsProcessor.h"
2829
#include "ByteCodeInterpreter.h"
2930
#include "LoggerInterfaces/Check.h"
@@ -63,14 +64,16 @@ Decide on type of Slices
6364
size_t sliceCount,
6465
char * const * sliceBuffers,
6566
size_t iterationsPerSlice,
66-
ptrdiff_t const * rowOffsets)
67+
ptrdiff_t const * rowOffsets,
68+
IDiagnosticStream& diagnosticStream)
6769
: m_code(code.GetCode()),
6870
m_jumpTable(code.GetJumpTable()),
6971
m_resultsProcessor(resultsProcessor),
7072
m_sliceCount(sliceCount),
7173
m_sliceBuffers(sliceBuffers),
7274
m_iterationsPerSlice(iterationsPerSlice),
73-
m_rowOffsets(rowOffsets)
75+
m_rowOffsets(rowOffsets),
76+
m_diagnosticStream(diagnosticStream)
7477
{
7578
}
7679

@@ -116,13 +119,25 @@ Decide on type of Slices
116119
m_ip = m_code.data();
117120
m_offset = iteration;
118121

122+
if (m_diagnosticStream.IsEnabled("bytecode/run"))
123+
{
124+
std::ostream& out = m_diagnosticStream.GetStream();
125+
out << "--------------------" << std::endl;
126+
out << "ByteCode RunOneIteration:" << std::endl;
127+
}
128+
119129
while (m_ip->GetOpcode() != Opcode::End)
120130
{
121131
const Opcode opcode = m_ip->GetOpcode();
122132
const unsigned row = m_ip->GetRow();
123133
const unsigned delta = m_ip->GetDelta();
124134
const bool inverted = m_ip->IsInverted();
125135

136+
if (m_diagnosticStream.IsEnabled("bytecode/run"))
137+
{
138+
std::ostream& out = m_diagnosticStream.GetStream();
139+
out << "Opcode: " << opcode << std::endl;
140+
}
126141
switch (opcode)
127142
{
128143
case Opcode::AndRow:

src/Plan/src/ByteCodeInterpreter.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
namespace BitFunnel
3535
{
3636
class ByteCodeGenerator;
37+
class IDiagnosticStream;
3738
class IResultsProcessor;
3839

3940
//*************************************************************************
@@ -69,7 +70,8 @@ namespace BitFunnel
6970
size_t sliceCount,
7071
char * const * sliceBuffers,
7172
size_t iterationsPerSlice,
72-
ptrdiff_t const * rowOffsets);
73+
ptrdiff_t const * rowOffsets,
74+
IDiagnosticStream & diagnosticStream);
7375

7476
// Runs the instruction sequence for a specified number of iterations.
7577
// Each iteration processes a single quadword of row data at the
@@ -216,6 +218,8 @@ namespace BitFunnel
216218

217219
// TODO: Formalize definition and usage of zero flag.
218220
bool m_zeroFlag;
221+
222+
IDiagnosticStream& m_diagnosticStream;
219223
};
220224

221225
inline std::ostream& operator<<(std::ostream& out, const ByteCodeInterpreter::Opcode value)

src/Plan/src/QueryPlanner.cpp

+21-19
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ namespace BitFunnel
5454
// way SimplePlanner is connected.
5555
std::vector<DocId> Factories::RunQueryPlanner(TermMatchNode const & tree,
5656
ISimpleIndex const & index,
57-
IDiagnosticStream* diagnosticStream)
57+
IDiagnosticStream& diagnosticStream)
5858
{
5959
// TODO: this really shouldn't create its own allocator.
6060
Allocator allocator(4096*16);
@@ -92,18 +92,18 @@ namespace BitFunnel
9292
ISimpleIndex const & index,
9393
// IThreadResources& threadResources,
9494
IAllocator& allocator,
95-
IDiagnosticStream* diagnosticStream)
95+
IDiagnosticStream& diagnosticStream)
9696
// bool generateNonBodyPlan,
9797
// unsigned maxIterationsScannedBetweenTerminationChecks)
9898
: m_resultsProcessor(Factories::CreateSimpleResultsProcessor())
9999
// : // m_x64FunctionGeneratorWrapper(threadResources),
100100
// m_maxIterationsScannedBetweenTerminationChecks(maxIterationsScannedBetweenTerminationChecks)
101101
{
102-
if (diagnosticStream != nullptr && diagnosticStream->IsEnabled("planning/term"))
102+
if (diagnosticStream.IsEnabled("planning/term"))
103103
{
104-
std::ostream& out = diagnosticStream->GetStream();
104+
std::ostream& out = diagnosticStream.GetStream();
105105
std::unique_ptr<IObjectFormatter>
106-
formatter(Factories::CreateObjectFormatter(diagnosticStream->GetStream()));
106+
formatter(Factories::CreateObjectFormatter(diagnosticStream.GetStream()));
107107

108108
out << "--------------------" << std::endl;
109109
out << "Term Plan:" << std::endl;
@@ -117,11 +117,11 @@ namespace BitFunnel
117117
// generateNonBodyPlan,
118118
allocator);
119119

120-
if (diagnosticStream != nullptr && diagnosticStream->IsEnabled("planning/row"))
120+
if (diagnosticStream.IsEnabled("planning/row"))
121121
{
122-
std::ostream& out = diagnosticStream->GetStream();
122+
std::ostream& out = diagnosticStream.GetStream();
123123
std::unique_ptr<IObjectFormatter>
124-
formatter(Factories::CreateObjectFormatter(diagnosticStream->GetStream()));
124+
formatter(Factories::CreateObjectFormatter(diagnosticStream.GetStream()));
125125

126126
out << "--------------------" << std::endl;
127127
out << "Row Plan:" << std::endl;
@@ -131,11 +131,11 @@ namespace BitFunnel
131131

132132
m_planRows = &rowPlan.GetPlanRows();
133133

134-
if (diagnosticStream != nullptr && diagnosticStream->IsEnabled("planning/planrows"))
134+
if (diagnosticStream.IsEnabled("planning/planrows"))
135135
{
136-
std::ostream& out = diagnosticStream->GetStream();
136+
std::ostream& out = diagnosticStream.GetStream();
137137
std::unique_ptr<IObjectFormatter>
138-
formatter(Factories::CreateObjectFormatter(diagnosticStream->GetStream()));
138+
formatter(Factories::CreateObjectFormatter(diagnosticStream.GetStream()));
139139

140140
out << "--------------------" << std::endl;
141141
out << "IPlanRows:" << std::endl;
@@ -161,11 +161,11 @@ namespace BitFunnel
161161
allocator);
162162

163163

164-
if (diagnosticStream != nullptr && diagnosticStream->IsEnabled("planning/rewrite"))
164+
if (diagnosticStream.IsEnabled("planning/rewrite"))
165165
{
166-
std::ostream& out = diagnosticStream->GetStream();
166+
std::ostream& out = diagnosticStream.GetStream();
167167
std::unique_ptr<IObjectFormatter>
168-
formatter(Factories::CreateObjectFormatter(diagnosticStream->GetStream()));
168+
formatter(Factories::CreateObjectFormatter(diagnosticStream.GetStream()));
169169

170170
out << "--------------------" << std::endl;
171171
out << "Rewritten Plan:" << std::endl;
@@ -178,11 +178,11 @@ namespace BitFunnel
178178
compiler.Compile(rewritten);
179179
CompileNode const & compileTree = compiler.CreateTree(c_maxRankValue);
180180

181-
if (diagnosticStream != nullptr && diagnosticStream->IsEnabled("planning/compile"))
181+
if (diagnosticStream.IsEnabled("planning/compile"))
182182
{
183-
std::ostream& out = diagnosticStream->GetStream();
183+
std::ostream& out = diagnosticStream.GetStream();
184184
std::unique_ptr<IObjectFormatter>
185-
formatter(Factories::CreateObjectFormatter(diagnosticStream->GetStream()));
185+
formatter(Factories::CreateObjectFormatter(diagnosticStream.GetStream()));
186186

187187
out << "--------------------" << std::endl;
188188
out << "Compile Nodes:" << std::endl;
@@ -223,14 +223,16 @@ namespace BitFunnel
223223
size_t sliceCount = sliceBuffers.size();
224224

225225
// Iterations per slice calculation.
226-
auto iterationsPerSlice = shard.GetSliceCapacity() >> 6 >> c_maxRankValue;
226+
const int c_horribleRankHack = 3;
227+
auto iterationsPerSlice = shard.GetSliceCapacity() >> 6 >> c_horribleRankHack;
227228

228229
ByteCodeInterpreter intepreter(m_code,
229230
*m_resultsProcessor,
230231
sliceCount,
231232
reinterpret_cast<char* const *>(sliceBuffers.data()),
232233
iterationsPerSlice,
233-
rowSet.GetRowOffsets(c_shardId));
234+
rowSet.GetRowOffsets(c_shardId),
235+
diagnosticStream);
234236

235237
intepreter.Run();
236238

src/Plan/src/QueryPlanner.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ namespace BitFunnel
5151
ISimpleIndex const & index,
5252
// IThreadResources& threadResources,
5353
IAllocator& allocator,
54-
IDiagnosticStream* diagnosticStream);
54+
IDiagnosticStream& diagnosticStream);
5555
// bool generateNonBodyPlan,
5656
// unsigned maxIterationsScannedBetweenTerminationChecks);
5757

src/Plan/src/QueryRunner.cpp

+8-1
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,15 @@
2020
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2121
// THE SOFTWARE.
2222

23+
#include <iostream> // Used for DiagnosticStream ref; not actually used.
24+
#include <memory> // Used for std::unique_ptr of diagnosticStream. Probably temporary.
2325
#include <ostream>
2426
#include <sstream>
2527

2628
#include "Allocator.h"
2729
#include "BitFunnel/Configuration/Factories.h"
2830
#include "BitFunnel/Configuration/IStreamConfiguration.h"
31+
#include "BitFunnel/IDiagnosticStream.h"
2932
#include "BitFunnel/Plan/Factories.h"
3033
#include "BitFunnel/Plan/QueryRunner.h"
3134
#include "BitFunnel/Utilities/Factories.h"
@@ -124,9 +127,13 @@ namespace BitFunnel
124127
QueryParser parser(s, m_config, *m_allocator);
125128
auto tree = parser.Parse();
126129

130+
// TODO: remove diagnosticStream and replace with nullable.
131+
auto diagnosticStream = Factories::CreateDiagnosticStream(std::cout);
127132
if (tree != nullptr)
128133
{
129-
auto observed = Factories::RunSimplePlanner(*tree, m_index);
134+
auto observed = Factories::RunSimplePlanner(*tree,
135+
m_index,
136+
*diagnosticStream);
130137
}
131138
}
132139

0 commit comments

Comments
 (0)