blob: da9ac3bd8f7bdb8c26a0794ec0367fcf455302d0 [file] [log] [blame]
// 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/drive_backend_v1/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<PendingChangeQueue::iterator, bool> 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