summaryrefslogtreecommitdiffstats
path: root/components/invalidation/unacked_invalidation_set.cc
diff options
context:
space:
mode:
authorrlarocque@chromium.org <rlarocque@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-07-17 19:28:46 +0000
committerrlarocque@chromium.org <rlarocque@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-07-17 19:28:46 +0000
commit001bbfdc4da9f8aec8e1a30770a1e4cef2347e0a (patch)
tree1017f4628ef475caaf86573c9c8ec2e7aa341997 /components/invalidation/unacked_invalidation_set.cc
parentcb363e702cb70f99c707be975e57015b438eaef0 (diff)
downloadchromium_src-001bbfdc4da9f8aec8e1a30770a1e4cef2347e0a.zip
chromium_src-001bbfdc4da9f8aec8e1a30770a1e4cef2347e0a.tar.gz
chromium_src-001bbfdc4da9f8aec8e1a30770a1e4cef2347e0a.tar.bz2
Move sync/notifier to components/invalidation
Moves all code remaining in sync/notifier to components/invalidation. Updates gyp files, DEPS, and #includes accordingly. In terms of program behavior, this should be one big no-op. This CL contains no non-trivial code changes. In terms of the build system, this is a significant change. Symbols that were previously exported through sync_notifier and related targets have moved into the components/invalidation related targets. Some SYNC_EXPORT macros have been replaced with INVALIDATION_EXPORT, which is significant since INVALIDATION_EXPORT is currently a no-op but SYNC_EXPORT has meaning under some build configurations. Unlike most other files in sync/notifier, invalidation_util.{cc,h} was moved to sync/internal_api/public/base. This is so it could be referenced from sync/internal_api/public/base/invalidation.cc. This is a slight regression, but it should be fixed in the next CL when we move all invalidations-related code out of sync/internal_api. TBR=rogerta,benwells BUG=259559 Review URL: https://codereview.chromium.org/387733004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@283840 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'components/invalidation/unacked_invalidation_set.cc')
-rw-r--r--components/invalidation/unacked_invalidation_set.cc210
1 files changed, 210 insertions, 0 deletions
diff --git a/components/invalidation/unacked_invalidation_set.cc b/components/invalidation/unacked_invalidation_set.cc
new file mode 100644
index 0000000..0d94a2f
--- /dev/null
+++ b/components/invalidation/unacked_invalidation_set.cc
@@ -0,0 +1,210 @@
+// Copyright 2014 The Chromium 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 "components/invalidation/unacked_invalidation_set.h"
+
+#include "base/strings/string_number_conversions.h"
+#include "components/invalidation/object_id_invalidation_map.h"
+#include "sync/internal_api/public/base/ack_handle.h"
+
+namespace {
+
+const char kSourceKey[] = "source";
+const char kNameKey[] = "name";
+const char kInvalidationListKey[] = "invalidation-list";
+
+} // namespace
+
+namespace syncer {
+
+const size_t UnackedInvalidationSet::kMaxBufferedInvalidations = 5;
+
+// static
+UnackedInvalidationSet::UnackedInvalidationSet(
+ invalidation::ObjectId id)
+ : registered_(false),
+ object_id_(id) {}
+
+UnackedInvalidationSet::UnackedInvalidationSet(
+ const UnackedInvalidationSet& other)
+ : registered_(other.registered_),
+ object_id_(other.object_id_),
+ invalidations_(other.invalidations_) {
+}
+
+UnackedInvalidationSet::~UnackedInvalidationSet() {}
+
+const invalidation::ObjectId& UnackedInvalidationSet::object_id() const {
+ return object_id_;
+}
+
+void UnackedInvalidationSet::Add(
+ const Invalidation& invalidation) {
+ SingleObjectInvalidationSet set;
+ set.Insert(invalidation);
+ AddSet(set);
+ if (!registered_)
+ Truncate(kMaxBufferedInvalidations);
+}
+
+void UnackedInvalidationSet::AddSet(
+ const SingleObjectInvalidationSet& invalidations) {
+ invalidations_.insert(invalidations.begin(), invalidations.end());
+ if (!registered_)
+ Truncate(kMaxBufferedInvalidations);
+}
+
+void UnackedInvalidationSet::ExportInvalidations(
+ WeakHandle<AckHandler> ack_handler,
+ ObjectIdInvalidationMap* out) const {
+ for (SingleObjectInvalidationSet::const_iterator it = invalidations_.begin();
+ it != invalidations_.end(); ++it) {
+ // Copy the invalidation and set the copy's ack_handler.
+ Invalidation inv(*it);
+ inv.set_ack_handler(ack_handler);
+ out->Insert(inv);
+ }
+}
+
+void UnackedInvalidationSet::Clear() {
+ invalidations_.clear();
+}
+
+void UnackedInvalidationSet::SetHandlerIsRegistered() {
+ registered_ = true;
+}
+
+void UnackedInvalidationSet::SetHandlerIsUnregistered() {
+ registered_ = false;
+ Truncate(kMaxBufferedInvalidations);
+}
+
+// Removes the matching ack handle from the list.
+void UnackedInvalidationSet::Acknowledge(const AckHandle& handle) {
+ bool handle_found = false;
+ for (SingleObjectInvalidationSet::const_iterator it = invalidations_.begin();
+ it != invalidations_.end(); ++it) {
+ if (it->ack_handle().Equals(handle)) {
+ invalidations_.erase(*it);
+ handle_found = true;
+ break;
+ }
+ }
+ DLOG_IF(WARNING, !handle_found)
+ << "Unrecognized to ack for object " << ObjectIdToString(object_id_);
+ (void)handle_found; // Silence unused variable warning in release builds.
+}
+
+// Erase the invalidation with matching ack handle from the list. Also creates
+// an 'UnknownVersion' invalidation with the same ack handle and places it at
+// the beginning of the list. If an unknown version invalidation currently
+// exists, it is replaced.
+void UnackedInvalidationSet::Drop(const AckHandle& handle) {
+ SingleObjectInvalidationSet::const_iterator it;
+ for (it = invalidations_.begin(); it != invalidations_.end(); ++it) {
+ if (it->ack_handle().Equals(handle)) {
+ break;
+ }
+ }
+ if (it == invalidations_.end()) {
+ DLOG(WARNING) << "Unrecognized drop request for object "
+ << ObjectIdToString(object_id_);
+ return;
+ }
+
+ Invalidation unknown_version = Invalidation::InitFromDroppedInvalidation(*it);
+ invalidations_.erase(*it);
+
+ // If an unknown version is in the list, we remove it so we can replace it.
+ if (!invalidations_.empty() && invalidations_.begin()->is_unknown_version()) {
+ invalidations_.erase(*invalidations_.begin());
+ }
+
+ invalidations_.insert(unknown_version);
+}
+
+scoped_ptr<base::DictionaryValue> UnackedInvalidationSet::ToValue() const {
+ scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue);
+ value->SetString(kSourceKey, base::IntToString(object_id_.source()));
+ value->SetString(kNameKey, object_id_.name());
+
+ scoped_ptr<base::ListValue> list_value(new base::ListValue);
+ for (InvalidationsSet::const_iterator it = invalidations_.begin();
+ it != invalidations_.end(); ++it) {
+ list_value->Append(it->ToValue().release());
+ }
+ value->Set(kInvalidationListKey, list_value.release());
+
+ return value.Pass();
+}
+
+bool UnackedInvalidationSet::ResetFromValue(
+ const base::DictionaryValue& value) {
+ std::string source_str;
+ if (!value.GetString(kSourceKey, &source_str)) {
+ DLOG(WARNING) << "Unable to deserialize source";
+ return false;
+ }
+ int source = 0;
+ if (!base::StringToInt(source_str, &source)) {
+ DLOG(WARNING) << "Invalid source: " << source_str;
+ return false;
+ }
+ std::string name;
+ if (!value.GetString(kNameKey, &name)) {
+ DLOG(WARNING) << "Unable to deserialize name";
+ return false;
+ }
+ object_id_ = invalidation::ObjectId(source, name);
+ const base::ListValue* invalidation_list = NULL;
+ if (!value.GetList(kInvalidationListKey, &invalidation_list)
+ || !ResetListFromValue(*invalidation_list)) {
+ // Earlier versions of this class did not set this field, so we don't treat
+ // parsing errors here as a fatal failure.
+ DLOG(WARNING) << "Unable to deserialize invalidation list.";
+ }
+ return true;
+}
+
+bool UnackedInvalidationSet::ResetListFromValue(
+ const base::ListValue& list) {
+ for (size_t i = 0; i < list.GetSize(); ++i) {
+ const base::DictionaryValue* dict;
+ if (!list.GetDictionary(i, &dict)) {
+ DLOG(WARNING) << "Failed to get invalidation dictionary at index " << i;
+ return false;
+ }
+ scoped_ptr<Invalidation> invalidation = Invalidation::InitFromValue(*dict);
+ if (!invalidation) {
+ DLOG(WARNING) << "Failed to parse invalidation at index " << i;
+ return false;
+ }
+ invalidations_.insert(*invalidation.get());
+ }
+ return true;
+}
+
+void UnackedInvalidationSet::Truncate(size_t max_size) {
+ DCHECK_GT(max_size, 0U);
+
+ if (invalidations_.size() <= max_size) {
+ return;
+ }
+
+ while (invalidations_.size() > max_size) {
+ invalidations_.erase(*invalidations_.begin());
+ }
+
+ // We dropped some invalidations. We remember the fact that an unknown
+ // amount of information has been lost by ensuring this list begins with
+ // an UnknownVersion invalidation. We remove the oldest remaining
+ // invalidation to make room for it.
+ invalidation::ObjectId id = invalidations_.begin()->object_id();
+ invalidations_.erase(*invalidations_.begin());
+
+ Invalidation unknown_version = Invalidation::InitUnknownVersion(id);
+ invalidations_.insert(unknown_version);
+}
+
+} // namespace syncer