Home | History | Annotate | Download | only in states
      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 
      9 namespace weave {
     10 
     11 StateChangeQueue::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 
     16 bool 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 
     43 std::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