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

Side by Side Diff: chrome/browser/bookmarks/bookmark_codec.cc

Issue 155560: Don't use ID generation logic always. Only reassign IDs... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 5 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/bookmarks/bookmark_codec.h" 5 #include "chrome/browser/bookmarks/bookmark_codec.h"
6 6
7 #include <algorithm>
8
7 #include "app/l10n_util.h" 9 #include "app/l10n_util.h"
8 #include "base/string_util.h" 10 #include "base/string_util.h"
9 #include "base/values.h" 11 #include "base/values.h"
10 #include "chrome/browser/bookmarks/bookmark_model.h" 12 #include "chrome/browser/bookmarks/bookmark_model.h"
11 #include "googleurl/src/gurl.h" 13 #include "googleurl/src/gurl.h"
12 #include "grit/generated_resources.h" 14 #include "grit/generated_resources.h"
13 15
14 using base::Time; 16 using base::Time;
15 17
16 UniqueIDGenerator::UniqueIDGenerator() {
17 Reset();
18 }
19
20 int64 UniqueIDGenerator::GetUniqueID(int64 id) {
21 // If the given ID is already assigned, generate new ID.
22 if (IsIdAssigned(id))
23 id = current_max_ + 1;
24
25 // Record the new ID as assigned.
26 RecordId(id);
27
28 if (id > current_max_)
29 current_max_ = id;
30
31 return id;
32 }
33
34 bool UniqueIDGenerator::IsIdAssigned(int64 id) const {
35 // If the set is already instantiated, then use the set to determine if the
36 // given ID is assigned. Otherwise use the current maximum to determine if the
37 // given ID is assigned.
38 if (assigned_ids_.get())
39 return assigned_ids_->find(id) != assigned_ids_->end();
40 else
41 return id <= current_max_;
42 }
43
44 void UniqueIDGenerator::RecordId(int64 id) {
45 // If the set is instantiated, then use the set.
46 if (assigned_ids_.get()) {
47 assigned_ids_->insert(id);
48 return;
49 }
50
51 // The set is not yet instantiated. If the ID is current_max_ + 1, then just
52 // update the current_max_. Otherwise, instantiate the set and add all IDs
53 // from 0 to current_max_ to it.
54 if (id == current_max_ + 1) {
55 ++current_max_;
56 return;
57 }
58 assigned_ids_.reset(new std::set<int64>);
59 for (int64 i = 0; i <= current_max_; ++i)
60 assigned_ids_->insert(i);
61 assigned_ids_->insert(id);
62 }
63
64 void UniqueIDGenerator::Reset() {
65 current_max_ = 0;
66 assigned_ids_.reset(NULL);
67 }
68
69 const wchar_t* BookmarkCodec::kRootsKey = L"roots"; 18 const wchar_t* BookmarkCodec::kRootsKey = L"roots";
70 const wchar_t* BookmarkCodec::kRootFolderNameKey = L"bookmark_bar"; 19 const wchar_t* BookmarkCodec::kRootFolderNameKey = L"bookmark_bar";
71 const wchar_t* BookmarkCodec::kOtherBookmarkFolderNameKey = L"other"; 20 const wchar_t* BookmarkCodec::kOtherBookmarkFolderNameKey = L"other";
72 const wchar_t* BookmarkCodec::kVersionKey = L"version"; 21 const wchar_t* BookmarkCodec::kVersionKey = L"version";
73 const wchar_t* BookmarkCodec::kChecksumKey = L"checksum"; 22 const wchar_t* BookmarkCodec::kChecksumKey = L"checksum";
74 const wchar_t* BookmarkCodec::kIdKey = L"id"; 23 const wchar_t* BookmarkCodec::kIdKey = L"id";
75 const wchar_t* BookmarkCodec::kTypeKey = L"type"; 24 const wchar_t* BookmarkCodec::kTypeKey = L"type";
76 const wchar_t* BookmarkCodec::kNameKey = L"name"; 25 const wchar_t* BookmarkCodec::kNameKey = L"name";
77 const wchar_t* BookmarkCodec::kDateAddedKey = L"date_added"; 26 const wchar_t* BookmarkCodec::kDateAddedKey = L"date_added";
78 const wchar_t* BookmarkCodec::kURLKey = L"url"; 27 const wchar_t* BookmarkCodec::kURLKey = L"url";
79 const wchar_t* BookmarkCodec::kDateModifiedKey = L"date_modified"; 28 const wchar_t* BookmarkCodec::kDateModifiedKey = L"date_modified";
80 const wchar_t* BookmarkCodec::kChildrenKey = L"children"; 29 const wchar_t* BookmarkCodec::kChildrenKey = L"children";
81 const wchar_t* BookmarkCodec::kTypeURL = L"url"; 30 const wchar_t* BookmarkCodec::kTypeURL = L"url";
82 const wchar_t* BookmarkCodec::kTypeFolder = L"folder"; 31 const wchar_t* BookmarkCodec::kTypeFolder = L"folder";
83 32
84 // Current version of the file. 33 // Current version of the file.
85 static const int kCurrentVersion = 1; 34 static const int kCurrentVersion = 1;
86 35
87 BookmarkCodec::BookmarkCodec() 36 BookmarkCodec::BookmarkCodec()
88 : ids_reassigned_(false) { 37 : ids_reassigned_(false),
38 ids_missing_(false),
39 maximum_id_(0) {
89 } 40 }
90 41
91 Value* BookmarkCodec::Encode(BookmarkModel* model) { 42 Value* BookmarkCodec::Encode(BookmarkModel* model) {
92 return Encode(model->GetBookmarkBarNode(), model->other_node()); 43 return Encode(model->GetBookmarkBarNode(), model->other_node());
93 } 44 }
94 45
95 Value* BookmarkCodec::Encode(const BookmarkNode* bookmark_bar_node, 46 Value* BookmarkCodec::Encode(const BookmarkNode* bookmark_bar_node,
96 const BookmarkNode* other_folder_node) { 47 const BookmarkNode* other_folder_node) {
97 ids_reassigned_ = false; 48 ids_reassigned_ = false;
98 InitializeChecksum(); 49 InitializeChecksum();
99 DictionaryValue* roots = new DictionaryValue(); 50 DictionaryValue* roots = new DictionaryValue();
100 roots->Set(kRootFolderNameKey, EncodeNode(bookmark_bar_node)); 51 roots->Set(kRootFolderNameKey, EncodeNode(bookmark_bar_node));
101 roots->Set(kOtherBookmarkFolderNameKey, EncodeNode(other_folder_node)); 52 roots->Set(kOtherBookmarkFolderNameKey, EncodeNode(other_folder_node));
102 53
103 DictionaryValue* main = new DictionaryValue(); 54 DictionaryValue* main = new DictionaryValue();
104 main->SetInteger(kVersionKey, kCurrentVersion); 55 main->SetInteger(kVersionKey, kCurrentVersion);
105 FinalizeChecksum(); 56 FinalizeChecksum();
106 // We are going to store the computed checksum. So set stored checksum to be 57 // We are going to store the computed checksum. So set stored checksum to be
107 // the same as computed checksum. 58 // the same as computed checksum.
108 stored_checksum_ = computed_checksum_; 59 stored_checksum_ = computed_checksum_;
109 main->Set(kChecksumKey, Value::CreateStringValue(computed_checksum_)); 60 main->Set(kChecksumKey, Value::CreateStringValue(computed_checksum_));
110 main->Set(kRootsKey, roots); 61 main->Set(kRootsKey, roots);
111 return main; 62 return main;
112 } 63 }
113 64
114 bool BookmarkCodec::Decode(BookmarkNode* bb_node, 65 bool BookmarkCodec::Decode(BookmarkNode* bb_node,
115 BookmarkNode* other_folder_node, 66 BookmarkNode* other_folder_node,
116 int64* max_id, 67 int64* max_id,
117 const Value& value) { 68 const Value& value) {
118 // TODO(munjal): Instead of paying the price of ID generator in al lcases, we
119 // should only pay the price if we detect the file has changed and do a second
120 // pass to reassign IDs. See issue 16357.
121 id_generator_.Reset();
122 ids_reassigned_ = false; 69 ids_reassigned_ = false;
70 ids_missing_ = false;
71 maximum_id_ = 0;
123 stored_checksum_.clear(); 72 stored_checksum_.clear();
124 InitializeChecksum(); 73 InitializeChecksum();
125 bool success = DecodeHelper(bb_node, other_folder_node, value); 74 bool success = DecodeHelper(bb_node, other_folder_node, value);
126 FinalizeChecksum(); 75 FinalizeChecksum();
127 *max_id = id_generator_.current_max() + 1; 76 // If either the checksums differ or some IDs were missing, reassign IDs.
77 if (ids_missing_ || computed_checksum() != stored_checksum())
78 ReassignIDs(bb_node, other_folder_node);
79 *max_id = maximum_id_ + 1;
128 return success; 80 return success;
129 } 81 }
130 82
131 Value* BookmarkCodec::EncodeNode(const BookmarkNode* node) { 83 Value* BookmarkCodec::EncodeNode(const BookmarkNode* node) {
132 DictionaryValue* value = new DictionaryValue(); 84 DictionaryValue* value = new DictionaryValue();
133 std::string id; 85 std::string id;
134 id = Int64ToString(node->id()); 86 id = Int64ToString(node->id());
135 value->SetString(kIdKey, id); 87 value->SetString(kIdKey, id);
136 const std::wstring& title = node->GetTitle(); 88 const std::wstring& title = node->GetTitle();
137 value->SetString(kNameKey, title); 89 value->SetString(kNameKey, title);
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 DecodeNode(*static_cast<DictionaryValue*>(child_value), parent, NULL); 175 DecodeNode(*static_cast<DictionaryValue*>(child_value), parent, NULL);
224 } 176 }
225 return true; 177 return true;
226 } 178 }
227 179
228 bool BookmarkCodec::DecodeNode(const DictionaryValue& value, 180 bool BookmarkCodec::DecodeNode(const DictionaryValue& value,
229 BookmarkNode* parent, 181 BookmarkNode* parent,
230 BookmarkNode* node) { 182 BookmarkNode* node) {
231 std::string id_string; 183 std::string id_string;
232 int64 id = 0; 184 int64 id = 0;
233 if (value.GetString(kIdKey, &id_string)) 185 if (!value.GetString(kIdKey, &id_string) || !StringToInt64(id_string, &id))
234 if (!StringToInt64(id_string, &id)) 186 ids_missing_ = true;
235 return false; 187
236 int64 new_id = id_generator_.GetUniqueID(id); 188 maximum_id_ = std::max(maximum_id_, id);
237 if (new_id != id)
238 ids_reassigned_ = true;
239 id = new_id;
240 189
241 std::wstring title; 190 std::wstring title;
242 if (!value.GetString(kNameKey, &title)) 191 value.GetString(kNameKey, &title);
243 title = std::wstring();
244 192
245 std::wstring date_added_string; 193 std::wstring date_added_string;
246 if (!value.GetString(kDateAddedKey, &date_added_string)) 194 if (!value.GetString(kDateAddedKey, &date_added_string))
247 date_added_string = Int64ToWString(Time::Now().ToInternalValue()); 195 date_added_string = Int64ToWString(Time::Now().ToInternalValue());
248 196
249 std::wstring type_string; 197 std::wstring type_string;
250 if (!value.GetString(kTypeKey, &type_string)) 198 if (!value.GetString(kTypeKey, &type_string))
251 return false; 199 return false;
252 200
253 if (type_string != kTypeURL && type_string != kTypeFolder) 201 if (type_string != kTypeURL && type_string != kTypeFolder)
(...skipping 22 matching lines...) Expand all
276 if (!value.Get(kChildrenKey, &child_values)) 224 if (!value.Get(kChildrenKey, &child_values))
277 return false; 225 return false;
278 226
279 if (child_values->GetType() != Value::TYPE_LIST) 227 if (child_values->GetType() != Value::TYPE_LIST)
280 return false; 228 return false;
281 229
282 if (!node) { 230 if (!node) {
283 node = new BookmarkNode(id, GURL()); 231 node = new BookmarkNode(id, GURL());
284 } else { 232 } else {
285 // If a new node is not created, explicitly assign ID to the existing one. 233 // If a new node is not created, explicitly assign ID to the existing one.
286 DCHECK(id != 0);
287 node->set_id(id); 234 node->set_id(id);
288 } 235 }
289 236
290 node->SetType(BookmarkNode::FOLDER); 237 node->SetType(BookmarkNode::FOLDER);
291 node->set_date_group_modified(Time::FromInternalValue( 238 node->set_date_group_modified(Time::FromInternalValue(
292 StringToInt64(WideToUTF16Hack(last_modified_date)))); 239 StringToInt64(WideToUTF16Hack(last_modified_date))));
293 240
294 if (parent) 241 if (parent)
295 parent->Add(parent->GetChildCount(), node); 242 parent->Add(parent->GetChildCount(), node);
296 243
297 UpdateChecksumWithFolderNode(id_string, title); 244 UpdateChecksumWithFolderNode(id_string, title);
298 245
299 if (!DecodeChildren(*static_cast<ListValue*>(child_values), node)) 246 if (!DecodeChildren(*static_cast<ListValue*>(child_values), node))
300 return false; 247 return false;
301 } 248 }
302 249
303 node->SetTitle(title); 250 node->SetTitle(title);
304 node->set_date_added(Time::FromInternalValue( 251 node->set_date_added(Time::FromInternalValue(
305 StringToInt64(WideToUTF16Hack(date_added_string)))); 252 StringToInt64(WideToUTF16Hack(date_added_string))));
306 return true; 253 return true;
307 } 254 }
308 255
256 void BookmarkCodec::ReassignIDs(BookmarkNode* bb_node,
257 BookmarkNode* other_node) {
258 maximum_id_ = 0;
259 ReassignIDsHelper(bb_node);
Erik does not do reviews 2009/07/15 19:44:52 Are there (or should there be) any assumptions abo
260 ReassignIDsHelper(other_node);
261 ids_reassigned_ = true;
262 }
263
264 void BookmarkCodec::ReassignIDsHelper(BookmarkNode* node) {
265 DCHECK(node);
266 node->set_id(++maximum_id_);
267 for (int i = 0; i < node->GetChildCount(); ++i)
268 ReassignIDsHelper(node->GetChild(i));
269 }
270
309 void BookmarkCodec::UpdateChecksum(const std::string& str) { 271 void BookmarkCodec::UpdateChecksum(const std::string& str) {
310 MD5Update(&md5_context_, str.data(), str.length() * sizeof(char)); 272 MD5Update(&md5_context_, str.data(), str.length() * sizeof(char));
311 } 273 }
312 274
313 void BookmarkCodec::UpdateChecksum(const std::wstring& str) { 275 void BookmarkCodec::UpdateChecksum(const std::wstring& str) {
314 MD5Update(&md5_context_, str.data(), str.length() * sizeof(wchar_t)); 276 MD5Update(&md5_context_, str.data(), str.length() * sizeof(wchar_t));
315 } 277 }
316 278
317 void BookmarkCodec::UpdateChecksumWithUrlNode(const std::string& id, 279 void BookmarkCodec::UpdateChecksumWithUrlNode(const std::string& id,
318 const std::wstring& title, 280 const std::wstring& title,
(...skipping 13 matching lines...) Expand all
332 294
333 void BookmarkCodec::InitializeChecksum() { 295 void BookmarkCodec::InitializeChecksum() {
334 MD5Init(&md5_context_); 296 MD5Init(&md5_context_);
335 } 297 }
336 298
337 void BookmarkCodec::FinalizeChecksum() { 299 void BookmarkCodec::FinalizeChecksum() {
338 MD5Digest digest; 300 MD5Digest digest;
339 MD5Final(&digest, &md5_context_); 301 MD5Final(&digest, &md5_context_);
340 computed_checksum_ = MD5DigestToBase16(digest); 302 computed_checksum_ = MD5DigestToBase16(digest);
341 } 303 }
OLDNEW
« no previous file with comments | « chrome/browser/bookmarks/bookmark_codec.h ('k') | chrome/browser/bookmarks/bookmark_codec_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698