Chromium Code Reviews| Index: third_party/WebKit/Source/platform/scheduler/base/time_domain.cc |
| diff --git a/third_party/WebKit/Source/platform/scheduler/base/time_domain.cc b/third_party/WebKit/Source/platform/scheduler/base/time_domain.cc |
| index e84c5c6f46ebbcf6c254ef35aaabc478ed4c0016..fa3199a70899650fa730a6583cb2ae3eb7fd7290 100644 |
| --- a/third_party/WebKit/Source/platform/scheduler/base/time_domain.cc |
| +++ b/third_party/WebKit/Source/platform/scheduler/base/time_domain.cc |
| @@ -13,6 +13,15 @@ |
| namespace blink { |
| namespace scheduler { |
| +struct TimeDomain::HeapElement { |
| + base::TimeTicks key; |
| + internal::TaskQueueImpl* value; |
| + |
| + bool operator<=(const HeapElement& other) const { return key <= other.key; } |
| + |
| + void SetHeapIndex(size_t i) { value->set_heap_index(i); } |
| +}; |
| + |
| TimeDomain::TimeDomain(Observer* observer) : observer_(observer) {} |
| TimeDomain::~TimeDomain() { |
| @@ -29,17 +38,14 @@ void TimeDomain::UnregisterQueue(internal::TaskQueueImpl* queue) { |
| DCHECK_EQ(queue->GetTimeDomain(), this); |
| UnregisterAsUpdatableTaskQueue(queue); |
| - // If present remove |task_queue| from delayed_wakeup_multimap_. |
| - // O(log n) |
| - QueueToDelayedWakeupMultimapIteratorMap::iterator it = |
| - queue_to_delayed_wakeup_multimap_iterator_map_.find(queue); |
| - |
| - if (it == queue_to_delayed_wakeup_multimap_iterator_map_.end()) |
| + // If no wakeup has been requested then bail out. |
| + if (queue->time_domain_wakeup().is_null()) |
| return; |
| - // O(1) amortized. |
| - delayed_wakeup_multimap_.erase(it->second); |
| - queue_to_delayed_wakeup_multimap_iterator_map_.erase(it); |
| + // O(log n) |
| + delayed_wakeup_queue_.eraseHeapIndex(queue->heap_index()); |
| + queue->set_time_domain_wakeup(base::TimeTicks()); |
| + queue->set_heap_index(0u); |
|
Sami
2016/10/14 07:26:16
Could we make 0u a named constant so 1-basedness o
alex clarke (OOO till 29th)
2016/10/14 13:55:35
I think I should actually move this into the templ
|
| } |
| void TimeDomain::MigrateQueue(internal::TaskQueueImpl* queue, |
| @@ -53,21 +59,18 @@ void TimeDomain::MigrateQueue(internal::TaskQueueImpl* queue, |
| if (UnregisterAsUpdatableTaskQueue(queue)) |
| destination_time_domain->updatable_queue_set_.insert(queue); |
| - // If present remove |task_queue| from delayed_wakeup_multimap_. |
| - // O(log n) |
| - QueueToDelayedWakeupMultimapIteratorMap::iterator it = |
| - queue_to_delayed_wakeup_multimap_iterator_map_.find(queue); |
| - |
| - if (it == queue_to_delayed_wakeup_multimap_iterator_map_.end()) |
| + // If no wakeup has been requested then bail out. |
| + if (queue->time_domain_wakeup().is_null()) |
| return; |
| - base::TimeTicks destination_now = destination_time_domain->Now(); |
| - destination_time_domain->ScheduleDelayedWork(queue, it->second->first, |
| - destination_now); |
| + // O(log n) |
| + delayed_wakeup_queue_.eraseHeapIndex(queue->heap_index()); |
| + queue->set_time_domain_wakeup(base::TimeTicks()); |
| + queue->set_heap_index(0u); |
| - // O(1) amortized. |
| - delayed_wakeup_multimap_.erase(it->second); |
| - queue_to_delayed_wakeup_multimap_iterator_map_.erase(it); |
| + base::TimeTicks destination_now = destination_time_domain->Now(); |
| + destination_time_domain->ScheduleDelayedWork( |
| + queue, queue->time_domain_wakeup(), destination_now); |
| } |
| void TimeDomain::ScheduleDelayedWork(internal::TaskQueueImpl* queue, |
| @@ -76,27 +79,20 @@ void TimeDomain::ScheduleDelayedWork(internal::TaskQueueImpl* queue, |
| DCHECK(main_thread_checker_.CalledOnValidThread()); |
| // We only want to store a single wakeup per queue, so we need to remove any |
| // previously registered wake up for |queue|. |
| - QueueToDelayedWakeupMultimapIteratorMap::iterator it = |
| - queue_to_delayed_wakeup_multimap_iterator_map_.find(queue); |
| - |
| - if (it != queue_to_delayed_wakeup_multimap_iterator_map_.end()) |
| - delayed_wakeup_multimap_.erase(it->second); |
| + if (!queue->time_domain_wakeup().is_null()) { |
| + delayed_wakeup_queue_.eraseHeapIndex(queue->heap_index()); |
| + queue->set_time_domain_wakeup(base::TimeTicks()); |
| + queue->set_heap_index(0u); |
| + } |
| - if (delayed_wakeup_multimap_.empty() || |
| - delayed_run_time < delayed_wakeup_multimap_.begin()->first) { |
| + if (delayed_wakeup_queue_.empty() || |
| + delayed_run_time < delayed_wakeup_queue_.min().key) { |
| base::TimeDelta delay = std::max(base::TimeDelta(), delayed_run_time - now); |
| RequestWakeup(now, delay); |
| } |
| - if (it != queue_to_delayed_wakeup_multimap_iterator_map_.end()) { |
| - // TODO(alexclarke): Use C++17 extract & insert to more efficiently modify |
| - // |queue_to_delayed_wakeup_multimap_iterator_map_|. |
| - it->second = delayed_wakeup_multimap_.insert({delayed_run_time, queue}); |
| - } else { |
| - // Insert the wakeup and store the map iterator for later convenience. |
| - queue_to_delayed_wakeup_multimap_iterator_map_.insert( |
| - {queue, delayed_wakeup_multimap_.insert({delayed_run_time, queue})}); |
| - } |
| + delayed_wakeup_queue_.insert({delayed_run_time, queue}); |
|
Sami
2016/10/14 07:26:16
Would it make sense to add an emplace() for this?
alex clarke (OOO till 29th)
2016/10/14 13:55:35
The thing about emplace is, if we're gonna do it w
|
| + queue->set_time_domain_wakeup(delayed_run_time); |
| if (observer_) |
| observer_->OnTimeDomainHasDelayedWork(queue); |
| @@ -167,38 +163,32 @@ void TimeDomain::WakeupReadyDelayedQueues(LazyNow* lazy_now) { |
| // Wake up any queues with pending delayed work. Note std::multipmap stores |
| // the elements sorted by key, so the begin() iterator points to the earliest |
| // queue to wakeup. |
| - while (!delayed_wakeup_multimap_.empty()) { |
| - DelayedWakeupMultimap::iterator next_wakeup = |
| - delayed_wakeup_multimap_.begin(); |
| - if (next_wakeup->first > lazy_now->Now()) |
| - break; |
| - |
| - internal::TaskQueueImpl* queue = next_wakeup->second; |
| - |
| - // O(1) amortized. |
| - delayed_wakeup_multimap_.erase(next_wakeup); |
| - // O(log n). |
| - queue_to_delayed_wakeup_multimap_iterator_map_.erase(queue); |
| + while (!delayed_wakeup_queue_.empty() && |
| + delayed_wakeup_queue_.min().key <= lazy_now->Now()) { |
| + internal::TaskQueueImpl* queue = delayed_wakeup_queue_.min().value; |
| + // O(log n) |
| + delayed_wakeup_queue_.eraseMin(); |
| + queue->set_time_domain_wakeup(base::TimeTicks()); |
| queue->WakeUpForDelayedWork(lazy_now); |
| } |
| } |
| bool TimeDomain::NextScheduledRunTime(base::TimeTicks* out_time) const { |
| DCHECK(main_thread_checker_.CalledOnValidThread()); |
| - if (delayed_wakeup_multimap_.empty()) |
| + if (delayed_wakeup_queue_.empty()) |
| return false; |
| - *out_time = delayed_wakeup_multimap_.begin()->first; |
| + *out_time = delayed_wakeup_queue_.min().key; |
| return true; |
| } |
| bool TimeDomain::NextScheduledTaskQueue(TaskQueue** out_task_queue) const { |
| DCHECK(main_thread_checker_.CalledOnValidThread()); |
| - if (delayed_wakeup_multimap_.empty()) |
| + if (delayed_wakeup_queue_.empty()) |
| return false; |
| - *out_task_queue = delayed_wakeup_multimap_.begin()->second; |
| + *out_task_queue = delayed_wakeup_queue_.min().value; |
| return true; |
| } |
| @@ -209,9 +199,9 @@ void TimeDomain::AsValueInto(base::trace_event::TracedValue* state) const { |
| for (auto* queue : updatable_queue_set_) |
| state->AppendString(queue->GetName()); |
| state->EndArray(); |
| - state->SetInteger("registered_delay_count", delayed_wakeup_multimap_.size()); |
| - if (!delayed_wakeup_multimap_.empty()) { |
| - base::TimeDelta delay = delayed_wakeup_multimap_.begin()->first - Now(); |
| + state->SetInteger("registered_delay_count", delayed_wakeup_queue_.size()); |
| + if (!delayed_wakeup_queue_.empty()) { |
| + base::TimeDelta delay = delayed_wakeup_queue_.min().key - Now(); |
| state->SetDouble("next_delay_ms", delay.InMillisecondsF()); |
| } |
| AsValueIntoInternal(state); |