|  | // Copyright 2015 The Weave Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #include "src/states/state_change_queue.h" | 
|  |  | 
|  | #include <base/logging.h> | 
|  |  | 
|  | namespace weave { | 
|  |  | 
|  | StateChangeQueue::StateChangeQueue(size_t max_queue_size) | 
|  | : max_queue_size_(max_queue_size) { | 
|  | CHECK_GT(max_queue_size_, 0U) << "Max queue size must not be zero"; | 
|  | } | 
|  |  | 
|  | bool StateChangeQueue::NotifyPropertiesUpdated( | 
|  | base::Time timestamp, | 
|  | const base::DictionaryValue& changed_properties) { | 
|  | auto& stored_changes = state_changes_[timestamp]; | 
|  | // Merge the old property set. | 
|  | if (stored_changes) | 
|  | stored_changes->MergeDictionary(&changed_properties); | 
|  | else | 
|  | stored_changes = changed_properties.CreateDeepCopy(); | 
|  |  | 
|  | while (state_changes_.size() > max_queue_size_) { | 
|  | // Queue is full. | 
|  | // Merge the two oldest records into one. The merge strategy is: | 
|  | //  - Move non-existent properties from element [old] to [new]. | 
|  | //  - If both [old] and [new] specify the same property, | 
|  | //    keep the value of [new]. | 
|  | //  - Keep the timestamp of [new]. | 
|  | auto element_old = state_changes_.begin(); | 
|  | auto element_new = std::next(element_old); | 
|  | // This will skip elements that exist in both [old] and [new]. | 
|  | element_old->second->MergeDictionary(element_new->second.get()); | 
|  | std::swap(element_old->second, element_new->second); | 
|  | state_changes_.erase(element_old); | 
|  | } | 
|  | return true; | 
|  | } | 
|  |  | 
|  | std::vector<StateChange> StateChangeQueue::GetAndClearRecordedStateChanges() { | 
|  | std::vector<StateChange> changes; | 
|  | changes.reserve(state_changes_.size()); | 
|  | for (auto& pair : state_changes_) { | 
|  | changes.push_back(StateChange{pair.first, std::move(pair.second)}); | 
|  | } | 
|  | state_changes_.clear(); | 
|  | return changes; | 
|  | } | 
|  |  | 
|  | }  // namespace weave |