Try to update a leaf's stats by acquiring its lock. If it can't be acquired, put it in a waiting queue to come back to later and try the next one. Once all leaf_ids have been visited, cycle through the waiting ids until they're gone.
| 146 | // one. Once all leaf_ids have been visited, cycle through the waiting ids |
| 147 | // until they're gone. |
| 148 | void UpdateStats(const core::RefCountPtr<FertileStatsResource>& resource, |
| 149 | const std::unique_ptr<TensorDataSet>& data, |
| 150 | const TensorInputTarget& target, int num_targets, |
| 151 | const Tensor& leaf_ids_tensor, |
| 152 | std::unordered_map<int32, std::unique_ptr<mutex>>* locks, |
| 153 | mutex* set_lock, int32 start, int32 end, |
| 154 | std::unordered_set<int32>* ready_to_split) { |
| 155 | const auto leaf_ids = leaf_ids_tensor.unaligned_flat<int32>(); |
| 156 | |
| 157 | // Stores leaf_id, leaf_depth, example_id for examples that are waiting |
| 158 | // on another to finish. |
| 159 | std::queue<std::tuple<int32, int32>> waiting; |
| 160 | |
| 161 | int32 i = start; |
| 162 | while (i < end || !waiting.empty()) { |
| 163 | int32 leaf_id; |
| 164 | int32 example_id; |
| 165 | bool was_waiting = false; |
| 166 | if (i >= end) { |
| 167 | std::tie(leaf_id, example_id) = waiting.front(); |
| 168 | waiting.pop(); |
| 169 | was_waiting = true; |
| 170 | } else { |
| 171 | leaf_id = leaf_ids(i); |
| 172 | example_id = i; |
| 173 | ++i; |
| 174 | } |
| 175 | const std::unique_ptr<mutex>& leaf_lock = (*locks)[leaf_id]; |
| 176 | if (was_waiting) { |
| 177 | leaf_lock->lock(); |
| 178 | } else { |
| 179 | if (!leaf_lock->try_lock()) { |
| 180 | waiting.emplace(leaf_id, example_id); |
| 181 | continue; |
| 182 | } |
| 183 | } |
| 184 | |
| 185 | bool is_finished; |
| 186 | resource->AddExampleToStatsAndInitialize(data, &target, {example_id}, |
| 187 | leaf_id, &is_finished); |
| 188 | leaf_lock->unlock(); |
| 189 | if (is_finished) { |
| 190 | set_lock->lock(); |
| 191 | ready_to_split->insert(leaf_id); |
| 192 | set_lock->unlock(); |
| 193 | } |
| 194 | } |
| 195 | } |
| 196 | |
| 197 | // Update leaves from start through end in the leaf_examples iterator. |
| 198 | void UpdateStatsCollated( |