Skip to content

Commit 29d96d2

Browse files
committed
std::string_view implementation
1 parent fc9c690 commit 29d96d2

1 file changed

Lines changed: 18 additions & 32 deletions

File tree

mt-kahypar/io/io_utils.h

Lines changed: 18 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
#include <fcntl.h>
3131
#include <string>
32+
#include <string_view>
3233
#include <thread>
3334
#include <sys/stat.h>
3435

@@ -195,19 +196,16 @@ void goto_next_line(char* mapped_file, size_t& pos, size_t& current_line, const
195196
}
196197

197198
MT_KAHYPAR_ATTRIBUTE_ALWAYS_INLINE
198-
void goto_next_line_unrolled(char* mapped_file, size_t& pos, size_t& current_line, const size_t length) {
199-
for ( ; pos + LOOP_UNROLLING_VALUE <= length; pos += LOOP_UNROLLING_VALUE ) {
200-
uint32_t flags = 0;
201-
for (size_t i = 0; i < LOOP_UNROLLING_VALUE; ++i) {
202-
flags |= static_cast<uint32_t>(mapped_file[pos + i] == '\n') << i;
203-
}
204-
if (flags == 0) continue;
199+
void goto_next_line_unchecked(char* mapped_file, size_t& pos, size_t& current_line, const size_t length) {
200+
std::string_view sv(mapped_file + pos, length - pos);
201+
size_t offset = sv.find('\n'); // compiles to memchr
205202

206-
int offset = utils::lowest_set_bit_32(flags);
203+
if (offset != std::string_view::npos) {
207204
ASSERT(is_line_ending(mapped_file, pos + offset));
208205
pos += (offset + 1);
209206
++current_line;
210-
break;
207+
} else {
208+
pos = length;
211209
}
212210
}
213211

@@ -253,38 +251,26 @@ vec<LineRange> split_lines(char* mapped_file,
253251
vec<std::pair<size_t, size_t>> line_positions;
254252
line_positions.reserve(expected_num_lines + 1);
255253

256-
// speed up bulk of processing via loop unrolling
257-
while ( line_positions.size() + 1 < expected_num_lines &&
258-
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 ) {
259257
// skip comments
260258
while ( mapped_file[pos] == '%' && pos < length ) {
261-
goto_next_line(mapped_file, pos, current_line, length);
259+
goto_next_line_unchecked(mapped_file, pos, current_line, length);
262260
}
263261

262+
goto_next_line_unchecked(mapped_file, pos, current_line, length);
264263
line_positions.emplace_back(pos, current_line);
265-
goto_next_line_unrolled(mapped_file, pos, current_line, length);
266264
}
267-
268-
// handle remainder without unrolling
269-
if ( mapped_file[pos - 1] != '\n' || (!line_positions.empty() && pos == line_positions.back().first) ) {
270-
// if the unrolled loop stopped at a weird position, fix it
271-
size_t dummy_line = current_line;
272-
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);
273268
}
274-
while ( line_positions.size() < expected_num_lines ) {
275-
// skip comments
276-
while ( mapped_file[pos] == '%' && pos < length ) {
277-
goto_next_line(mapped_file, pos, current_line, length);
278-
}
279269

280-
if ( mapped_file[pos - 1] != '\n' || (!line_positions.empty() && pos == line_positions.back().first) ) {
281-
parsing_exception("expected " + STR(expected_num_lines + 1) + " lines, but there are only " +
282-
STR(line_positions.size()) + " lines (excluding comments)");
283-
}
284-
line_positions.emplace_back(pos, current_line);
285-
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)");
286273
}
287-
line_positions.emplace_back(pos, current_line);
288274

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

0 commit comments

Comments
 (0)