diff options
author | rlarocque@chromium.org <rlarocque@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-07-17 19:28:46 +0000 |
---|---|---|
committer | rlarocque@chromium.org <rlarocque@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-07-17 19:28:46 +0000 |
commit | 001bbfdc4da9f8aec8e1a30770a1e4cef2347e0a (patch) | |
tree | 1017f4628ef475caaf86573c9c8ec2e7aa341997 /components/invalidation/unacked_invalidation_set.cc | |
parent | cb363e702cb70f99c707be975e57015b438eaef0 (diff) | |
download | chromium_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.cc | 210 |
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 |