Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(874)

Unified Diff: sync/notifier/unacked_invalidation_storage.cc

Issue 23754021: Invalidation trickles mega-patch (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: sync/notifier/unacked_invalidation_storage.cc
diff --git a/sync/notifier/unacked_invalidation_storage.cc b/sync/notifier/unacked_invalidation_storage.cc
new file mode 100644
index 0000000000000000000000000000000000000000..33c6cda7384caf9d6a028f784457fe3ead3942a3
--- /dev/null
+++ b/sync/notifier/unacked_invalidation_storage.cc
@@ -0,0 +1,198 @@
+// Copyright 2013 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 "sync/notifier/unacked_invalidation_storage.h"
+
+#include "base/strings/string_number_conversions.h"
+#include "sync/internal_api/public/base/ack_handle.h"
+#include "sync/notifier/object_id_invalidation_map.h"
+#include "sync/notifier/ordered_invalidation_list.h"
+#include "sync/notifier/sync_invalidation_listener.h"
+
+namespace {
+
+const char kSourceKey[] = "source";
+const char kNameKey[] = "name";
+const char kInvalidationListKey[] = "invalidation-list";
+
+const size_t kBufferSize =
+ syncer::SyncInvalidationListener::kMaxBufferedInvalidations;
+
+} // namespace
+
+namespace syncer {
+
+// static
+UnackedInvalidationStorage::UnackedInvalidationStorage(
+ invalidation::ObjectId id)
+ : registered_(false),
+ object_id_(id) {}
+
+UnackedInvalidationStorage::~UnackedInvalidationStorage() {}
+
+void UnackedInvalidationStorage::RecordInvalidation(
+ const Invalidation& invalidation) {
+ OrderedInvalidationList list;
+ list.Insert(invalidation);
+ RecordInvalidations(list);
+}
+
+void UnackedInvalidationStorage::RecordInvalidations(
+ const OrderedInvalidationList& invalidations) {
+ invalidations_.insert(invalidations.begin(), invalidations.end());
+ Truncate(kBufferSize);
+}
+
+void UnackedInvalidationStorage::UnpackRecordedInvalidations(
+ ObjectIdInvalidationMap* out,
+ WeakHandle<AckHandler> ack_handler) const {
+ for (OrderedInvalidationList::const_iterator it = invalidations_.begin();
+ it != invalidations_.end(); ++it) {
+ Invalidation inv(*it);
+ inv.SetAckHandler(ack_handler);
+ out->Insert(inv);
+ }
+}
+
+void UnackedInvalidationStorage::Clear() {
+ invalidations_.clear();
+}
+
+void UnackedInvalidationStorage::SetIsRegistered() {
+ registered_ = true;
+}
+
+void UnackedInvalidationStorage::UnsetIsRegistered() {
+ registered_ = false;
+ Clear();
+}
+
+// Removes the matching ack handle from the list.
+void UnackedInvalidationStorage::Acknowledge(const AckHandle& handle) {
+ bool handle_found = false;
+ for (OrderedInvalidationList::const_iterator it = invalidations_.begin();
+ it != invalidations_.end(); ++it) {
+ if (it->GetAckHandle().Equals(handle)) {
+ invalidations_.erase(it);
+ handle_found = true;
+ break;
+ }
+ }
+ DLOG_IF(WARNING, !handle_found)
+ << "Unrecognized to ack for object " << ObjectIdToString(object_id_);
+}
+
+// Erases 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 UnackedInvalidationStorage::Drop(const AckHandle& handle) {
+ OrderedInvalidationList::const_iterator it;
+ for (it = invalidations_.begin(); it != invalidations_.end(); ++it) {
+ if (it->GetAckHandle().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()->IsUnknownVersion()) {
+ invalidations_.erase(invalidations_.begin());
+ }
+
+ invalidations_.insert(unknown_version);
+}
+
+scoped_ptr<base::DictionaryValue> UnackedInvalidationStorage::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 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 UnackedInvalidationStorage::ResetListFromValue(
+ const base::ListValue& list) {
+ for (size_t i = 0; i < list.GetSize(); ++i) {
+ Invalidation invalidation;
+ const base::DictionaryValue* dict;
+ if (!list.GetDictionary(i, &dict) || !invalidation.ResetFromValue(*dict)) {
+ DLOG(WARNING) << "Failed to parse invalidation at index " << i;
+ return false;
+ }
+ invalidations_.insert(invalidation);
+ }
+ return true;
+}
+
+bool UnackedInvalidationStorage::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;
+}
+
+const invalidation::ObjectId& UnackedInvalidationStorage::GetObjectId() const {
+ return object_id_;
+}
+
+void UnackedInvalidationStorage::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()->GetObjectId();
+ invalidations_.erase(invalidations_.begin());
+
+ Invalidation unknown_version = Invalidation::InitUnknownVersion(id);
+ invalidations_.insert(unknown_version);
+}
+
+} // namespace syncer
« no previous file with comments | « sync/notifier/unacked_invalidation_storage.h ('k') | sync/notifier/unacked_invalidation_storage_test_util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698