1// Copyright 2015 The Weave Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "src/states/state_change_queue.h" 6 7#include <base/logging.h> 8 9namespace weave { 10 11StateChangeQueue::StateChangeQueue(size_t max_queue_size) 12 : max_queue_size_(max_queue_size) { 13 CHECK_GT(max_queue_size_, 0U) << "Max queue size must not be zero"; 14} 15 16bool StateChangeQueue::NotifyPropertiesUpdated( 17 base::Time timestamp, 18 const base::DictionaryValue& changed_properties) { 19 auto& stored_changes = state_changes_[timestamp]; 20 // Merge the old property set. 21 if (stored_changes) 22 stored_changes->MergeDictionary(&changed_properties); 23 else 24 stored_changes.reset(changed_properties.DeepCopy()); 25 26 while (state_changes_.size() > max_queue_size_) { 27 // Queue is full. 28 // Merge the two oldest records into one. The merge strategy is: 29 // - Move non-existent properties from element [old] to [new]. 30 // - If both [old] and [new] specify the same property, 31 // keep the value of [new]. 32 // - Keep the timestamp of [new]. 33 auto element_old = state_changes_.begin(); 34 auto element_new = std::next(element_old); 35 // This will skip elements that exist in both [old] and [new]. 36 element_old->second->MergeDictionary(element_new->second.get()); 37 std::swap(element_old->second, element_new->second); 38 state_changes_.erase(element_old); 39 } 40 return true; 41} 42 43std::vector<StateChange> StateChangeQueue::GetAndClearRecordedStateChanges() { 44 std::vector<StateChange> changes; 45 changes.reserve(state_changes_.size()); 46 for (auto& pair : state_changes_) { 47 changes.push_back(StateChange{pair.first, std::move(pair.second)}); 48 } 49 state_changes_.clear(); 50 return changes; 51} 52 53} // namespace weave 54