1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "chrome/browser/sync_file_system/drive_backend_v1/remote_change_handler.h" 6 7 #include "base/logging.h" 8 #include "webkit/common/fileapi/file_system_util.h" 9 10 namespace sync_file_system { 11 12 RemoteChangeHandler::ChangeQueueItem::ChangeQueueItem() 13 : changestamp(0) {} 14 15 RemoteChangeHandler::ChangeQueueItem::ChangeQueueItem( 16 int64 changestamp, 17 const fileapi::FileSystemURL& url) 18 : changestamp(changestamp), url(url) {} 19 20 bool RemoteChangeHandler::ChangeQueueComparator::operator()( 21 const ChangeQueueItem& left, 22 const ChangeQueueItem& right) { 23 if (left.changestamp != right.changestamp) 24 return left.changestamp < right.changestamp; 25 return fileapi::FileSystemURL::Comparator()(left.url, right.url); 26 } 27 28 RemoteChangeHandler::RemoteChange::RemoteChange() 29 : changestamp(0), 30 change(FileChange::FILE_CHANGE_ADD_OR_UPDATE, SYNC_FILE_TYPE_UNKNOWN) {} 31 32 RemoteChangeHandler::RemoteChange::RemoteChange( 33 int64 changestamp, 34 const std::string& resource_id, 35 const std::string& md5_checksum, 36 const base::Time& updated_time, 37 const fileapi::FileSystemURL& url, 38 const FileChange& change) 39 : changestamp(changestamp), 40 resource_id(resource_id), 41 md5_checksum(md5_checksum), 42 updated_time(updated_time), 43 url(url), 44 change(change) {} 45 46 RemoteChangeHandler::RemoteChange::~RemoteChange() {} 47 48 bool RemoteChangeHandler::RemoteChangeComparator::operator()( 49 const RemoteChange& left, 50 const RemoteChange& right) { 51 // This should return true if |right| has higher priority than |left|. 52 // Smaller changestamps have higher priorities (i.e. need to be processed 53 // earlier). 54 if (left.changestamp != right.changestamp) 55 return left.changestamp > right.changestamp; 56 return false; 57 } 58 59 RemoteChangeHandler::RemoteChangeHandler() {} 60 61 RemoteChangeHandler::~RemoteChangeHandler() {} 62 63 bool RemoteChangeHandler::GetChange(RemoteChange* remote_change) { 64 const fileapi::FileSystemURL& url = changes_.begin()->url; 65 const base::FilePath::StringType& normalized_path = 66 fileapi::VirtualPath::GetNormalizedFilePath(url.path()); 67 DCHECK(ContainsKey(origin_to_changes_map_, url.origin())); 68 PathToChangeMap* path_to_change = &origin_to_changes_map_[url.origin()]; 69 DCHECK(ContainsKey(*path_to_change, normalized_path)); 70 *remote_change = (*path_to_change)[normalized_path].remote_change; 71 return true; 72 } 73 74 bool RemoteChangeHandler::GetChangeForURL( 75 const fileapi::FileSystemURL& url, 76 RemoteChange* remote_change) { 77 OriginToChangesMap::iterator found_origin = 78 origin_to_changes_map_.find(url.origin()); 79 if (found_origin == origin_to_changes_map_.end()) 80 return false; 81 82 PathToChangeMap* path_to_change = &found_origin->second; 83 PathToChangeMap::iterator found_change = path_to_change->find( 84 fileapi::VirtualPath::GetNormalizedFilePath(url.path())); 85 if (found_change == path_to_change->end()) 86 return false; 87 88 *remote_change = found_change->second.remote_change; 89 return true; 90 } 91 92 void RemoteChangeHandler::AppendChange(const RemoteChange& remote_change) { 93 base::FilePath::StringType normalized_path = 94 fileapi::VirtualPath::GetNormalizedFilePath(remote_change.url.path()); 95 96 PathToChangeMap* path_to_change = 97 &origin_to_changes_map_[remote_change.url.origin()]; 98 PathToChangeMap::iterator found = path_to_change->find(normalized_path); 99 100 // Remove an existing change for |remote_change.url.path()|. 101 if (found != path_to_change->end()) 102 changes_.erase(found->second.position_in_queue); 103 104 std::pair<PendingChangeQueue::iterator, bool> inserted_to_queue = 105 changes_.insert(ChangeQueueItem(remote_change.changestamp, 106 remote_change.url)); 107 DCHECK(inserted_to_queue.second); 108 109 (*path_to_change)[normalized_path] = 110 ChangeMapItem(remote_change, inserted_to_queue.first); 111 } 112 113 bool RemoteChangeHandler::RemoveChangeForURL( 114 const fileapi::FileSystemURL& url) { 115 OriginToChangesMap::iterator found_origin = 116 origin_to_changes_map_.find(url.origin()); 117 if (found_origin == origin_to_changes_map_.end()) 118 return false; 119 120 PathToChangeMap* path_to_change = &found_origin->second; 121 PathToChangeMap::iterator found_change = path_to_change->find( 122 fileapi::VirtualPath::GetNormalizedFilePath(url.path())); 123 if (found_change == path_to_change->end()) 124 return false; 125 126 changes_.erase(found_change->second.position_in_queue); 127 path_to_change->erase(found_change); 128 if (path_to_change->empty()) 129 origin_to_changes_map_.erase(found_origin); 130 return true; 131 } 132 133 void RemoteChangeHandler::RemoveChangesForOrigin(const GURL& origin) { 134 OriginToChangesMap::iterator found = origin_to_changes_map_.find(origin); 135 if (found == origin_to_changes_map_.end()) 136 return; 137 for (PathToChangeMap::iterator itr = found->second.begin(); 138 itr != found->second.end(); ++itr) 139 changes_.erase(itr->second.position_in_queue); 140 origin_to_changes_map_.erase(found); 141 } 142 143 bool RemoteChangeHandler::HasChangesForOrigin(const GURL& origin) const { 144 return ContainsKey(origin_to_changes_map_, origin); 145 } 146 147 RemoteChangeHandler::ChangeMapItem::ChangeMapItem() {} 148 149 RemoteChangeHandler::ChangeMapItem::ChangeMapItem( 150 const RemoteChange& remote_change, 151 PendingChangeQueue::iterator position_in_queue) 152 : remote_change(remote_change), 153 position_in_queue(position_in_queue) {} 154 155 RemoteChangeHandler::ChangeMapItem::~ChangeMapItem() {} 156 157 } // namespace sync_file_system 158