Skip to content

Commit c409200

Browse files
committed
std::string_view implementation
1 parent feadb39 commit c409200

1 file changed

Lines changed: 13 additions & 25 deletions

File tree

mt-kahypar/io/io_utils.h

Lines changed: 13 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -196,9 +196,9 @@ void goto_next_line(char* mapped_file, size_t& pos, size_t& current_line, const
196196
}
197197

198198
MT_KAHYPAR_ATTRIBUTE_ALWAYS_INLINE
199-
void goto_next_line_unrolled(char* mapped_file, size_t& pos, size_t& current_line, const size_t length) {
199+
void goto_next_line_unchecked(char* mapped_file, size_t& pos, size_t& current_line, const size_t length) {
200200
std::string_view sv(mapped_file + pos, length - pos);
201-
size_t offset = sv.find('\n');
201+
size_t offset = sv.find('\n'); // compiles to memchr
202202

203203
if (offset != std::string_view::npos) {
204204
ASSERT(is_line_ending(mapped_file, pos + offset));
@@ -251,38 +251,26 @@ vec<LineRange> split_lines(char* mapped_file,
251251
vec<std::pair<size_t, size_t>> line_positions;
252252
line_positions.reserve(expected_num_lines + 1);
253253

254-
// speed up bulk of processing via loop unrolling
255-
while ( line_positions.size() + 1 < expected_num_lines &&
256-
pos + LOOP_UNROLLING_VALUE <= length ) {
254+
// find line endings very fast
255+
line_positions.emplace_back(pos, current_line);
256+
while ( line_positions.size() < expected_num_lines + 1 && pos < length ) {
257257
// skip comments
258258
while ( mapped_file[pos] == '%' && pos < length ) {
259-
goto_next_line(mapped_file, pos, current_line, length);
259+
goto_next_line_unchecked(mapped_file, pos, current_line, length);
260260
}
261261

262+
goto_next_line_unchecked(mapped_file, pos, current_line, length);
262263
line_positions.emplace_back(pos, current_line);
263-
goto_next_line_unrolled(mapped_file, pos, current_line, length);
264264
}
265-
266-
// handle remainder without unrolling
267-
if ( mapped_file[pos - 1] != '\n' || (!line_positions.empty() && pos == line_positions.back().first) ) {
268-
// if the unrolled loop stopped at a weird position, fix it
269-
size_t dummy_line = current_line;
270-
goto_next_line(mapped_file, pos, dummy_line, length);
265+
if ( line_positions.size() < expected_num_lines + 1 && mapped_file[pos - 1] == '\n' ) {
266+
// special case for last line that is not terminated by a newline (might be end of file or empty line)
267+
line_positions.emplace_back(pos, current_line);
271268
}
272-
while ( line_positions.size() < expected_num_lines ) {
273-
// skip comments
274-
while ( mapped_file[pos] == '%' && pos < length ) {
275-
goto_next_line(mapped_file, pos, current_line, length);
276-
}
277269

278-
if ( mapped_file[pos - 1] != '\n' || (!line_positions.empty() && pos == line_positions.back().first) ) {
279-
parsing_exception("expected " + STR(expected_num_lines + 1) + " lines, but there are only " +
280-
STR(line_positions.size()) + " lines (excluding comments)");
281-
}
282-
line_positions.emplace_back(pos, current_line);
283-
goto_next_line(mapped_file, pos, current_line, length);
270+
if ( line_positions.size() < expected_num_lines + 1 ) { // note: +1 for header line
271+
parsing_exception("expected " + STR(expected_num_lines + 1) + " lines, but there are only " +
272+
STR(line_positions.size()) + " lines (excluding comments)");
284273
}
285-
line_positions.emplace_back(pos, current_line);
286274

287275
// split the lines into ranges that can be processed in parallel
288276
const size_t num_ranges = num_parallel_ranges();

0 commit comments

Comments
 (0)