| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/visitedlink/visitedlink_master.h" | 5 #include "chrome/browser/visitedlink/visitedlink_master.h" |
| 6 | 6 |
| 7 #if defined(OS_WIN) | 7 #if defined(OS_WIN) |
| 8 #include <windows.h> | 8 #include <windows.h> |
| 9 #include <io.h> | 9 #include <io.h> |
| 10 #include <shlobj.h> | 10 #include <shlobj.h> |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 184 | 184 |
| 185 listener_ = listener; | 185 listener_ = listener; |
| 186 file_ = NULL; | 186 file_ = NULL; |
| 187 shared_memory_ = NULL; | 187 shared_memory_ = NULL; |
| 188 shared_memory_serial_ = 0; | 188 shared_memory_serial_ = 0; |
| 189 used_items_ = 0; | 189 used_items_ = 0; |
| 190 table_size_override_ = 0; | 190 table_size_override_ = 0; |
| 191 history_service_override_ = NULL; | 191 history_service_override_ = NULL; |
| 192 suppress_rebuild_ = false; | 192 suppress_rebuild_ = false; |
| 193 profile_ = profile; | 193 profile_ = profile; |
| 194 sequence_token_ = BrowserThread::GetBlockingPool()->GetSequenceToken(); |
| 194 | 195 |
| 195 #ifndef NDEBUG | 196 #ifndef NDEBUG |
| 196 posted_asynchronous_operation_ = false; | 197 posted_asynchronous_operation_ = false; |
| 197 #endif | 198 #endif |
| 198 } | 199 } |
| 199 | 200 |
| 200 bool VisitedLinkMaster::Init() { | 201 bool VisitedLinkMaster::Init() { |
| 201 // We probably shouldn't be loading this from the UI thread, | 202 // We probably shouldn't be loading this from the UI thread, |
| 202 // but it does need to happen early on in startup. | 203 // but it does need to happen early on in startup. |
| 203 // http://code.google.com/p/chromium/issues/detail?id=24163 | 204 // http://code.google.com/p/chromium/issues/detail?id=24163 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 235 // If the table is "full", we don't add URLs and just drop them on the floor. | 236 // If the table is "full", we don't add URLs and just drop them on the floor. |
| 236 // This can happen if we get thousands of new URLs and something causes | 237 // This can happen if we get thousands of new URLs and something causes |
| 237 // the table resizing to fail. This check prevents a hang in that case. Note | 238 // the table resizing to fail. This check prevents a hang in that case. Note |
| 238 // that this is *not* the resize limit, this is just a sanity check. | 239 // that this is *not* the resize limit, this is just a sanity check. |
| 239 if (used_items_ / 8 > table_length_ / 10) | 240 if (used_items_ / 8 > table_length_ / 10) |
| 240 return null_hash_; // Table is more than 80% full. | 241 return null_hash_; // Table is more than 80% full. |
| 241 | 242 |
| 242 return AddFingerprint(fingerprint, true); | 243 return AddFingerprint(fingerprint, true); |
| 243 } | 244 } |
| 244 | 245 |
| 246 void VisitedLinkMaster::PostIOTask(const tracked_objects::Location& from_here, |
| 247 const base::Closure& task) { |
| 248 BrowserThread::GetBlockingPool()->PostSequencedWorkerTask(sequence_token_, |
| 249 from_here, task); |
| 250 } |
| 251 |
| 245 void VisitedLinkMaster::AddURL(const GURL& url) { | 252 void VisitedLinkMaster::AddURL(const GURL& url) { |
| 246 Hash index = TryToAddURL(url); | 253 Hash index = TryToAddURL(url); |
| 247 if (!table_builder_ && index != null_hash_) { | 254 if (!table_builder_ && index != null_hash_) { |
| 248 // Not rebuilding, so we want to keep the file on disk up-to-date. | 255 // Not rebuilding, so we want to keep the file on disk up-to-date. |
| 249 WriteUsedItemCountToFile(); | 256 WriteUsedItemCountToFile(); |
| 250 WriteHashRangeToFile(index, index); | 257 WriteHashRangeToFile(index, index); |
| 251 ResizeTableIfNecessary(); | 258 ResizeTableIfNecessary(); |
| 252 } | 259 } |
| 253 } | 260 } |
| 254 | 261 |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 473 header[2] = table_length_; | 480 header[2] = table_length_; |
| 474 header[3] = used_items_; | 481 header[3] = used_items_; |
| 475 WriteToFile(file_, 0, header, sizeof(header)); | 482 WriteToFile(file_, 0, header, sizeof(header)); |
| 476 WriteToFile(file_, sizeof(header), salt_, LINK_SALT_LENGTH); | 483 WriteToFile(file_, sizeof(header), salt_, LINK_SALT_LENGTH); |
| 477 | 484 |
| 478 // Write the hash data. | 485 // Write the hash data. |
| 479 WriteToFile(file_, kFileHeaderSize, | 486 WriteToFile(file_, kFileHeaderSize, |
| 480 hash_table_, table_length_ * sizeof(Fingerprint)); | 487 hash_table_, table_length_ * sizeof(Fingerprint)); |
| 481 | 488 |
| 482 // The hash table may have shrunk, so make sure this is the end. | 489 // The hash table may have shrunk, so make sure this is the end. |
| 483 BrowserThread::PostTask( | 490 PostIOTask(FROM_HERE, base::Bind(base::IgnoreResult(&TruncateFile), file_)); |
| 484 BrowserThread::FILE, | |
| 485 FROM_HERE, | |
| 486 base::Bind(base::IgnoreResult(&TruncateFile), file_)); | |
| 487 return true; | 491 return true; |
| 488 } | 492 } |
| 489 | 493 |
| 490 bool VisitedLinkMaster::InitFromFile() { | 494 bool VisitedLinkMaster::InitFromFile() { |
| 491 DCHECK(file_ == NULL); | 495 DCHECK(file_ == NULL); |
| 492 | 496 |
| 493 FilePath filename; | 497 FilePath filename; |
| 494 GetDatabaseFileName(&filename); | 498 GetDatabaseFileName(&filename); |
| 495 ScopedFILE file_closer(OpenFile(filename, "rb+")); | 499 ScopedFILE file_closer(OpenFile(filename, "rb+")); |
| 496 if (!file_closer.get()) | 500 if (!file_closer.get()) |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 666 return true; | 670 return true; |
| 667 } | 671 } |
| 668 | 672 |
| 669 void VisitedLinkMaster::FreeURLTable() { | 673 void VisitedLinkMaster::FreeURLTable() { |
| 670 if (shared_memory_) { | 674 if (shared_memory_) { |
| 671 delete shared_memory_; | 675 delete shared_memory_; |
| 672 shared_memory_ = NULL; | 676 shared_memory_ = NULL; |
| 673 } | 677 } |
| 674 if (!file_) | 678 if (!file_) |
| 675 return; | 679 return; |
| 676 | 680 PostIOTask(FROM_HERE, base::Bind(base::IgnoreResult(&fclose), file_)); |
| 677 BrowserThread::PostTask( | |
| 678 BrowserThread::FILE, | |
| 679 FROM_HERE, | |
| 680 base::Bind(base::IgnoreResult(&fclose), file_)); | |
| 681 } | 681 } |
| 682 | 682 |
| 683 bool VisitedLinkMaster::ResizeTableIfNecessary() { | 683 bool VisitedLinkMaster::ResizeTableIfNecessary() { |
| 684 DCHECK(table_length_ > 0) << "Must have a table"; | 684 DCHECK(table_length_ > 0) << "Must have a table"; |
| 685 | 685 |
| 686 // Load limits for good performance/space. We are pretty conservative about | 686 // Load limits for good performance/space. We are pretty conservative about |
| 687 // keeping the table not very full. This is because we use linear probing | 687 // keeping the table not very full. This is because we use linear probing |
| 688 // which increases the likelihood of clumps of entries which will reduce | 688 // which increases the likelihood of clumps of entries which will reduce |
| 689 // performance. | 689 // performance. |
| 690 const float max_table_load = 0.5f; // Grow when we're > this full. | 690 const float max_table_load = 0.5f; // Grow when we're > this full. |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 853 } | 853 } |
| 854 } | 854 } |
| 855 | 855 |
| 856 void VisitedLinkMaster::WriteToFile(FILE* file, | 856 void VisitedLinkMaster::WriteToFile(FILE* file, |
| 857 off_t offset, | 857 off_t offset, |
| 858 void* data, | 858 void* data, |
| 859 int32 data_size) { | 859 int32 data_size) { |
| 860 #ifndef NDEBUG | 860 #ifndef NDEBUG |
| 861 posted_asynchronous_operation_ = true; | 861 posted_asynchronous_operation_ = true; |
| 862 #endif | 862 #endif |
| 863 | 863 PostIOTask(FROM_HERE, |
| 864 BrowserThread::PostTask( | |
| 865 BrowserThread::FILE, FROM_HERE, | |
| 866 base::Bind(&AsyncWrite, file, offset, | 864 base::Bind(&AsyncWrite, file, offset, |
| 867 std::string(static_cast<const char*>(data), data_size))); | 865 std::string(static_cast<const char*>(data), data_size))); |
| 868 } | 866 } |
| 869 | 867 |
| 870 void VisitedLinkMaster::WriteUsedItemCountToFile() { | 868 void VisitedLinkMaster::WriteUsedItemCountToFile() { |
| 871 if (!file_) | 869 if (!file_) |
| 872 return; // See comment on the file_ variable for why this might happen. | 870 return; // See comment on the file_ variable for why this might happen. |
| 873 WriteToFile(file_, kFileHeaderUsedOffset, &used_items_, sizeof(used_items_)); | 871 WriteToFile(file_, kFileHeaderUsedOffset, &used_items_, sizeof(used_items_)); |
| 874 } | 872 } |
| 875 | 873 |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 946 } | 944 } |
| 947 | 945 |
| 948 void VisitedLinkMaster::TableBuilder::OnCompleteMainThread() { | 946 void VisitedLinkMaster::TableBuilder::OnCompleteMainThread() { |
| 949 if (master_) | 947 if (master_) |
| 950 master_->OnTableRebuildComplete(success_, fingerprints_); | 948 master_->OnTableRebuildComplete(success_, fingerprints_); |
| 951 | 949 |
| 952 // WILL (generally) DELETE THIS! This balances the AddRef in | 950 // WILL (generally) DELETE THIS! This balances the AddRef in |
| 953 // VisitedLinkMaster::RebuildTableFromHistory. | 951 // VisitedLinkMaster::RebuildTableFromHistory. |
| 954 Release(); | 952 Release(); |
| 955 } | 953 } |
| OLD | NEW |