// 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 "chrome/browser/sync_file_system/remote_change_handler.h" #include "base/logging.h" #include "webkit/common/fileapi/file_system_util.h" namespace sync_file_system { RemoteChangeHandler::ChangeQueueItem::ChangeQueueItem() : changestamp(0) {} RemoteChangeHandler::ChangeQueueItem::ChangeQueueItem( int64 changestamp, const fileapi::FileSystemURL& url) : changestamp(changestamp), url(url) {} bool RemoteChangeHandler::ChangeQueueComparator::operator()( const ChangeQueueItem& left, const ChangeQueueItem& right) { if (left.changestamp != right.changestamp) return left.changestamp < right.changestamp; return fileapi::FileSystemURL::Comparator()(left.url, right.url); } RemoteChangeHandler::RemoteChange::RemoteChange() : changestamp(0), change(FileChange::FILE_CHANGE_ADD_OR_UPDATE, SYNC_FILE_TYPE_UNKNOWN) {} RemoteChangeHandler::RemoteChange::RemoteChange( int64 changestamp, const std::string& resource_id, const std::string& md5_checksum, const base::Time& updated_time, const fileapi::FileSystemURL& url, const FileChange& change) : changestamp(changestamp), resource_id(resource_id), md5_checksum(md5_checksum), updated_time(updated_time), url(url), change(change) {} RemoteChangeHandler::RemoteChange::~RemoteChange() {} bool RemoteChangeHandler::RemoteChangeComparator::operator()( const RemoteChange& left, const RemoteChange& right) { // This should return true if |right| has higher priority than |left|. // Smaller changestamps have higher priorities (i.e. need to be processed // earlier). if (left.changestamp != right.changestamp) return left.changestamp > right.changestamp; return false; } RemoteChangeHandler::RemoteChangeHandler() {} RemoteChangeHandler::~RemoteChangeHandler() {} bool RemoteChangeHandler::GetChange(RemoteChange* remote_change) { const fileapi::FileSystemURL& url = changes_.begin()->url; const base::FilePath::StringType& normalized_path = fileapi::VirtualPath::GetNormalizedFilePath(url.path()); DCHECK(ContainsKey(origin_to_changes_map_, url.origin())); PathToChangeMap* path_to_change = &origin_to_changes_map_[url.origin()]; DCHECK(ContainsKey(*path_to_change, normalized_path)); *remote_change = (*path_to_change)[normalized_path].remote_change; return true; } bool RemoteChangeHandler::GetChangeForURL( const fileapi::FileSystemURL& url, RemoteChange* remote_change) { OriginToChangesMap::iterator found_origin = origin_to_changes_map_.find(url.origin()); if (found_origin == origin_to_changes_map_.end()) return false; PathToChangeMap* path_to_change = &found_origin->second; PathToChangeMap::iterator found_change = path_to_change->find( fileapi::VirtualPath::GetNormalizedFilePath(url.path())); if (found_change == path_to_change->end()) return false; *remote_change = found_change->second.remote_change; return true; } void RemoteChangeHandler::AppendChange(const RemoteChange& remote_change) { base::FilePath::StringType normalized_path = fileapi::VirtualPath::GetNormalizedFilePath(remote_change.url.path()); PathToChangeMap* path_to_change = &origin_to_changes_map_[remote_change.url.origin()]; PathToChangeMap::iterator found = path_to_change->find(normalized_path); // Remove an existing change for |remote_change.url.path()|. if (found != path_to_change->end()) changes_.erase(found->second.position_in_queue); std::pair inserted_to_queue = changes_.insert(ChangeQueueItem(remote_change.changestamp, remote_change.url)); DCHECK(inserted_to_queue.second); (*path_to_change)[normalized_path] = ChangeMapItem(remote_change, inserted_to_queue.first); } bool RemoteChangeHandler::RemoveChangeForURL( const fileapi::FileSystemURL& url) { OriginToChangesMap::iterator found_origin = origin_to_changes_map_.find(url.origin()); if (found_origin == origin_to_changes_map_.end()) return false; PathToChangeMap* path_to_change = &found_origin->second; PathToChangeMap::iterator found_change = path_to_change->find( fileapi::VirtualPath::GetNormalizedFilePath(url.path())); if (found_change == path_to_change->end()) return false; changes_.erase(found_change->second.position_in_queue); path_to_change->erase(found_change); if (path_to_change->empty()) origin_to_changes_map_.erase(found_origin); return true; } void RemoteChangeHandler::RemoveChangesForOrigin(const GURL& origin) { OriginToChangesMap::iterator found = origin_to_changes_map_.find(origin); if (found == origin_to_changes_map_.end()) return; for (PathToChangeMap::iterator itr = found->second.begin(); itr != found->second.end(); ++itr) changes_.erase(itr->second.position_in_queue); origin_to_changes_map_.erase(found); } bool RemoteChangeHandler::HasChangesForOrigin(const GURL& origin) const { return ContainsKey(origin_to_changes_map_, origin); } RemoteChangeHandler::ChangeMapItem::ChangeMapItem() {} RemoteChangeHandler::ChangeMapItem::ChangeMapItem( const RemoteChange& remote_change, PendingChangeQueue::iterator position_in_queue) : remote_change(remote_change), position_in_queue(position_in_queue) {} RemoteChangeHandler::ChangeMapItem::~ChangeMapItem() {} } // namespace sync_file_system