| 213 | } |
| 214 | |
| 215 | std::vector<std::shared_ptr<SerializedPage>> DestinationBuffer::acknowledge( |
| 216 | int64_t sequence, |
| 217 | bool fromGetData) { |
| 218 | const int64_t numDeleted = sequence - sequence_; |
| 219 | if (numDeleted == 0 && fromGetData) { |
| 220 | // If called from getData, it is expected that there will be |
| 221 | // nothing to delete because a previous acknowledgement has been |
| 222 | // received before the getData. This is not guaranteed though |
| 223 | // because the messages may arrive out of order. Note that getData |
| 224 | // implicitly acknowledges all messages with a lower sequence |
| 225 | // number than the one in getData. |
| 226 | return {}; |
| 227 | } |
| 228 | if (numDeleted <= 0) { |
| 229 | // Acknowledges come out of order, e.g. ack of 10 and 9 have |
| 230 | // swapped places in flight. |
| 231 | VLOG(1) << this << " Out of order ack: " << sequence << " over " |
| 232 | << sequence_; |
| 233 | return {}; |
| 234 | } |
| 235 | |
| 236 | BOLT_CHECK_LE( |
| 237 | numDeleted, data_.size(), "Ack received for a not yet produced item"); |
| 238 | std::vector<std::shared_ptr<SerializedPage>> freed; |
| 239 | for (auto i = 0; i < numDeleted; ++i) { |
| 240 | if (data_[i] == nullptr) { |
| 241 | BOLT_CHECK_EQ(i, data_.size() - 1, "null marker found in the middle"); |
| 242 | break; |
| 243 | } |
| 244 | stats_.recordAcknowledge(*data_[i]); |
| 245 | freed.push_back(std::move(data_[i])); |
| 246 | } |
| 247 | data_.erase(data_.begin(), data_.begin() + numDeleted); |
| 248 | sequence_ += numDeleted; |
| 249 | return freed; |
| 250 | } |
| 251 | |
| 252 | std::vector<std::shared_ptr<SerializedPage>> |
| 253 | DestinationBuffer::deleteResults() { |
no test coverage detected