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

Unified Diff: chrome/browser/visitedlink_master.cc

Issue 19028: Roll forward 8722,8721 (Closed)
Patch Set: Created 11 years, 11 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/visitedlink_master.h ('k') | chrome/browser/visitedlink_perftest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/visitedlink_master.cc
diff --git a/chrome/browser/visitedlink_master.cc b/chrome/browser/visitedlink_master.cc
index 22a963827cd6582c7c937026db1b4efdfafa058d..85470cc40c2f4b5bf63b2fdc2fd27e5276a505c9 100644
--- a/chrome/browser/visitedlink_master.cc
+++ b/chrome/browser/visitedlink_master.cc
@@ -4,20 +4,40 @@
#include "chrome/browser/visitedlink_master.h"
+#if defined(OS_WIN)
#include <windows.h>
+#include <io.h>
#include <shlobj.h>
+#endif // defined(OS_WIN)
+#include <stdio.h>
+
#include <algorithm>
+#include "base/file_util.h"
#include "base/logging.h"
#include "base/message_loop.h"
#include "base/path_service.h"
+#include "base/process_util.h"
#include "base/rand_util.h"
#include "base/stack_container.h"
#include "base/string_util.h"
+#include "base/thread.h"
#include "chrome/browser/browser_process.h"
+#if defined(OS_WIN)
#include "chrome/browser/history/history.h"
#include "chrome/browser/profile.h"
+#else
+// TODO(port): We should be using history.h & profile.h, remove scaffolding
+// when those are ported.
+#include "chrome/common/temp_scaffolding_stubs.h"
+#endif // !defined(OS_WIN)
+#if defined(OS_WIN)
#include "chrome/common/win_util.h"
+#endif
+
+using file_util::ScopedFILE;
+using file_util::OpenFile;
+using file_util::TruncateFile;
const int32 VisitedLinkMaster::kFileHeaderSignatureOffset = 0;
const int32 VisitedLinkMaster::kFileHeaderVersionOffset = 4;
@@ -36,7 +56,7 @@ const size_t VisitedLinkMaster::kFileHeaderSize =
// table in NewTableSizeForCount (prime number).
const unsigned VisitedLinkMaster::kDefaultTableSize = 16381;
-const int32 VisitedLinkMaster::kBigDeleteThreshold = 64;
+const size_t VisitedLinkMaster::kBigDeleteThreshold = 64;
namespace {
@@ -48,43 +68,42 @@ void GenerateSalt(uint8 salt[LINK_SALT_LENGTH]) {
uint64 randval = base::RandUint64();
memcpy(salt, &randval, 8);
}
+
// AsyncWriter ----------------------------------------------------------------
// This task executes on a background thread and executes a write. This
// prevents us from blocking the UI thread doing I/O.
class AsyncWriter : public Task {
public:
- AsyncWriter(HANDLE hfile, int32 offset, const void* data, int32 data_len)
- : hfile_(hfile),
+ AsyncWriter(FILE* file, int32 offset, const void* data, size_t data_len)
+ : file_(file),
offset_(offset) {
data_->resize(data_len);
memcpy(&*data_->begin(), data, data_len);
}
virtual void Run() {
- WriteToFile(hfile_, offset_,
+ WriteToFile(file_, offset_,
&*data_->begin(), static_cast<int32>(data_->size()));
}
// Exposed as a static so it can be called directly from the Master to
// reduce the number of platform-specific I/O sites we have. Returns true if
// the write was complete.
- static bool WriteToFile(HANDLE hfile,
- int32 offset,
+ static bool WriteToFile(FILE* file,
+ off_t offset,
const void* data,
- int32 data_len) {
- if (SetFilePointer(hfile, offset, NULL, FILE_BEGIN) ==
- INVALID_SET_FILE_POINTER)
+ size_t data_len) {
+ if (fseek(file, offset, SEEK_SET) != 0)
return false; // Don't write to an invalid part of the file.
- DWORD num_written;
- return WriteFile(hfile, data, data_len, &num_written, NULL) &&
- (num_written == data_len);
+ size_t num_written = fwrite(data, 1, data_len, file);
+ return num_written == data_len;
}
private:
// The data to write and where to write it.
- HANDLE hfile_;
+ FILE* file_;
int32 offset_; // Offset from the beginning of the file.
// Most writes are just a single fingerprint, so we reserve that much in this
@@ -98,14 +117,14 @@ class AsyncWriter : public Task {
// same thread as the writing to keep things synchronized.
class AsyncSetEndOfFile : public Task {
public:
- explicit AsyncSetEndOfFile(HANDLE hfile) : hfile_(hfile) {}
+ explicit AsyncSetEndOfFile(FILE* file) : file_(file) {}
virtual void Run() {
- SetEndOfFile(hfile_);
+ TruncateFile(file_);
}
private:
- HANDLE hfile_;
+ FILE* file_;
DISALLOW_EVIL_CONSTRUCTORS(AsyncSetEndOfFile);
};
@@ -113,14 +132,14 @@ class AsyncSetEndOfFile : public Task {
// the writing to keep things synchronized.
class AsyncCloseHandle : public Task {
public:
- explicit AsyncCloseHandle(HANDLE hfile) : hfile_(hfile) {}
+ explicit AsyncCloseHandle(FILE* file) : file_(file) {}
virtual void Run() {
- CloseHandle(hfile_);
+ fclose(file_);
}
private:
- HANDLE hfile_;
+ FILE* file_;
DISALLOW_EVIL_CONSTRUCTORS(AsyncCloseHandle);
};
@@ -194,11 +213,11 @@ VisitedLinkMaster::VisitedLinkMaster(base::Thread* file_thread,
PostNewTableEvent* poster,
HistoryService* history_service,
bool suppress_rebuild,
- const std::wstring& filename,
+ const FilePath& filename,
int32 default_table_size) {
InitMembers(file_thread, poster, NULL);
- database_name_override_.assign(filename);
+ database_name_override_ = filename;
table_size_override_ = default_table_size;
history_service_override_ = history_service;
suppress_rebuild_ = suppress_rebuild;
@@ -248,7 +267,7 @@ std::wstring VisitedLinkMaster::GetSharedMemoryName() const {
profile_id = profile_->GetID().c_str();
return StringPrintf(L"GVisitedLinks_%lu_%lu_%ls",
- GetCurrentProcessId(), shared_memory_serial_,
+ base::GetCurrentProcId(), shared_memory_serial_,
profile_id.c_str());
}
@@ -512,19 +531,19 @@ bool VisitedLinkMaster::WriteFullTable() {
// We should pick up the most common types of these failures when we notice
// that the file size is different when we load it back in, and then we will
// regenerate the table.
- win_util::ScopedHandle hfile_closer; // Valid only when not open already.
- HANDLE hfile; // Always valid.
+ ScopedFILE file_closer; // Valid only when not open already.
+ FILE* file; // Always valid.
if (file_) {
- hfile = file_;
+ file = file_;
} else {
- std::wstring filename;
+ FilePath filename;
GetDatabaseFileName(&filename);
- hfile_closer.Set(
- CreateFile(filename.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL,
- CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL));
- if (!hfile_closer.IsValid())
+ file_closer.reset(OpenFile(filename, "wb+"));
+ if (!file_closer.get()) {
+ DLOG(ERROR) << "Failed to open file " << filename.value();
return false;
- hfile = hfile_closer;
+ }
+ file = file_closer.get();
}
// Write the new header.
@@ -533,54 +552,54 @@ bool VisitedLinkMaster::WriteFullTable() {
header[1] = kFileCurrentVersion;
header[2] = table_length_;
header[3] = used_items_;
- WriteToFile(hfile, 0, header, sizeof(header));
- WriteToFile(hfile, sizeof(header), salt_, LINK_SALT_LENGTH);
+ WriteToFile(file, 0, header, sizeof(header));
+ WriteToFile(file, sizeof(header), salt_, LINK_SALT_LENGTH);
// Write the hash data.
- WriteToFile(hfile, kFileHeaderSize,
+ WriteToFile(file, kFileHeaderSize,
hash_table_, table_length_ * sizeof(Fingerprint));
// The hash table may have shrunk, so make sure this is the end.
if (file_thread_) {
- AsyncSetEndOfFile* setter = new AsyncSetEndOfFile(hfile);
+ AsyncSetEndOfFile* setter = new AsyncSetEndOfFile(file);
file_thread_->PostTask(FROM_HERE, setter);
} else {
- SetEndOfFile(hfile);
+ TruncateFile(file);
}
// Keep the file open so we can dynamically write changes to it. When the
- // file was alrady open, the hfile_closer is NULL, and file_ is already good.
- if (hfile_closer.IsValid())
- file_ = hfile_closer.Take();
+ // file was already open, the file_closer is NULL, and file_ is already good.
+ if (file_closer.get())
+ file_ = file_closer.release();
return true;
}
bool VisitedLinkMaster::InitFromFile() {
DCHECK(file_ == NULL);
- std::wstring filename;
+ FilePath filename;
GetDatabaseFileName(&filename);
- win_util::ScopedHandle hfile(
- CreateFile(filename.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL,
- OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL));
- if (!hfile.IsValid())
+ ScopedFILE file_closer(OpenFile(filename, "rb+"));
+ if (!file_closer.get()) {
+ DLOG(ERROR) << "Failed to open file " << filename.value();
return false;
+ }
int32 num_entries, used_count;
- if (!ReadFileHeader(hfile, &num_entries, &used_count, salt_))
+ if (!ReadFileHeader(file_closer.get(), &num_entries, &used_count, salt_))
return false; // Header isn't valid.
// Allocate and read the table.
if (!CreateURLTable(num_entries, false))
return false;
- if (!ReadFromFile(hfile, kFileHeaderSize,
+ if (!ReadFromFile(file_closer.get(), kFileHeaderSize,
hash_table_, num_entries * sizeof(Fingerprint))) {
FreeURLTable();
return false;
}
used_items_ = used_count;
- file_ = hfile.Take();
+ file_ = file_closer.release();
return true;
}
@@ -609,20 +628,27 @@ bool VisitedLinkMaster::InitFromScratch(bool suppress_rebuild) {
return RebuildTableFromHistory();
}
-bool VisitedLinkMaster::ReadFileHeader(HANDLE hfile,
+bool VisitedLinkMaster::ReadFileHeader(FILE* file,
int32* num_entries,
int32* used_count,
uint8 salt[LINK_SALT_LENGTH]) {
- int32 file_size = GetFileSize(hfile, NULL);
+ // Get file size.
+ // Note that there is no need to seek back to the original location in the
+ // file since ReadFromFile() [which is the next call accessing the file]
+ // seeks before reading.
+ if (fseek(file, 0, SEEK_END) == -1)
+ return false;
+ size_t file_size = ftell(file);
+
if (file_size <= kFileHeaderSize)
return false;
uint8 header[kFileHeaderSize];
- if (!ReadFromFile(hfile, 0, &header, kFileHeaderSize))
+ if (!ReadFromFile(file, 0, &header, kFileHeaderSize))
return false;
// Verify the signature.
- uint32 signature;
+ int32 signature;
memcpy(&signature, &header[kFileHeaderSignatureOffset], sizeof(signature));
if (signature != kFileSignature)
return false;
@@ -652,7 +678,7 @@ bool VisitedLinkMaster::ReadFileHeader(HANDLE hfile,
return true;
}
-bool VisitedLinkMaster::GetDatabaseFileName(std::wstring* filename) {
+bool VisitedLinkMaster::GetDatabaseFileName(FilePath* filename) {
if (!database_name_override_.empty()) {
// use this filename, the directory must exist
*filename = database_name_override_;
@@ -662,8 +688,8 @@ bool VisitedLinkMaster::GetDatabaseFileName(std::wstring* filename) {
if (!profile_ || profile_->GetPath().empty())
return false;
- *filename = profile_->GetPath();
- filename->append(L"\\Visited Links");
+ FilePath profile_dir = FilePath::FromWStringHack(profile_->GetPath());
+ *filename = profile_dir.Append(FILE_PATH_LITERAL("Visited Links"));
return true;
}
@@ -735,7 +761,7 @@ void VisitedLinkMaster::FreeURLTable() {
AsyncCloseHandle* closer = new AsyncCloseHandle(file_);
file_thread_->PostTask(FROM_HERE, closer);
} else {
- CloseHandle(file_);
+ fclose(file_);
}
}
}
@@ -752,7 +778,8 @@ bool VisitedLinkMaster::ResizeTableIfNecessary() {
float load = ComputeTableLoad();
if (load < max_table_load &&
- (table_length_ <= kDefaultTableSize || load > min_table_load))
+ (table_length_ <= static_cast<float>(kDefaultTableSize) ||
+ load > min_table_load))
return false;
// Table needs to grow or shrink.
@@ -823,7 +850,7 @@ uint32 VisitedLinkMaster::NewTableSizeForCount(int32 item_count) const {
int desired = item_count * 3;
// Find the closest prime.
- for (int i = 0; i < arraysize(table_sizes); i ++) {
+ for (size_t i = 0; i < arraysize(table_sizes); i ++) {
if (table_sizes[i] > desired)
return table_sizes[i];
}
@@ -908,8 +935,8 @@ void VisitedLinkMaster::OnTableRebuildComplete(
}
}
-void VisitedLinkMaster::WriteToFile(HANDLE hfile,
- int32 offset,
+void VisitedLinkMaster::WriteToFile(FILE* file,
+ off_t offset,
void* data,
int32 data_size) {
#ifndef NDEBUG
@@ -918,12 +945,12 @@ void VisitedLinkMaster::WriteToFile(HANDLE hfile,
if (file_thread_) {
// Send the write to the other thread for execution to avoid blocking.
- AsyncWriter* writer = new AsyncWriter(hfile, offset, data, data_size);
+ AsyncWriter* writer = new AsyncWriter(file, offset, data, data_size);
file_thread_->PostTask(FROM_HERE, writer);
} else {
// When there is no I/O thread, we are probably running in unit test mode,
// just do the write synchronously.
- AsyncWriter::WriteToFile(hfile, offset, data, data_size);
+ AsyncWriter::WriteToFile(file, offset, data, data_size);
}
}
@@ -949,21 +976,20 @@ void VisitedLinkMaster::WriteHashRangeToFile(Hash first_hash, Hash last_hash) {
}
}
-bool VisitedLinkMaster::ReadFromFile(HANDLE hfile,
- int32 offset,
+bool VisitedLinkMaster::ReadFromFile(FILE* file,
+ off_t offset,
void* data,
- int32 data_size) {
+ size_t data_size) {
#ifndef NDEBUG
// Since this function is synchronous, we require that no asynchronous
// operations could possibly be pending.
DCHECK(!posted_asynchronous_operation_);
#endif
- SetFilePointer(hfile, offset, NULL, FILE_BEGIN);
+ fseek(file, offset, SEEK_SET);
- DWORD num_read;
- return ReadFile(hfile, data, data_size, &num_read, NULL) &&
- num_read == data_size;
+ size_t num_read = fread(data, 1, data_size, file);
+ return num_read == data_size;
}
// VisitedLinkTableBuilder ----------------------------------------------------
@@ -972,8 +998,8 @@ VisitedLinkMaster::TableBuilder::TableBuilder(
VisitedLinkMaster* master,
const uint8 salt[LINK_SALT_LENGTH])
: master_(master),
- success_(true),
- main_message_loop_(MessageLoop::current()) {
+ main_message_loop_(MessageLoop::current()),
+ success_(true) {
fingerprints_.reserve(4096);
memcpy(salt_, salt, sizeof(salt));
}
« no previous file with comments | « chrome/browser/visitedlink_master.h ('k') | chrome/browser/visitedlink_perftest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698