| Index: content/browser/indexed_db/leveldb/leveldb_database.cc
|
| diff --git a/content/browser/indexed_db/leveldb/leveldb_database.cc b/content/browser/indexed_db/leveldb/leveldb_database.cc
|
| deleted file mode 100644
|
| index 0a8307c0a980af09240f77fd6edda4cde5ec4b26..0000000000000000000000000000000000000000
|
| --- a/content/browser/indexed_db/leveldb/leveldb_database.cc
|
| +++ /dev/null
|
| @@ -1,361 +0,0 @@
|
| -// Copyright (c) 2013 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 "content/browser/indexed_db/leveldb/leveldb_database.h"
|
| -
|
| -#include <string>
|
| -
|
| -#include "base/basictypes.h"
|
| -#include "base/logging.h"
|
| -#include "base/memory/scoped_ptr.h"
|
| -#include "base/metrics/histogram.h"
|
| -#include "base/string16.h"
|
| -#include "base/sys_info.h"
|
| -#include "base/utf_string_conversions.h"
|
| -#include "content/browser/indexed_db/leveldb/leveldb_comparator.h"
|
| -#include "content/browser/indexed_db/leveldb/leveldb_iterator.h"
|
| -#include "content/browser/indexed_db/leveldb/leveldb_slice.h"
|
| -#include "content/browser/indexed_db/leveldb/leveldb_write_batch.h"
|
| -#include "third_party/leveldatabase/env_idb.h"
|
| -#include "third_party/leveldatabase/src/helpers/memenv/memenv.h"
|
| -#include "third_party/leveldatabase/src/include/leveldb/comparator.h"
|
| -#include "third_party/leveldatabase/src/include/leveldb/db.h"
|
| -#include "third_party/leveldatabase/src/include/leveldb/env.h"
|
| -#include "third_party/leveldatabase/src/include/leveldb/slice.h"
|
| -
|
| -namespace content {
|
| -
|
| -static leveldb::Slice MakeSlice(const std::vector<char>& value) {
|
| - return leveldb::Slice(&*value.begin(), value.size());
|
| -}
|
| -
|
| -static leveldb::Slice MakeSlice(const LevelDBSlice& s) {
|
| - return leveldb::Slice(s.begin(), s.end() - s.begin());
|
| -}
|
| -
|
| -static LevelDBSlice MakeLevelDBSlice(const leveldb::Slice& s) {
|
| - return LevelDBSlice(s.data(), s.data() + s.size());
|
| -}
|
| -
|
| -class ComparatorAdapter : public leveldb::Comparator {
|
| - public:
|
| - explicit ComparatorAdapter(const LevelDBComparator* comparator)
|
| - : comparator_(comparator) {}
|
| -
|
| - virtual int Compare(const leveldb::Slice& a, const leveldb::Slice& b) const
|
| - OVERRIDE {
|
| - return comparator_->Compare(MakeLevelDBSlice(a), MakeLevelDBSlice(b));
|
| - }
|
| -
|
| - virtual const char* Name() const OVERRIDE { return comparator_->Name(); }
|
| -
|
| - // TODO(jsbell): Support the methods below in the future.
|
| - virtual void FindShortestSeparator(std::string* start,
|
| - const leveldb::Slice& limit) const
|
| - OVERRIDE {}
|
| - virtual void FindShortSuccessor(std::string* key) const OVERRIDE {}
|
| -
|
| - private:
|
| - const LevelDBComparator* comparator_;
|
| -};
|
| -
|
| -LevelDBSnapshot::LevelDBSnapshot(LevelDBDatabase* db)
|
| - : db_(db->db_.get()), snapshot_(db_->GetSnapshot()) {}
|
| -
|
| -LevelDBSnapshot::~LevelDBSnapshot() { db_->ReleaseSnapshot(snapshot_); }
|
| -
|
| -LevelDBDatabase::LevelDBDatabase() {}
|
| -
|
| -LevelDBDatabase::~LevelDBDatabase() {
|
| - // db_'s destructor uses comparator_adapter_; order of deletion is important.
|
| - db_.reset();
|
| - comparator_adapter_.reset();
|
| - env_.reset();
|
| -}
|
| -
|
| -static leveldb::Status OpenDB(leveldb::Comparator* comparator,
|
| - leveldb::Env* env,
|
| - const base::FilePath& path,
|
| - leveldb::DB** db) {
|
| - leveldb::Options options;
|
| - options.comparator = comparator;
|
| - options.create_if_missing = true;
|
| - options.paranoid_checks = true;
|
| -
|
| - // Marking compression as explicitly off so snappy support can be
|
| - // compiled in for other leveldb clients without implicitly enabling
|
| - // it for IndexedDB. http://crbug.com/81384
|
| - options.compression = leveldb::kNoCompression;
|
| -
|
| - // 20 max_open_files is the minimum LevelDB allows but its cache behaves
|
| - // poorly with less than 4 files per shard. As of this writing the latest
|
| - // leveldb (1.9) hardcodes 16 shards. See
|
| - // https://code.google.com/p/chromium/issues/detail?id=227313#c11
|
| - options.max_open_files = 80;
|
| - options.env = env;
|
| -
|
| - // ChromiumEnv assumes UTF8, converts back to FilePath before using.
|
| - return leveldb::DB::Open(options, path.AsUTF8Unsafe(), db);
|
| -}
|
| -
|
| -bool LevelDBDatabase::Destroy(const base::FilePath& file_name) {
|
| - leveldb::Options options;
|
| - options.env = leveldb::IDBEnv();
|
| - // ChromiumEnv assumes UTF8, converts back to FilePath before using.
|
| - const leveldb::Status s =
|
| - leveldb::DestroyDB(file_name.AsUTF8Unsafe(), options);
|
| - return s.ok();
|
| -}
|
| -
|
| -static void HistogramFreeSpace(const char* type,
|
| - const base::FilePath& file_name) {
|
| - string16 name = ASCIIToUTF16("WebCore.IndexedDB.LevelDB.Open") +
|
| - ASCIIToUTF16(type) + ASCIIToUTF16("FreeDiskSpace");
|
| - int64 free_disk_space_in_k_bytes =
|
| - base::SysInfo::AmountOfFreeDiskSpace(file_name) / 1024;
|
| - if (free_disk_space_in_k_bytes < 0) {
|
| - base::Histogram::FactoryGet(
|
| - "WebCore.IndexedDB.LevelDB.FreeDiskSpaceFailure",
|
| - 1,
|
| - 2 /*boundary*/,
|
| - 2 /*boundary*/ + 1,
|
| - base::HistogramBase::kUmaTargetedHistogramFlag)->Add(1 /*sample*/);
|
| - return;
|
| - }
|
| - int clamped_disk_space_k_bytes =
|
| - free_disk_space_in_k_bytes > INT_MAX ? INT_MAX
|
| - : free_disk_space_in_k_bytes;
|
| - const uint64 histogram_max = static_cast<uint64>(1e9);
|
| - COMPILE_ASSERT(histogram_max <= INT_MAX, histogram_max_too_big);
|
| - base::Histogram::FactoryGet(UTF16ToUTF8(name),
|
| - 1,
|
| - histogram_max,
|
| - 11 /*buckets*/,
|
| - base::HistogramBase::kUmaTargetedHistogramFlag)
|
| - ->Add(clamped_disk_space_k_bytes);
|
| -}
|
| -
|
| -static void HistogramLevelDBError(const char* histogram_name,
|
| - const leveldb::Status& s) {
|
| - DCHECK(!s.ok());
|
| - enum {
|
| - LEVEL_DB_NOT_FOUND,
|
| - LEVEL_DB_CORRUPTION,
|
| - LEVEL_DB_IO_ERROR,
|
| - LEVEL_DB_OTHER,
|
| - LEVEL_DB_MAX_ERROR
|
| - };
|
| - int leveldb_error = LEVEL_DB_OTHER;
|
| - if (s.IsNotFound())
|
| - leveldb_error = LEVEL_DB_NOT_FOUND;
|
| - else if (s.IsCorruption())
|
| - leveldb_error = LEVEL_DB_CORRUPTION;
|
| - else if (s.IsIOError())
|
| - leveldb_error = LEVEL_DB_IO_ERROR;
|
| - base::Histogram::FactoryGet(histogram_name,
|
| - 1,
|
| - LEVEL_DB_MAX_ERROR,
|
| - LEVEL_DB_MAX_ERROR + 1,
|
| - base::HistogramBase::kUmaTargetedHistogramFlag)
|
| - ->Add(leveldb_error);
|
| -}
|
| -
|
| -scoped_ptr<LevelDBDatabase> LevelDBDatabase::Open(
|
| - const base::FilePath& file_name,
|
| - const LevelDBComparator* comparator) {
|
| - scoped_ptr<ComparatorAdapter> comparator_adapter(
|
| - new ComparatorAdapter(comparator));
|
| -
|
| - leveldb::DB* db;
|
| - const leveldb::Status s =
|
| - OpenDB(comparator_adapter.get(), leveldb::IDBEnv(), file_name, &db);
|
| -
|
| - if (!s.ok()) {
|
| - HistogramLevelDBError("WebCore.IndexedDB.LevelDBOpenErrors", s);
|
| - HistogramFreeSpace("Failure", file_name);
|
| -
|
| - LOG(ERROR) << "Failed to open LevelDB database from "
|
| - << file_name.AsUTF8Unsafe() << "," << s.ToString();
|
| - return scoped_ptr<LevelDBDatabase>();
|
| - }
|
| -
|
| - HistogramFreeSpace("Success", file_name);
|
| -
|
| - scoped_ptr<LevelDBDatabase> result(new LevelDBDatabase);
|
| - result->db_ = make_scoped_ptr(db);
|
| - result->comparator_adapter_ = comparator_adapter.Pass();
|
| - result->comparator_ = comparator;
|
| -
|
| - return result.Pass();
|
| -}
|
| -
|
| -scoped_ptr<LevelDBDatabase> LevelDBDatabase::OpenInMemory(
|
| - const LevelDBComparator* comparator) {
|
| - scoped_ptr<ComparatorAdapter> comparator_adapter(
|
| - new ComparatorAdapter(comparator));
|
| - scoped_ptr<leveldb::Env> in_memory_env(leveldb::NewMemEnv(leveldb::IDBEnv()));
|
| -
|
| - leveldb::DB* db;
|
| - const leveldb::Status s = OpenDB(
|
| - comparator_adapter.get(), in_memory_env.get(), base::FilePath(), &db);
|
| -
|
| - if (!s.ok()) {
|
| - LOG(ERROR) << "Failed to open in-memory LevelDB database: " << s.ToString();
|
| - return scoped_ptr<LevelDBDatabase>();
|
| - }
|
| -
|
| - scoped_ptr<LevelDBDatabase> result(new LevelDBDatabase);
|
| - result->env_ = in_memory_env.Pass();
|
| - result->db_ = make_scoped_ptr(db);
|
| - result->comparator_adapter_ = comparator_adapter.Pass();
|
| - result->comparator_ = comparator;
|
| -
|
| - return result.Pass();
|
| -}
|
| -
|
| -bool LevelDBDatabase::Put(const LevelDBSlice& key,
|
| - const std::vector<char>& value) {
|
| - leveldb::WriteOptions write_options;
|
| - write_options.sync = true;
|
| -
|
| - const leveldb::Status s =
|
| - db_->Put(write_options, MakeSlice(key), MakeSlice(value));
|
| - if (s.ok())
|
| - return true;
|
| - LOG(ERROR) << "LevelDB put failed: " << s.ToString();
|
| - return false;
|
| -}
|
| -
|
| -bool LevelDBDatabase::Remove(const LevelDBSlice& key) {
|
| - leveldb::WriteOptions write_options;
|
| - write_options.sync = true;
|
| -
|
| - const leveldb::Status s = db_->Delete(write_options, MakeSlice(key));
|
| - if (s.ok())
|
| - return true;
|
| - if (s.IsNotFound())
|
| - return false;
|
| - LOG(ERROR) << "LevelDB remove failed: " << s.ToString();
|
| - return false;
|
| -}
|
| -
|
| -bool LevelDBDatabase::Get(const LevelDBSlice& key,
|
| - std::vector<char>& value,
|
| - bool& found,
|
| - const LevelDBSnapshot* snapshot) {
|
| - found = false;
|
| - std::string result;
|
| - leveldb::ReadOptions read_options;
|
| - read_options.verify_checksums = true; // TODO(jsbell): Disable this if the
|
| - // performance impact is too great.
|
| - read_options.snapshot = snapshot ? snapshot->snapshot_ : 0;
|
| -
|
| - const leveldb::Status s = db_->Get(read_options, MakeSlice(key), &result);
|
| - if (s.ok()) {
|
| - found = true;
|
| - value.clear();
|
| - value.insert(value.end(), result.begin(), result.end());
|
| - return true;
|
| - }
|
| - if (s.IsNotFound())
|
| - return true;
|
| - LOG(ERROR) << "LevelDB get failed: " << s.ToString();
|
| - return false;
|
| -}
|
| -
|
| -bool LevelDBDatabase::Write(LevelDBWriteBatch& write_batch) {
|
| - leveldb::WriteOptions write_options;
|
| - write_options.sync = true;
|
| -
|
| - const leveldb::Status s =
|
| - db_->Write(write_options, write_batch.write_batch_.get());
|
| - if (s.ok())
|
| - return true;
|
| - HistogramLevelDBError("WebCore.IndexedDB.LevelDBWriteErrors", s);
|
| - LOG(ERROR) << "LevelDB write failed: " << s.ToString();
|
| - return false;
|
| -}
|
| -
|
| -namespace {
|
| -class IteratorImpl : public LevelDBIterator {
|
| - public:
|
| - virtual ~IteratorImpl() {}
|
| -
|
| - virtual bool IsValid() const OVERRIDE;
|
| - virtual void SeekToLast() OVERRIDE;
|
| - virtual void Seek(const LevelDBSlice& target) OVERRIDE;
|
| - virtual void Next() OVERRIDE;
|
| - virtual void Prev() OVERRIDE;
|
| - virtual LevelDBSlice Key() const OVERRIDE;
|
| - virtual LevelDBSlice Value() const OVERRIDE;
|
| -
|
| - private:
|
| - friend class content::LevelDBDatabase;
|
| - IteratorImpl(scoped_ptr<leveldb::Iterator> iterator);
|
| - void CheckStatus();
|
| -
|
| - scoped_ptr<leveldb::Iterator> iterator_;
|
| -};
|
| -}
|
| -
|
| -IteratorImpl::IteratorImpl(scoped_ptr<leveldb::Iterator> it)
|
| - : iterator_(it.Pass()) {}
|
| -
|
| -void IteratorImpl::CheckStatus() {
|
| - const leveldb::Status s = iterator_->status();
|
| - if (!s.ok())
|
| - LOG(ERROR) << "LevelDB iterator error: " << s.ToString();
|
| -}
|
| -
|
| -bool IteratorImpl::IsValid() const { return iterator_->Valid(); }
|
| -
|
| -void IteratorImpl::SeekToLast() {
|
| - iterator_->SeekToLast();
|
| - CheckStatus();
|
| -}
|
| -
|
| -void IteratorImpl::Seek(const LevelDBSlice& target) {
|
| - iterator_->Seek(MakeSlice(target));
|
| - CheckStatus();
|
| -}
|
| -
|
| -void IteratorImpl::Next() {
|
| - DCHECK(IsValid());
|
| - iterator_->Next();
|
| - CheckStatus();
|
| -}
|
| -
|
| -void IteratorImpl::Prev() {
|
| - DCHECK(IsValid());
|
| - iterator_->Prev();
|
| - CheckStatus();
|
| -}
|
| -
|
| -LevelDBSlice IteratorImpl::Key() const {
|
| - DCHECK(IsValid());
|
| - return MakeLevelDBSlice(iterator_->key());
|
| -}
|
| -
|
| -LevelDBSlice IteratorImpl::Value() const {
|
| - DCHECK(IsValid());
|
| - return MakeLevelDBSlice(iterator_->value());
|
| -}
|
| -
|
| -scoped_ptr<LevelDBIterator> LevelDBDatabase::CreateIterator(
|
| - const LevelDBSnapshot* snapshot) {
|
| - leveldb::ReadOptions read_options;
|
| - read_options.verify_checksums = true; // TODO(jsbell): Disable this if the
|
| - // performance impact is too great.
|
| - read_options.snapshot = snapshot ? snapshot->snapshot_ : 0;
|
| - scoped_ptr<leveldb::Iterator> i(db_->NewIterator(read_options));
|
| - if (!i) // TODO(jsbell): Double check if we actually need to check this.
|
| - return scoped_ptr<LevelDBIterator>();
|
| - return scoped_ptr<LevelDBIterator>(new IteratorImpl(i.Pass()));
|
| -}
|
| -
|
| -const LevelDBComparator* LevelDBDatabase::Comparator() const {
|
| - return comparator_;
|
| -}
|
| -
|
| -} // namespace content
|
|
|