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

Unified Diff: chrome/browser/sync/engine/syncapi.cc

Issue 7033043: [Sync] Speed up sync node browser/search in about:sync (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address comments Created 9 years, 7 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
« no previous file with comments | « chrome/browser/sync/engine/syncapi.h ('k') | chrome/browser/sync/engine/syncapi_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/sync/engine/syncapi.cc
diff --git a/chrome/browser/sync/engine/syncapi.cc b/chrome/browser/sync/engine/syncapi.cc
index 37f56ab32b354d687300b1c301fdda31de41a394..5b3ba21b6e078aebd92299f2814edc63cf204023 100644
--- a/chrome/browser/sync/engine/syncapi.cc
+++ b/chrome/browser/sync/engine/syncapi.cc
@@ -8,11 +8,14 @@
#include <bitset>
#include <iomanip>
#include <list>
+#include <map>
#include <queue>
#include <string>
#include <vector>
#include "base/base64.h"
+#include "base/bind.h"
+#include "base/callback.h"
#include "base/command_line.h"
#include "base/json/json_writer.h"
#include "base/logging.h"
@@ -330,17 +333,22 @@ int64 BaseNode::GetFirstChildId() const {
return IdToMetahandle(GetTransaction()->GetWrappedTrans(), id_string);
}
-DictionaryValue* BaseNode::ToValue() const {
+DictionaryValue* BaseNode::GetSummaryAsValue() const {
DictionaryValue* node_info = new DictionaryValue();
node_info->SetString("id", base::Int64ToString(GetId()));
- // TODO(akalin): Return time in a better format.
- node_info->SetString("modificationTime",
- base::Int64ToString(GetModificationTime()));
- node_info->SetString("parentId", base::Int64ToString(GetParentId()));
node_info->SetBoolean("isFolder", GetIsFolder());
// TODO(akalin): Add a std::string accessor for the title.
node_info->SetString("title", WideToUTF8(GetTitle()));
node_info->Set("type", ModelTypeToValue(GetModelType()));
+ return node_info;
+}
+
+DictionaryValue* BaseNode::GetDetailsAsValue() const {
+ DictionaryValue* node_info = GetSummaryAsValue();
+ // TODO(akalin): Return time in a better format.
+ node_info->SetString("modificationTime",
+ base::Int64ToString(GetModificationTime()));
+ node_info->SetString("parentId", base::Int64ToString(GetParentId()));
// Specifics are already in the Entry value, so no need to duplicate
// it here.
node_info->SetString("externalId",
@@ -1101,7 +1109,7 @@ DictionaryValue* SyncManager::ChangeRecord::ToValue(
} else {
ReadNode node(trans);
if (node.InitByIdLookup(id)) {
- node_value = node.ToValue();
+ node_value = node.GetDetailsAsValue();
}
}
if (!node_value) {
@@ -1112,34 +1120,6 @@ DictionaryValue* SyncManager::ChangeRecord::ToValue(
return value;
}
-bool BaseNode::ContainsString(const std::string& lowercase_query) const {
- DCHECK(GetEntry());
- // TODO(lipalani) - figure out what to do if the node is encrypted.
- const sync_pb::EntitySpecifics& specifics = GetEntry()->Get(SPECIFICS);
- std::string temp;
- // The protobuf serialized string contains the original strings. So
- // we will just serialize it and search it.
- specifics.SerializeToString(&temp);
-
- // Now convert to lower case.
- StringToLowerASCII(&temp);
-
- if (temp.find(lowercase_query) != std::string::npos)
- return true;
-
- // Now go through all the string fields to see if the value is there.
- for (int i = syncable::STRING_FIELDS_BEGIN; i < syncable::STRING_FIELDS_END;
- ++i) {
- std::string value = GetEntry()->Get(
- static_cast<syncable::StringField>(i));
-
- StringToLowerASCII(&value);
- if (value.find(lowercase_query) != std::string::npos)
- return true;
- }
- return false;
-}
-
SyncManager::ExtraPasswordChangeRecordData::ExtraPasswordChangeRecordData() {}
SyncManager::ExtraPasswordChangeRecordData::ExtraPasswordChangeRecordData(
@@ -1224,6 +1204,29 @@ class SyncManager::SyncInternal
notification_info_map_.insert(
std::make_pair(syncable::ModelTypeFromInt(i), NotificationInfo()));
}
+
lipalani1 2011/06/02 23:06:39 This list does not seem to change. So is it possib
akalin 2011/06/02 23:14:58 As we discussed, C++ isn't expressive enough to do
+ // Bind message handlers.
+ BindJsMessageHandler(
+ "getNotificationState",
+ &SyncManager::SyncInternal::GetNotificationState);
+ BindJsMessageHandler(
+ "getNotificationInfo",
+ &SyncManager::SyncInternal::GetNotificationInfo);
+ BindJsMessageHandler(
+ "getRootNodeDetails",
+ &SyncManager::SyncInternal::GetRootNodeDetails);
+ BindJsMessageHandler(
+ "getNodeSummariesById",
+ &SyncManager::SyncInternal::GetNodeSummariesById);
+ BindJsMessageHandler(
+ "getNodeDetailsById",
+ &SyncManager::SyncInternal::GetNodeDetailsById);
+ BindJsMessageHandler(
+ "getChildNodeIds",
+ &SyncManager::SyncInternal::GetChildNodeIds);
+ BindJsMessageHandler(
+ "findNodesContainingString",
+ &SyncManager::SyncInternal::FindNodesContainingString);
}
virtual ~SyncInternal() {
@@ -1442,9 +1445,14 @@ class SyncManager::SyncInternal
const browser_sync::JsArgList& args,
const browser_sync::JsEventHandler* target) OVERRIDE;
- ListValue* FindNodesContainingString(const std::string& query);
-
private:
+ typedef browser_sync::JsArgList
+ (SyncManager::SyncInternal::*UnboundJsMessageHandler)(
+ const browser_sync::JsArgList&);
+ typedef base::Callback<browser_sync::JsArgList(browser_sync::JsArgList)>
+ JsMessageHandler;
+ typedef std::map<std::string, JsMessageHandler> JsMessageHandlerMap;
+
// Helper to call OnAuthError when no authentication credentials are
// available.
void RaiseAuthNeededEvent();
@@ -1556,14 +1564,31 @@ class SyncManager::SyncInternal
// Checks for server reachabilty and requests a nudge.
void OnIPAddressChangedImpl();
- // Functions called by ProcessMessage().
- browser_sync::JsArgList ProcessGetNodesByIdMessage(
+ // Helper function used only by the constructor.
+ void BindJsMessageHandler(
+ const std::string& name,
+ UnboundJsMessageHandler unbound_message_handler);
+
+ // JS message handlers.
+ browser_sync::JsArgList GetNotificationState(
const browser_sync::JsArgList& args);
- browser_sync::JsArgList ProcessGetChildNodeIdsMessage(
+ browser_sync::JsArgList GetNotificationInfo(
const browser_sync::JsArgList& args);
- browser_sync::JsArgList ProcessFindNodesContainingString(
+ browser_sync::JsArgList GetRootNodeDetails(
+ const browser_sync::JsArgList& args);
+
+ browser_sync::JsArgList GetNodeSummariesById(
+ const browser_sync::JsArgList& args);
+
+ browser_sync::JsArgList GetNodeDetailsById(
+ const browser_sync::JsArgList& args);
+
+ browser_sync::JsArgList GetChildNodeIds(
+ const browser_sync::JsArgList& args);
+
+ browser_sync::JsArgList FindNodesContainingString(
const browser_sync::JsArgList& args);
// We couple the DirectoryManager and username together in a UserShare member
@@ -1628,6 +1653,8 @@ class SyncManager::SyncInternal
NotificationInfoMap notification_info_map_;
browser_sync::JsDirectoryChangeListener js_directory_change_listener_;
+
+ JsMessageHandlerMap js_message_handlers_;
};
const int SyncManager::SyncInternal::kDefaultNudgeDelayMilliseconds = 200;
const int SyncManager::SyncInternal::kPreferencesNudgeDelayMilliseconds = 2000;
@@ -2126,52 +2153,6 @@ void SyncManager::SyncInternal::EncryptDataTypes(
return;
}
-namespace {
-
-void FindChildNodesContainingString(const std::string& lowercase_query,
- const ReadNode& parent_node,
- sync_api::ReadTransaction* trans,
- ListValue* result) {
- int64 child_id = parent_node.GetFirstChildId();
- while (child_id != kInvalidId) {
- ReadNode node(trans);
- if (node.InitByIdLookup(child_id)) {
- if (node.ContainsString(lowercase_query)) {
- result->Append(new StringValue(base::Int64ToString(child_id)));
- }
- FindChildNodesContainingString(lowercase_query, node, trans, result);
- child_id = node.GetSuccessorId();
- } else {
- LOG(WARNING) << "Lookup of node failed. Id: " << child_id;
- return;
- }
- }
-}
-} // namespace
-
-// Returned pointer owned by the caller.
-ListValue* SyncManager::SyncInternal::FindNodesContainingString(
- const std::string& query) {
- // Convert the query string to lower case to perform case insensitive
- // searches.
- std::string lowercase_query = query;
- StringToLowerASCII(&lowercase_query);
- ReadTransaction trans(GetUserShare());
- ReadNode root(&trans);
- root.InitByRootLookup();
-
- ListValue* result = new ListValue();
-
- base::Time start_time = base::Time::Now();
- FindChildNodesContainingString(lowercase_query, root, &trans, result);
- base::Time end_time = base::Time::Now();
-
- base::TimeDelta delta = end_time - start_time;
- VLOG(1) << "Time taken in milliseconds to search " << delta.InMilliseconds();
-
- return result;
-}
-
void SyncManager::SyncInternal::ReEncryptEverything(WriteTransaction* trans) {
syncable::ModelTypeSet encrypted_types =
GetEncryptedDataTypes(trans->GetWrappedTrans());
@@ -2685,77 +2666,25 @@ const browser_sync::JsEventRouter*
return parent_router_;
}
-namespace {
-
-void LogNoRouter(const std::string& name,
- const browser_sync::JsArgList& args) {
- VLOG(1) << "No parent router; not replying to message " << name
- << " with args " << args.ToString();
-}
-
-} // namespace
-
void SyncManager::SyncInternal::ProcessMessage(
const std::string& name, const browser_sync::JsArgList& args,
const browser_sync::JsEventHandler* sender) {
DCHECK(initialized_);
- if (name == "getNotificationState") {
- if (!parent_router_) {
- LogNoRouter(name, args);
- return;
- }
- bool notifications_enabled = allstatus_.status().notifications_enabled;
- ListValue return_args;
- return_args.Append(Value::CreateBooleanValue(notifications_enabled));
- parent_router_->RouteJsMessageReply(
- name, browser_sync::JsArgList(&return_args), sender);
- } else if (name == "getNotificationInfo") {
- if (!parent_router_) {
- LogNoRouter(name, args);
- return;
- }
+ if (!parent_router_) {
+ VLOG(1) << "No parent router; not replying to message " << name
+ << " with args " << args.ToString();
+ return;
+ }
- ListValue return_args;
- return_args.Append(NotificationInfoToValue(notification_info_map_));
- parent_router_->RouteJsMessageReply(
- name, browser_sync::JsArgList(&return_args), sender);
- } else if (name == "getRootNode") {
- if (!parent_router_) {
- LogNoRouter(name, args);
- return;
- }
- ReadTransaction trans(GetUserShare());
- ReadNode root(&trans);
- root.InitByRootLookup();
- ListValue return_args;
- return_args.Append(root.ToValue());
- parent_router_->RouteJsMessageReply(
- name, browser_sync::JsArgList(&return_args), sender);
- } else if (name == "getNodesById") {
- if (!parent_router_) {
- LogNoRouter(name, args);
- return;
- }
- parent_router_->RouteJsMessageReply(
- name, ProcessGetNodesByIdMessage(args), sender);
- } else if (name == "getChildNodeIds") {
- if (!parent_router_) {
- LogNoRouter(name, args);
- return;
- }
- parent_router_->RouteJsMessageReply(
- name, ProcessGetChildNodeIdsMessage(args), sender);
- } else if (name == "findNodesContainingString") {
- if (!parent_router_) {
- LogNoRouter(name, args);
- return;
- }
- parent_router_->RouteJsMessageReply(
- name, ProcessFindNodesContainingString(args), sender);
- } else {
+ JsMessageHandler js_message_handler = js_message_handlers_[name];
+ if (js_message_handler.is_null()) {
VLOG(1) << "Dropping unknown message " << name
<< " with args " << args.ToString();
+ return;
}
+
+ parent_router_->RouteJsMessageReply(
+ name, js_message_handler.Run(args), sender);
}
void SyncManager::SyncInternal::RouteJsEvent(
@@ -2777,76 +2706,120 @@ void SyncManager::SyncInternal::RouteJsMessageReply(
parent_router_->RouteJsMessageReply(name, args, target);
}
+void SyncManager::SyncInternal::BindJsMessageHandler(
+ const std::string& name,
+ UnboundJsMessageHandler unbound_message_handler) {
+ js_message_handlers_[name] =
+ base::Bind(unbound_message_handler, base::Unretained(this));
+}
+
+browser_sync::JsArgList
+ SyncManager::SyncInternal::GetNotificationState(
+ const browser_sync::JsArgList& args) {
+ bool notifications_enabled = allstatus_.status().notifications_enabled;
+ ListValue return_args;
+ return_args.Append(Value::CreateBooleanValue(notifications_enabled));
+ return browser_sync::JsArgList(&return_args);
+}
+
+browser_sync::JsArgList
+ SyncManager::SyncInternal::GetNotificationInfo(
+ const browser_sync::JsArgList& args) {
+ ListValue return_args;
+ return_args.Append(NotificationInfoToValue(notification_info_map_));
+ return browser_sync::JsArgList(&return_args);
+}
+
+browser_sync::JsArgList
+ SyncManager::SyncInternal::GetRootNodeDetails(
+ const browser_sync::JsArgList& args) {
+ ReadTransaction trans(GetUserShare());
+ ReadNode root(&trans);
+ root.InitByRootLookup();
+ ListValue return_args;
+ return_args.Append(root.GetDetailsAsValue());
+ return browser_sync::JsArgList(&return_args);
+}
+
namespace {
-bool GetId(const ListValue& ids, int i, int64* id) {
+int64 GetId(const ListValue& ids, int i) {
std::string id_str;
if (!ids.GetString(i, &id_str)) {
- return false;
- }
- if (!base::StringToInt64(id_str, id)) {
- return false;
+ return kInvalidId;
}
- if (*id == kInvalidId) {
- return false;
+ int64 id = kInvalidId;
+ if (!base::StringToInt64(id_str, &id)) {
+ return kInvalidId;
}
- return true;
+ return id;
}
-} // namespace
-
-browser_sync::JsArgList SyncManager::SyncInternal::ProcessGetNodesByIdMessage(
- const browser_sync::JsArgList& args) {
+browser_sync::JsArgList GetNodeInfoById(
+ const browser_sync::JsArgList& args,
+ UserShare* user_share,
+ DictionaryValue* (BaseNode::*info_getter)() const) {
+ CHECK(info_getter);
ListValue return_args;
- ListValue* nodes = new ListValue();
- return_args.Append(nodes);
+ ListValue* node_summaries = new ListValue();
+ return_args.Append(node_summaries);
ListValue* id_list = NULL;
- ReadTransaction trans(GetUserShare());
+ ReadTransaction trans(user_share);
if (args.Get().GetList(0, &id_list)) {
+ CHECK(id_list);
for (size_t i = 0; i < id_list->GetSize(); ++i) {
- int64 id = kInvalidId;
- if (!GetId(*id_list, i, &id)) {
+ int64 id = GetId(*id_list, i);
+ if (id == kInvalidId) {
continue;
}
ReadNode node(&trans);
if (!node.InitByIdLookup(id)) {
continue;
}
- nodes->Append(node.ToValue());
+ node_summaries->Append((node.*info_getter)());
}
}
return browser_sync::JsArgList(&return_args);
}
+} // namespace
+
+browser_sync::JsArgList
+ SyncManager::SyncInternal::GetNodeSummariesById(
+ const browser_sync::JsArgList& args) {
+ return GetNodeInfoById(args, GetUserShare(), &BaseNode::GetSummaryAsValue);
+}
+
+browser_sync::JsArgList
+ SyncManager::SyncInternal::GetNodeDetailsById(
+ const browser_sync::JsArgList& args) {
+ return GetNodeInfoById(args, GetUserShare(), &BaseNode::GetDetailsAsValue);
+}
+
browser_sync::JsArgList SyncManager::SyncInternal::
- ProcessGetChildNodeIdsMessage(
+ GetChildNodeIds(
const browser_sync::JsArgList& args) {
ListValue return_args;
ListValue* child_ids = new ListValue();
return_args.Append(child_ids);
- int64 id = kInvalidId;
- if (GetId(args.Get(), 0, &id)) {
+ int64 id = GetId(args.Get(), 0);
+ if (id != kInvalidId) {
ReadTransaction trans(GetUserShare());
- ReadNode node(&trans);
- if (node.InitByIdLookup(id)) {
- int64 child_id = node.GetFirstChildId();
- while (child_id != kInvalidId) {
- ReadNode child_node(&trans);
- if (!child_node.InitByIdLookup(child_id)) {
- break;
- }
- child_ids->Append(Value::CreateStringValue(
- base::Int64ToString(child_id)));
- child_id = child_node.GetSuccessorId();
- }
+ syncable::Directory::ChildHandles child_handles;
+ trans.GetLookup()->GetChildHandlesByHandle(trans.GetWrappedTrans(),
+ id, &child_handles);
+ for (syncable::Directory::ChildHandles::const_iterator it =
+ child_handles.begin(); it != child_handles.end(); ++it) {
+ child_ids->Append(Value::CreateStringValue(
+ base::Int64ToString(*it)));
}
}
return browser_sync::JsArgList(&return_args);
}
browser_sync::JsArgList SyncManager::SyncInternal::
- ProcessFindNodesContainingString(
- const browser_sync::JsArgList& args) {
+ FindNodesContainingString(
+ const browser_sync::JsArgList& args) {
std::string query;
ListValue return_args;
if (!args.Get().GetString(0, &query)) {
@@ -2854,8 +2827,27 @@ browser_sync::JsArgList SyncManager::SyncInternal::
return browser_sync::JsArgList(&return_args);
}
- ListValue* result = FindNodesContainingString(query);
+ // Convert the query string to lower case to perform case insensitive
+ // searches.
+ std::string lowercase_query = query;
+ StringToLowerASCII(&lowercase_query);
+
+ ListValue* result = new ListValue();
return_args.Append(result);
+
+ ReadTransaction trans(GetUserShare());
+ std::vector<const syncable::EntryKernel*> entry_kernels;
+ trans.GetLookup()->GetAllEntryKernels(trans.GetWrappedTrans(),
+ &entry_kernels);
+
+ for (std::vector<const syncable::EntryKernel*>::const_iterator it =
+ entry_kernels.begin(); it != entry_kernels.end(); ++it) {
+ if ((*it)->ContainsString(lowercase_query)) {
+ result->Append(new StringValue(base::Int64ToString(
+ (*it)->ref(syncable::META_HANDLE))));
+ }
+ }
+
return browser_sync::JsArgList(&return_args);
}
@@ -3002,7 +2994,7 @@ void SyncManager::LogUnsyncedItems(int level) const {
it != unsynced_handles.end(); ++it) {
ReadNode node(&trans);
if (node.InitByIdLookup(*it)) {
- scoped_ptr<DictionaryValue> value(node.ToValue());
+ scoped_ptr<DictionaryValue> value(node.GetDetailsAsValue());
std::string info;
base::JSONWriter::Write(value.get(), true, &info);
VLOG(level) << info;
« no previous file with comments | « chrome/browser/sync/engine/syncapi.h ('k') | chrome/browser/sync/engine/syncapi_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698