diff options
author | agayev@chromium.org <agayev@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-08 21:16:53 +0000 |
---|---|---|
committer | agayev@chromium.org <agayev@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-08 21:16:53 +0000 |
commit | 82ce8a41cfb0bff9902bce4aa3adc726c1f0a2cf (patch) | |
tree | f3dc58413e1f9e62142bb85af9e48d98bf3b1052 | |
parent | 74b264fd1b3aaeef944d1c50173e85f7965afbd1 (diff) | |
download | chromium_src-82ce8a41cfb0bff9902bce4aa3adc726c1f0a2cf.zip chromium_src-82ce8a41cfb0bff9902bce4aa3adc726c1f0a2cf.tar.gz chromium_src-82ce8a41cfb0bff9902bce4aa3adc726c1f0a2cf.tar.bz2 |
Adding disk_cache::Entry implementation.
BUG=157187
TEST=net_unittests --gtest_filter="FlashCacheTest.*" --gtest_repeat=10 --shuffle
Review URL: https://chromiumcodereview.appspot.com/12847012
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@192896 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | net/disk_cache/flash/flash_entry_impl.cc | 149 | ||||
-rw-r--r-- | net/disk_cache/flash/flash_entry_impl.h | 98 | ||||
-rw-r--r-- | net/disk_cache/flash/flash_entry_unittest.cc | 48 | ||||
-rw-r--r-- | net/disk_cache/flash/internal_entry.cc | 86 | ||||
-rw-r--r-- | net/disk_cache/flash/internal_entry.h | 63 | ||||
-rw-r--r-- | net/disk_cache/flash/log_store_entry.cc | 16 | ||||
-rw-r--r-- | net/disk_cache/flash/log_store_entry.h | 2 | ||||
-rw-r--r-- | net/net.gyp | 5 |
8 files changed, 458 insertions, 9 deletions
diff --git a/net/disk_cache/flash/flash_entry_impl.cc b/net/disk_cache/flash/flash_entry_impl.cc new file mode 100644 index 0000000..3d64b03 --- /dev/null +++ b/net/disk_cache/flash/flash_entry_impl.cc @@ -0,0 +1,149 @@ +// Copyright (c) 2012 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 "base/location.h" +#include "base/message_loop_proxy.h" +#include "base/task_runner_util.h" +#include "net/base/io_buffer.h" +#include "net/base/net_errors.h" +#include "net/disk_cache/flash/flash_entry_impl.h" +#include "net/disk_cache/flash/internal_entry.h" + +namespace disk_cache { + +FlashEntryImpl::FlashEntryImpl(const std::string& key, + LogStore* store, + base::MessageLoopProxy* cache_thread) + : init_(false), + key_(key), + new_internal_entry_(new InternalEntry(key, store)), + cache_thread_(cache_thread) { + memset(stream_sizes_, 0, sizeof(stream_sizes_)); +} + +FlashEntryImpl::FlashEntryImpl(int32 id, + LogStore* store, + base::MessageLoopProxy* cache_thread) + : init_(false), + old_internal_entry_(new InternalEntry(id, store)), + cache_thread_(cache_thread) { +} + +int FlashEntryImpl::Init(const CompletionCallback& callback) { + if (new_internal_entry_) { + DCHECK(callback.is_null()); + init_ = true; + return net::OK; + } + DCHECK(!callback.is_null() && old_internal_entry_); + callback_ = callback; + PostTaskAndReplyWithResult(cache_thread_, FROM_HERE, + Bind(&InternalEntry::Init, old_internal_entry_), + Bind(&FlashEntryImpl::OnInitComplete, this)); + return net::ERR_IO_PENDING; +} + +void FlashEntryImpl::Doom() { + DCHECK(init_); + NOTREACHED(); +} + +void FlashEntryImpl::Close() { + DCHECK(init_); + Release(); +} + +std::string FlashEntryImpl::GetKey() const { + DCHECK(init_); + return key_; +} + +base::Time FlashEntryImpl::GetLastUsed() const { + DCHECK(init_); + NOTREACHED(); + return base::Time::Now(); +} + +base::Time FlashEntryImpl::GetLastModified() const { + DCHECK(init_); + NOTREACHED(); + return base::Time::Now(); +} + +int32 FlashEntryImpl::GetDataSize(int index) const { + DCHECK(init_); + return new_internal_entry_->GetDataSize(index); +} + +int FlashEntryImpl::ReadData(int index, int offset, IOBuffer* buf, int buf_len, + const CompletionCallback& callback) { + DCHECK(init_); + return new_internal_entry_->ReadData(index, offset, buf, buf_len, callback); +} + +int FlashEntryImpl::WriteData(int index, int offset, IOBuffer* buf, int buf_len, + const CompletionCallback& callback, + bool truncate) { + DCHECK(init_); + return new_internal_entry_->WriteData(index, offset, buf, buf_len, callback); +} + +int FlashEntryImpl::ReadSparseData(int64 offset, IOBuffer* buf, int buf_len, + const CompletionCallback& callback) { + DCHECK(init_); + NOTREACHED(); + return net::ERR_FAILED; +} + +int FlashEntryImpl::WriteSparseData(int64 offset, IOBuffer* buf, int buf_len, + const CompletionCallback& callback) { + DCHECK(init_); + NOTREACHED(); + return net::ERR_FAILED; +} + +int FlashEntryImpl::GetAvailableRange(int64 offset, int len, int64* start, + const CompletionCallback& callback) { + DCHECK(init_); + NOTREACHED(); + return net::ERR_FAILED; +} + +bool FlashEntryImpl::CouldBeSparse() const { + DCHECK(init_); + NOTREACHED(); + return false; +} + +void FlashEntryImpl::CancelSparseIO() { + DCHECK(init_); + NOTREACHED(); +} + +int FlashEntryImpl::ReadyForSparseIO(const CompletionCallback& callback) { + DCHECK(init_); + NOTREACHED(); + return net::ERR_FAILED; +} + +void FlashEntryImpl::OnInitComplete( + scoped_ptr<KeyAndStreamSizes> key_and_stream_sizes) { + DCHECK(!callback_.is_null()); + if (!key_and_stream_sizes) { + callback_.Run(net::ERR_FAILED); + } else { + key_ = key_and_stream_sizes->key; + memcpy(stream_sizes_, key_and_stream_sizes->stream_sizes, + sizeof(stream_sizes_)); + init_ = true; + callback_.Run(net::OK); + } +} + +FlashEntryImpl::~FlashEntryImpl() { + cache_thread_->PostTask(FROM_HERE, + Bind(&InternalEntry::Close, new_internal_entry_)); +} + +} // namespace disk_cache diff --git a/net/disk_cache/flash/flash_entry_impl.h b/net/disk_cache/flash/flash_entry_impl.h new file mode 100644 index 0000000..32f489f --- /dev/null +++ b/net/disk_cache/flash/flash_entry_impl.h @@ -0,0 +1,98 @@ +// Copyright (c) 2012 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. + +#ifndef NET_DISK_CACHE_FLASH_ENTRY_IMPL_H_ +#define NET_DISK_CACHE_FLASH_ENTRY_IMPL_H_ + +#include <string> + +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" +#include "net/base/net_export.h" +#include "net/disk_cache/disk_cache.h" +#include "net/disk_cache/flash/internal_entry.h" + +namespace base { + +class MessageLoopProxy; + +} // namespace base + +namespace disk_cache { + +class InternalEntry; +class IOBuffer; +class LogStore; + +// We use split objects to minimize the context switches between the main thread +// and the cache thread in the most common case of creating a new entry. +// +// All calls on a new entry are served synchronously. When an object is +// destructed (via final Close() call), a message is posted to the cache thread +// to save the object to storage. +// +// When an entry is not new, every asynchronous call is posted to the cache +// thread, just as before; synchronous calls like GetKey() and GetDataSize() are +// served from the main thread. +class NET_EXPORT_PRIVATE FlashEntryImpl + : public Entry, + public base::RefCountedThreadSafe<FlashEntryImpl> { + friend class base::RefCountedThreadSafe<FlashEntryImpl>; + public: + FlashEntryImpl(const std::string& key, + LogStore* store, + base::MessageLoopProxy* cache_thread); + FlashEntryImpl(int32 id, + LogStore* store, + base::MessageLoopProxy* cache_thread); + + int Init(const CompletionCallback& callback); + + // disk_cache::Entry interface. + virtual void Doom() OVERRIDE; + virtual void Close() OVERRIDE; + virtual std::string GetKey() const OVERRIDE; + virtual base::Time GetLastUsed() const OVERRIDE; + virtual base::Time GetLastModified() const OVERRIDE; + virtual int32 GetDataSize(int index) const OVERRIDE; + virtual int ReadData(int index, int offset, IOBuffer* buf, int buf_len, + const CompletionCallback& callback) OVERRIDE; + virtual int WriteData(int index, int offset, IOBuffer* buf, int buf_len, + const CompletionCallback& callback, + bool truncate) OVERRIDE; + virtual int ReadSparseData(int64 offset, IOBuffer* buf, int buf_len, + const CompletionCallback& callback) OVERRIDE; + virtual int WriteSparseData(int64 offset, IOBuffer* buf, int buf_len, + const CompletionCallback& callback) OVERRIDE; + virtual int GetAvailableRange(int64 offset, int len, int64* start, + const CompletionCallback& callback) OVERRIDE; + virtual bool CouldBeSparse() const OVERRIDE; + virtual void CancelSparseIO() OVERRIDE; + virtual int ReadyForSparseIO(const CompletionCallback& callback) OVERRIDE; + + private: + void OnInitComplete(scoped_ptr<KeyAndStreamSizes> key_and_stream_sizes); + virtual ~FlashEntryImpl(); + + bool init_; + std::string key_; + int stream_sizes_[kFlashLogStoreEntryNumStreams]; + + // Used if |this| is an newly created entry. + scoped_refptr<InternalEntry> new_internal_entry_; + + // Used if |this| is an existing entry. + scoped_refptr<InternalEntry> old_internal_entry_; + + // Copy of the callback for asynchronous calls on |old_internal_entry_|. + CompletionCallback callback_; + + scoped_refptr<base::MessageLoopProxy> cache_thread_; + + DISALLOW_COPY_AND_ASSIGN(FlashEntryImpl); +}; + +} // namespace disk_cache + +#endif // NET_DISK_CACHE_FLASH_ENTRY_IMPL_H_ diff --git a/net/disk_cache/flash/flash_entry_unittest.cc b/net/disk_cache/flash/flash_entry_unittest.cc new file mode 100644 index 0000000..ea6eaaac --- /dev/null +++ b/net/disk_cache/flash/flash_entry_unittest.cc @@ -0,0 +1,48 @@ +// Copyright (c) 2012 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 "base/memory/ref_counted.h" +#include "base/string_util.h" +#include "base/threading/thread.h" +#include "base/threading/thread_restrictions.h" +#include "net/base/io_buffer.h" +#include "net/base/net_errors.h" +#include "net/disk_cache/disk_cache_test_util.h" +#include "net/disk_cache/flash/flash_cache_test_base.h" +#include "net/disk_cache/flash/flash_entry_impl.h" +#include "net/disk_cache/flash/format.h" +#include "testing/gtest/include/gtest/gtest.h" + +using net::CompletionCallback; + +TEST_F(FlashCacheTest, FlashEntryCreate) { + base::Thread cache_thread("CacheThread"); + ASSERT_TRUE(cache_thread.StartWithOptions( + base::Thread::Options(MessageLoop::TYPE_IO, 0))); + + const std::string key = "foo.com"; + disk_cache::FlashEntryImpl* entry = + new disk_cache::FlashEntryImpl(key, + log_store_.get(), + cache_thread.message_loop_proxy()); + entry->AddRef(); + EXPECT_EQ(net::OK, entry->Init(CompletionCallback())); + EXPECT_EQ(key, entry->GetKey()); + EXPECT_EQ(0, entry->GetDataSize(0)); + EXPECT_EQ(0, entry->GetDataSize(1)); + EXPECT_EQ(0, entry->GetDataSize(2)); + + const int kSize1 = 100; + scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize1)); + CacheTestFillBuffer(buffer1->data(), kSize1, false); + EXPECT_EQ(0, entry->ReadData(0, 0, buffer1, kSize1, CompletionCallback())); + base::strlcpy(buffer1->data(), "the data", kSize1); + EXPECT_EQ(kSize1, entry->WriteData(0, 0, buffer1, kSize1, + CompletionCallback(), false)); + memset(buffer1->data(), 0, kSize1); + EXPECT_EQ(kSize1, entry->ReadData(0, 0, buffer1, kSize1, + CompletionCallback())); + EXPECT_STREQ("the data", buffer1->data()); + entry->Close(); +} diff --git a/net/disk_cache/flash/internal_entry.cc b/net/disk_cache/flash/internal_entry.cc new file mode 100644 index 0000000..14659732 --- /dev/null +++ b/net/disk_cache/flash/internal_entry.cc @@ -0,0 +1,86 @@ +// Copyright (c) 2012 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 "net/disk_cache/flash/internal_entry.h" + +#include "base/memory/ref_counted.h" +#include "net/base/completion_callback.h" +#include "net/base/io_buffer.h" +#include "net/base/net_errors.h" +#include "net/disk_cache/flash/log_store.h" +#include "net/disk_cache/flash/log_store_entry.h" + +using net::IOBuffer; +using net::StringIOBuffer; +using net::CompletionCallback; + +namespace disk_cache { + +KeyAndStreamSizes::KeyAndStreamSizes() { +} + +InternalEntry::InternalEntry(const std::string& key, LogStore* store) + : store_(store), + entry_(new LogStoreEntry(store_)) { + entry_->Init(); + WriteKey(entry_.get(), key); +} + +InternalEntry::InternalEntry(int32 id, LogStore* store) + : store_(store), + entry_(new LogStoreEntry(store_, id)) { +} + +InternalEntry::~InternalEntry() { +} + +scoped_ptr<KeyAndStreamSizes> InternalEntry::Init() { + scoped_ptr<KeyAndStreamSizes> null; + if (entry_->IsNew()) + return null.Pass(); + if (!entry_->Init()) + return null.Pass(); + + scoped_ptr<KeyAndStreamSizes> rv(new KeyAndStreamSizes); + if (!ReadKey(entry_.get(), &rv->key)) + return null.Pass(); + for (int i = 0; i < kFlashLogStoreEntryNumStreams; ++i) + rv->stream_sizes[i] = entry_->GetDataSize(i+1); + return rv.Pass(); +} + +int32 InternalEntry::GetDataSize(int index) const { + return entry_->GetDataSize(++index); +} + +int InternalEntry::ReadData(int index, int offset, IOBuffer* buf, int buf_len, + const CompletionCallback& callback) { + return entry_->ReadData(++index, offset, buf, buf_len); +} + +int InternalEntry::WriteData(int index, int offset, IOBuffer* buf, int buf_len, + const CompletionCallback& callback) { + return entry_->WriteData(++index, offset, buf, buf_len); +} + +void InternalEntry::Close() { + entry_->Close(); +} + +bool InternalEntry::WriteKey(LogStoreEntry* entry, const std::string& key) { + int key_size = static_cast<int>(key.size()); + scoped_refptr<IOBuffer> key_buf(new StringIOBuffer(key)); + return entry->WriteData(0, 0, key_buf, key_size) == key_size; +} + +bool InternalEntry::ReadKey(LogStoreEntry* entry, std::string* key) { + int key_size = entry->GetDataSize(0); + scoped_refptr<net::IOBuffer> key_buf(new net::IOBuffer(key_size)); + if (entry->ReadData(0, 0, key_buf, key_size) != key_size) + return false; + key->assign(key_buf->data(), key_size); + return true; +} + +} // namespace disk_cache diff --git a/net/disk_cache/flash/internal_entry.h b/net/disk_cache/flash/internal_entry.h new file mode 100644 index 0000000..eeb2793 --- /dev/null +++ b/net/disk_cache/flash/internal_entry.h @@ -0,0 +1,63 @@ +// Copyright (c) 2012 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. + +#ifndef NET_DISK_CACHE_FLASH_INTERNAL_ENTRY_H_ +#define NET_DISK_CACHE_FLASH_INTERNAL_ENTRY_H_ + +#include <string> + +#include "base/basictypes.h" +#include "base/memory/scoped_ptr.h" +#include "net/base/completion_callback.h" +#include "net/base/net_export.h" +#include "net/disk_cache/flash/format.h" + +namespace net { + +class IOBuffer; + +} // namespace net + +namespace disk_cache { + +struct KeyAndStreamSizes { + KeyAndStreamSizes(); + std::string key; + int stream_sizes[kFlashLogStoreEntryNumStreams]; +}; + +class LogStore; +class LogStoreEntry; + +// Actual entry implementation that does all the work of reading, writing and +// storing data. +class NET_EXPORT_PRIVATE InternalEntry + : public base::RefCountedThreadSafe<InternalEntry> { + friend class base::RefCountedThreadSafe<InternalEntry>; + public: + InternalEntry(const std::string& key, LogStore* store); + InternalEntry(int32 id, LogStore* store); + + scoped_ptr<KeyAndStreamSizes> Init(); + int32 GetDataSize(int index) const; + int ReadData(int index, int offset, net::IOBuffer* buf, int buf_len, + const net::CompletionCallback& callback); + int WriteData(int index, int offset, net::IOBuffer* buf, int buf_len, + const net::CompletionCallback& callback); + void Close(); + + private: + bool WriteKey(LogStoreEntry* entry, const std::string& key); + bool ReadKey(LogStoreEntry* entry, std::string* key); + ~InternalEntry(); + + LogStore* store_; + scoped_ptr<LogStoreEntry> entry_; + + DISALLOW_COPY_AND_ASSIGN(InternalEntry); +}; + +} // namespace disk_cache + +#endif // NET_DISK_CACHE_FLASH_INTERNAL_ENTRY_H_ diff --git a/net/disk_cache/flash/log_store_entry.cc b/net/disk_cache/flash/log_store_entry.cc index 7909c66..1e26ec5 100644 --- a/net/disk_cache/flash/log_store_entry.cc +++ b/net/disk_cache/flash/log_store_entry.cc @@ -27,7 +27,7 @@ LogStoreEntry::~LogStoreEntry() { bool LogStoreEntry::Init() { DCHECK(!init_); - if (!ReadOnly()) { + if (IsNew()) { init_ = true; return true; } @@ -53,13 +53,13 @@ bool LogStoreEntry::Init() { bool LogStoreEntry::Close() { DCHECK(init_ && !closed_); - if (ReadOnly()) { + if (IsNew()) { + closed_ = deleted_ ? true : Save(); + } else { store_->CloseEntry(id_); if (deleted_) store_->DeleteEntry(id_, Size()); closed_ = true; - } else { - closed_ = deleted_ ? true : Save(); } return closed_; } @@ -86,7 +86,7 @@ int LogStoreEntry::ReadData(int index, int offset, net::IOBuffer* buf, if (offset + buf_len > stream_size) buf_len = stream_size - offset; - if (ReadOnly()) { + if (!IsNew()) { offset += streams_[index].offset; if (store_->ReadData(id_, buf->data(), buf_len, offset)) return buf_len; @@ -122,8 +122,8 @@ void LogStoreEntry::Delete() { deleted_ = true; } -bool LogStoreEntry::ReadOnly() const { - return id_ != -1; +bool LogStoreEntry::IsNew() const { + return id_ == -1; } bool LogStoreEntry::InvalidStream(int stream_index) const { @@ -140,7 +140,7 @@ int32 LogStoreEntry::Size() const { } bool LogStoreEntry::Save() { - DCHECK(init_ && !closed_ && !deleted_ && !ReadOnly()); + DCHECK(init_ && !closed_ && !deleted_ && IsNew()); int32 stream_sizes[kFlashLogStoreEntryNumStreams]; COMPILE_ASSERT(sizeof(stream_sizes) == kFlashLogStoreEntryHeaderSize, invalid_log_store_entry_header_size); diff --git a/net/disk_cache/flash/log_store_entry.h b/net/disk_cache/flash/log_store_entry.h index ef184ee1..5791949 100644 --- a/net/disk_cache/flash/log_store_entry.h +++ b/net/disk_cache/flash/log_store_entry.h @@ -30,6 +30,7 @@ class NET_EXPORT_PRIVATE LogStoreEntry { bool Close(); int32 id() const; + bool IsNew() const; int32 GetDataSize(int index) const; int ReadData(int index, int offset, net::IOBuffer* buf, int buf_len); @@ -45,7 +46,6 @@ class NET_EXPORT_PRIVATE LogStoreEntry { std::vector<char> write_buffer; }; - bool ReadOnly() const; bool InvalidStream(int stream_index) const; int32 Size() const; bool Save(); diff --git a/net/net.gyp b/net/net.gyp index fcbb2e8..4a4f1fa 100644 --- a/net/net.gyp +++ b/net/net.gyp @@ -391,7 +391,11 @@ 'disk_cache/simple/simple_index.h', 'disk_cache/simple/simple_synchronous_entry.cc', 'disk_cache/simple/simple_synchronous_entry.h', + 'disk_cache/flash/flash_entry_impl.cc', + 'disk_cache/flash/flash_entry_impl.h', 'disk_cache/flash/format.h', + 'disk_cache/flash/internal_entry.cc', + 'disk_cache/flash/internal_entry.h', 'disk_cache/flash/log_store.cc', 'disk_cache/flash/log_store.h', 'disk_cache/flash/log_store_entry.cc', @@ -1434,6 +1438,7 @@ 'disk_cache/entry_unittest.cc', 'disk_cache/mapped_file_unittest.cc', 'disk_cache/storage_block_unittest.cc', + 'disk_cache/flash/flash_entry_unittest.cc', 'disk_cache/flash/log_store_entry_unittest.cc', 'disk_cache/flash/log_store_unittest.cc', 'disk_cache/flash/segment_unittest.cc', |