| 95 | } |
| 96 | |
| 97 | void RecordYielder::MainLoop() { |
| 98 | while (true) { |
| 99 | ++epoch_; |
| 100 | num_records_yielded_in_epoch_ = 0; |
| 101 | num_records_added_in_epoch_ = 0; |
| 102 | |
| 103 | // Finds all files. |
| 104 | std::vector<string> filenames; |
| 105 | Status s = MatchFiles(opts_.file_pattern, &filenames); |
| 106 | |
| 107 | if (filenames.empty()) { |
| 108 | s = errors::NotFound("Found no files at ", opts_.file_pattern); |
| 109 | if (ShouldFinish(s)) { |
| 110 | buf_enough_.notify_all(); |
| 111 | break; |
| 112 | } |
| 113 | } |
| 114 | |
| 115 | if (ShouldFinish(s)) break; |
| 116 | |
| 117 | // Shuffles these files according to the epoch # and random seed. |
| 118 | std::mt19937_64 shuffle_rnd( |
| 119 | Hash64(reinterpret_cast<char*>(&epoch_), sizeof(epoch_), opts_.seed)); |
| 120 | std::shuffle(filenames.begin(), filenames.end(), shuffle_rnd); |
| 121 | |
| 122 | // Left-shift the filename list. |
| 123 | const std::vector<string>::size_type num = filenames.size(); |
| 124 | int64 shift; |
| 125 | if (0 <= opts_.file_shuffle_shift_ratio && |
| 126 | opts_.file_shuffle_shift_ratio < 1) { |
| 127 | shift = opts_.file_shuffle_shift_ratio * num; |
| 128 | std::rotate(filenames.begin(), filenames.begin() + shift, |
| 129 | filenames.end()); |
| 130 | } |
| 131 | |
| 132 | // Shards files and use one thread to go through each shard. |
| 133 | const int N = opts_.parallelism; |
| 134 | std::vector<Shard> shards(N); |
| 135 | for (int i = 0; i < N; ++i) { |
| 136 | Shard* shard = &shards[i]; |
| 137 | shard->index = i; |
| 138 | for (std::vector<string>::size_type j = i; j < filenames.size(); j += N) { |
| 139 | shard->filenames.push_back(filenames[j]); |
| 140 | } |
| 141 | thread_->Schedule([this, shard]() { ShardLoop(shard); }); |
| 142 | } |
| 143 | for (int i = 0; i < N; ++i) { |
| 144 | shards[i].done.WaitForNotification(); |
| 145 | s.Update(shards[i].status); |
| 146 | } |
| 147 | |
| 148 | if (num_records_added_in_epoch_ < opts_.bufsize) { |
| 149 | mutex_lock l(mu_); |
| 150 | opts_.bufsize = num_records_added_in_epoch_; |
| 151 | } |
| 152 | |
| 153 | if (ShouldFinish(s)) { |
| 154 | buf_enough_.notify_all(); |
nothing calls this directly
no test coverage detected