blob: effe7f3f8ff940942fef1917cd1d0d820c32b009 [file] [log] [blame]
// 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.reset(changed_properties.DeepCopy());
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