diff options
Diffstat (limited to 'src/protocols.cc')
| -rw-r--r-- | src/protocols.cc | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/src/protocols.cc b/src/protocols.cc index 31b3bfd..df7353a 100644 --- a/src/protocols.cc +++ b/src/protocols.cc @@ -66,7 +66,7 @@ public: entry.data_ = data; entry.size_ = size; - reschedule_with_lock(); + if (size) reschedule_with_lock(); } void update(size_t id, void const* data, size_t size) override { @@ -87,6 +87,15 @@ public: return; } } + + for (auto const& active : active_) { + if (active == id) { + invalidate_.emplace(id); + return; + } + } + + if (old == 0) reschedule_with_lock(); } void remove(size_t id) override { @@ -268,7 +277,7 @@ private: void reschedule_with_lock() { if (cache_.size() < cache_size_) { - size_t want = cache_.size() - cache_size_; + size_t want = cache_size_ - cache_.size(); size_t queued = active_.size() + queue_.size(); if (want < queued) { want = 0; @@ -382,6 +391,14 @@ private: std::unique_ptr<Protocol::Match>&& match, std::unique_ptr<AttributedText>&& text) { active_.erase(std::find(active_.begin(), active_.end(), id)); + if (invalidate_.erase(id)) { + if (wanted_ == id) { + queue_.emplace_front(id, size, std::move(match), std::move(text)); + } else { + queue_.emplace_back(id, size, std::move(match), std::move(text)); + } + return; + } while (cache_.size() >= cache_size_) { auto oldest = cache_.end(); for (auto it = cache_.begin(); it != cache_.end(); ++it) { @@ -457,6 +474,7 @@ private: std::vector<CacheEntry> cache_; std::vector<size_t> active_; std::deque<QueueEntry> queue_; + std::unordered_set<size_t> invalidate_; std::deque<ContentEntry> content_done_; std::deque<ContentEntry> content_queue_; |
