New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Better result tables #193
Better result tables #193
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow, that's what I call a giant Pull Request. Reviewing and testing this will take some time but here is what I noticed on a quick first pass. Overall this already looks very nice
class OBComp { | ||
public: | ||
OBComp(const vector<pair<size_t, bool>>& sortIndices) | ||
: _sortIndices(sortIndices) {} | ||
|
||
bool operator()(const E& a, const E& b) const { | ||
template <int I> | ||
bool operator()(const typename IdTableImpl<I>::Row& a, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should take the Row
type from IdTableStatic
instead of from the …Impl
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's what I tried out initially, but because the Row
type in IdTableStatic
is declared using a using
statement the compiler had trouble inferring the value of I
(which must be found using template argument deduction). Templating the entire comparator on the other hand leads to the problem, that the I needs to be determined within the OrderBy
operation, which would require a set of 5 if clauses to determine the value of I
for the comparator (as the CALL_WITH_FIXED...
macros don't support this case).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting that using
changes the behavior like that, do you think that is intended/correct or rather a compiler problem?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually am not certain if this should work or not, but I think it might fall into the 'Aliases are never deduced' rule (cppreference).
src/engine/IdTable.h
Outdated
if (IdTableImpl<COLS>::_size + 1 >= IdTableImpl<COLS>::_capacity) { | ||
grow(); | ||
} | ||
std::memcpy(IdTableImpl<COLS>::_data + |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think a normal assignment might be preferable to forcing a memcpy
here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using memcpy
avoids the less efficient row based access here (which would construct and object). As this is part of the internals of the IdTable
I went for efficiency over simplicity here.
341aca9
to
1f65a85
Compare
DeepCode encountered a problem when analyzing this pull request. If you want to retry, create a comment: "Retry Deepcode". |
src/engine/IdTable.h
Outdated
/** | ||
* This is simply an Id* which has some additional methods. | ||
**/ | ||
class ConstRow { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this have a Id*
field so that as a struct it does indeed have the same size as an Id*
? Also I think it should be specified final
then we can also drop the virtual destructor
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought about this and then realized that the custom Row
type for tables with a fixed with doesn't make any sense. The latest commit changes it to std::array<Id, COLS>
, which should make the operator[]
perform significantly more standard conform for IdTableStatic
with fixed width.
@floriankramer somehow your commits look like GitHub sees two identies for you. You might want to check if you have all your mail addresses in your GitHub profile |
ec729e8
to
1b202ce
Compare
1b202ce
to
effdcc7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few nitpicks/questions other than that I think this is almost ready to merge. Great work!
iterator(Id* data, size_t row, size_t cols) | ||
: _data(data), _row(row), _rowView(data + (cols * row), cols) {} | ||
iterator() : _data(nullptr), _row(0) {} | ||
iterator(Id* data, size_t row, size_t) : _data(data), _row(row) {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's with the last unnamed parameter here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The iterator has to take the number of columns as a parameter to allow for compatibility between the fixed width and variable with IdTable
. To prevent the compiler from complaining about an unused parameter we can either not give the parameter a name, or cast it to void in the constructors body (e.g. (void)cols;
).
I've added a comment explaining the unnamed parameter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you could also use
iterator(Id* data, size_t row, size_t /* cols */) : _data(data), _row(row) {}
} | ||
} | ||
|
||
Row& operator=(const Row& other) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need a check for self assignment here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added the check
return *this; | ||
} | ||
|
||
Row& operator=(Row&& other) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Self assignment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added the check
IdTableImpl<COLS>::setCols(cols); | ||
} | ||
|
||
void emplace_back() { push_back(); } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need the no param emplace_back()
if we don't have one with params?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added the no params version for convenience (and because it was used in several places in the code and made porting that to IdTables
easier). I haven't yet found a nice way of implementing an emplace with arguments that doesn't rely on c style va_args.
src/engine/IndexScan.cpp
Outdated
} | ||
|
||
// _____________________________________________________________________________ | ||
void IndexScan::computeSOPfreeO(ResultTable* result) const { | ||
result->_nofColumns = 2; | ||
result->_data.setCols(result->_nofColumns); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we could remove the _nofColumns
member from ResultTable
that would only save 8 bytes but also remove the line above this line
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed
@floriankramer any idea what killed the QLever instance during the end-to-end tests with the latest changes? Locally it seems to hang at
of the first query |
@floriankramer I was able to reproduce this running under
This seems to indicate that somewhere the columns did indeed get mixed up
|
92eebe4
to
2e1ac17
Compare
This pr replaces
std::vector<std::array>
andstd::vector<std::vector>
as the data type used by result tables to a newIdTable
type. This ensures that the result data is always stored dense and makes the templating of operations easier.