2021-03-10 04:10:51 +00:00
|
|
|
// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
|
|
|
|
// This source code is licensed under both the GPLv2 (found in the
|
|
|
|
// COPYING file in the root directory) and Apache 2.0 License
|
|
|
|
// (found in the LICENSE.Apache file in the root directory).
|
|
|
|
|
|
|
|
#include "file/line_file_reader.h"
|
|
|
|
|
|
|
|
#include <cstring>
|
|
|
|
|
2021-09-08 01:23:58 +00:00
|
|
|
#include "monitoring/iostats_context_imp.h"
|
|
|
|
|
2021-03-10 04:10:51 +00:00
|
|
|
namespace ROCKSDB_NAMESPACE {
|
|
|
|
|
2021-09-15 22:08:39 +00:00
|
|
|
IOStatus LineFileReader::Create(const std::shared_ptr<FileSystem>& fs,
|
|
|
|
const std::string& fname,
|
|
|
|
const FileOptions& file_opts,
|
|
|
|
std::unique_ptr<LineFileReader>* reader,
|
2022-05-24 17:28:57 +00:00
|
|
|
IODebugContext* dbg,
|
|
|
|
RateLimiter* rate_limiter) {
|
2021-03-10 04:10:51 +00:00
|
|
|
std::unique_ptr<FSSequentialFile> file;
|
2021-09-15 22:08:39 +00:00
|
|
|
IOStatus io_s = fs->NewSequentialFile(fname, file_opts, &file, dbg);
|
|
|
|
if (io_s.ok()) {
|
2022-05-24 17:28:57 +00:00
|
|
|
reader->reset(new LineFileReader(
|
|
|
|
std::move(file), fname, nullptr,
|
|
|
|
std::vector<std::shared_ptr<EventListener>>{}, rate_limiter));
|
2021-03-10 04:10:51 +00:00
|
|
|
}
|
2021-09-15 22:08:39 +00:00
|
|
|
return io_s;
|
2021-03-10 04:10:51 +00:00
|
|
|
}
|
|
|
|
|
2022-05-24 17:28:57 +00:00
|
|
|
bool LineFileReader::ReadLine(std::string* out,
|
|
|
|
Env::IOPriority rate_limiter_priority) {
|
2021-03-10 04:10:51 +00:00
|
|
|
assert(out);
|
2021-09-15 22:08:39 +00:00
|
|
|
if (!io_status_.ok()) {
|
2021-03-10 04:10:51 +00:00
|
|
|
// Status should be checked (or permit unchecked) any time we return false.
|
2021-09-15 22:08:39 +00:00
|
|
|
io_status_.MustCheck();
|
2021-03-10 04:10:51 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
out->clear();
|
|
|
|
for (;;) {
|
|
|
|
// Look for line delimiter
|
|
|
|
const char* found = static_cast<const char*>(
|
|
|
|
std::memchr(buf_begin_, '\n', buf_end_ - buf_begin_));
|
|
|
|
if (found) {
|
|
|
|
size_t len = found - buf_begin_;
|
|
|
|
out->append(buf_begin_, len);
|
|
|
|
buf_begin_ += len + /*delim*/ 1;
|
|
|
|
++line_number_;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (at_eof_) {
|
2021-09-15 22:08:39 +00:00
|
|
|
io_status_.MustCheck();
|
2021-03-10 04:10:51 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
// else flush and reload buffer
|
|
|
|
out->append(buf_begin_, buf_end_ - buf_begin_);
|
|
|
|
Slice result;
|
2022-05-24 17:28:57 +00:00
|
|
|
io_status_ =
|
|
|
|
sfr_.Read(buf_.size(), &result, buf_.data(), rate_limiter_priority);
|
2021-09-08 01:23:58 +00:00
|
|
|
IOSTATS_ADD(bytes_read, result.size());
|
2021-09-15 22:08:39 +00:00
|
|
|
if (!io_status_.ok()) {
|
|
|
|
io_status_.MustCheck();
|
2021-03-10 04:10:51 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (result.size() != buf_.size()) {
|
|
|
|
// The obscure way of indicating EOF
|
|
|
|
at_eof_ = true;
|
|
|
|
}
|
|
|
|
buf_begin_ = result.data();
|
|
|
|
buf_end_ = result.data() + result.size();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace ROCKSDB_NAMESPACE
|