From e5187c36c657e2ac682c1cec57227510ef890c8b Mon Sep 17 00:00:00 2001 From: "hans@chromium.org" Date: Thu, 29 Sep 2011 12:29:13 +0000 Subject: [PATCH] IndexedDB: Use LevelDB also for in-memory databases https://bugs.webkit.org/show_bug.cgi?id=68903 Reviewed by Steve Block. Source/WebCore: Add LevelDBDatabase::openInMemory() which uses leveldb::NewMemEnv() to create in-memory LevelDB databases. Use this in IDBLeveLDBBackingStore::open() when the caller passes in an empty file path. This happens in Chromium's incognito mode, and when running layout tests. Fix IDBSQLiteBackingStore::backingStoreExists() so it doesn't create files when passed in an empty file path, but uses the in-memory mode instead. Existing layout tests will all be run in-memory. * platform/leveldb/LevelDBDatabase.cpp: (WebCore::LevelDBDatabase::~LevelDBDatabase): (WebCore::openDB): (WebCore::LevelDBDatabase::open): (WebCore::LevelDBDatabase::openInMemory): * platform/leveldb/LevelDBDatabase.h: * storage/IDBLevelDBBackingStore.cpp: (WebCore::IDBLevelDBBackingStore::open): * storage/IDBSQLiteBackingStore.cpp: (WebCore::IDBSQLiteBackingStore::backingStoreExists): Source/WebKit/chromium: Don't fall back to SQLite or use a temporary dir for in-memory databases (Incognito and layout tests); LevelDB supports in-memory databases now. * public/WebIDBFactory.h: * src/WebIDBFactoryImpl.cpp: (WebKit::WebIDBFactoryImpl::getDatabaseNames): (WebKit::WebIDBFactoryImpl::open): Tools: Remove the temporary dir that was necessary before LevelDB supported in-memory databases. * DumpRenderTree/chromium/TestShell.cpp: (TestShell::TestShell): * DumpRenderTree/chromium/TestShell.h: git-svn-id: http://svn.webkit.org/repository/webkit/trunk@96322 268f45cc-cd09-0410-ab3c-d52691b4dbfc --- Source/WebCore/ChangeLog | 32 +++++++++++++++++ .../WebCore/platform/leveldb/LevelDBDatabase.cpp | 42 +++++++++++++++++++--- Source/WebCore/platform/leveldb/LevelDBDatabase.h | 5 ++- Source/WebCore/storage/IDBLevelDBBackingStore.cpp | 24 +++++++------ Source/WebCore/storage/IDBSQLiteBackingStore.cpp | 6 ++-- Source/WebKit/chromium/ChangeLog | 16 +++++++++ Source/WebKit/chromium/public/WebIDBFactory.h | 1 - Source/WebKit/chromium/src/WebIDBFactoryImpl.cpp | 26 -------------- Tools/ChangeLog | 14 ++++++++ Tools/DumpRenderTree/chromium/TestShell.cpp | 6 ---- Tools/DumpRenderTree/chromium/TestShell.h | 3 -- 11 files changed, 120 insertions(+), 55 deletions(-) diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog index 0fa3993..e6ee20a 100644 --- a/Source/WebCore/ChangeLog +++ b/Source/WebCore/ChangeLog @@ -1,3 +1,35 @@ +2011-09-29 Hans Wennborg + + IndexedDB: Use LevelDB also for in-memory databases + https://bugs.webkit.org/show_bug.cgi?id=68903 + + Reviewed by Steve Block. + + Add LevelDBDatabase::openInMemory() which uses leveldb::NewMemEnv() + to create in-memory LevelDB databases. + + Use this in IDBLeveLDBBackingStore::open() when the caller passes in + an empty file path. + This happens in Chromium's incognito mode, and when running layout + tests. + + Fix IDBSQLiteBackingStore::backingStoreExists() so it doesn't create + files when passed in an empty file path, but uses the in-memory mode + instead. + + Existing layout tests will all be run in-memory. + + * platform/leveldb/LevelDBDatabase.cpp: + (WebCore::LevelDBDatabase::~LevelDBDatabase): + (WebCore::openDB): + (WebCore::LevelDBDatabase::open): + (WebCore::LevelDBDatabase::openInMemory): + * platform/leveldb/LevelDBDatabase.h: + * storage/IDBLevelDBBackingStore.cpp: + (WebCore::IDBLevelDBBackingStore::open): + * storage/IDBSQLiteBackingStore.cpp: + (WebCore::IDBSQLiteBackingStore::backingStoreExists): + 2011-09-29 Ilya Tikhonovsky Web Inspector: speed-up Network panel. Change _staleResources type from array to object. diff --git a/Source/WebCore/platform/leveldb/LevelDBDatabase.cpp b/Source/WebCore/platform/leveldb/LevelDBDatabase.cpp index 935d7ed..41a1aef 100644 --- a/Source/WebCore/platform/leveldb/LevelDBDatabase.cpp +++ b/Source/WebCore/platform/leveldb/LevelDBDatabase.cpp @@ -33,8 +33,10 @@ #include "LevelDBSlice.h" #include "LevelDBWriteBatch.h" #include "Logging.h" +#include #include #include +#include #include #include #include @@ -96,18 +98,26 @@ LevelDBDatabase::~LevelDBDatabase() // m_db's destructor uses m_comparatorAdapter; order of deletion is important. m_db.clear(); m_comparatorAdapter.clear(); + m_env.clear(); } -PassOwnPtr LevelDBDatabase::open(const String& fileName, const LevelDBComparator* comparator) +static leveldb::Status openDB(leveldb::Comparator* comparator, leveldb::Env* env, const String& path, leveldb::DB** db) { - OwnPtr comparatorAdapter = adoptPtr(new ComparatorAdapter(comparator)); - leveldb::Options options; - options.comparator = comparatorAdapter.get(); + options.comparator = comparator; options.create_if_missing = true; options.paranoid_checks = true; + options.env = env; + + return leveldb::DB::Open(options, path.utf8().data(), db); +} + +PassOwnPtr LevelDBDatabase::open(const String& fileName, const LevelDBComparator* comparator) +{ + OwnPtr comparatorAdapter = adoptPtr(new ComparatorAdapter(comparator)); + leveldb::DB* db; - const leveldb::Status s = leveldb::DB::Open(options, fileName.utf8().data(), &db); + const leveldb::Status s = openDB(comparatorAdapter.get(), leveldb::Env::Default(), fileName, &db); if (!s.ok()) { LOG_ERROR("Failed to open LevelDB database from %s: %s", fileName.ascii().data(), s.ToString().c_str()); @@ -122,6 +132,28 @@ PassOwnPtr LevelDBDatabase::open(const String& fileName, const return result.release(); } +PassOwnPtr LevelDBDatabase::openInMemory(const LevelDBComparator* comparator) +{ + OwnPtr comparatorAdapter = adoptPtr(new ComparatorAdapter(comparator)); + OwnPtr inMemoryEnv = adoptPtr(leveldb::NewMemEnv(leveldb::Env::Default())); + + leveldb::DB* db; + const leveldb::Status s = openDB(comparatorAdapter.get(), inMemoryEnv.get(), String(), &db); + + if (!s.ok()) { + LOG_ERROR("Failed to open in-memory LevelDB database: %s", s.ToString().c_str()); + return nullptr; + } + + OwnPtr result = adoptPtr(new LevelDBDatabase); + result->m_env = inMemoryEnv.release(); + result->m_db = adoptPtr(db); + result->m_comparatorAdapter = comparatorAdapter.release(); + result->m_comparator = comparator; + + return result.release(); +} + bool LevelDBDatabase::put(const LevelDBSlice& key, const Vector& value) { leveldb::WriteOptions writeOptions; diff --git a/Source/WebCore/platform/leveldb/LevelDBDatabase.h b/Source/WebCore/platform/leveldb/LevelDBDatabase.h index cbeeedf..c6ce21c 100644 --- a/Source/WebCore/platform/leveldb/LevelDBDatabase.h +++ b/Source/WebCore/platform/leveldb/LevelDBDatabase.h @@ -36,6 +36,7 @@ namespace leveldb { class Comparator; class DB; +class Env; } namespace WebCore { @@ -48,6 +49,7 @@ class LevelDBWriteBatch; class LevelDBDatabase { public: static PassOwnPtr open(const String& fileName, const LevelDBComparator*); + static PassOwnPtr openInMemory(const LevelDBComparator*); ~LevelDBDatabase(); bool put(const LevelDBSlice& key, const Vector& value); @@ -60,9 +62,10 @@ public: private: LevelDBDatabase(); + OwnPtr m_env; + OwnPtr m_comparatorAdapter; OwnPtr m_db; const LevelDBComparator* m_comparator; - OwnPtr m_comparatorAdapter; }; } diff --git a/Source/WebCore/storage/IDBLevelDBBackingStore.cpp b/Source/WebCore/storage/IDBLevelDBBackingStore.cpp index 4af33e4..d7e3c9d 100644 --- a/Source/WebCore/storage/IDBLevelDBBackingStore.cpp +++ b/Source/WebCore/storage/IDBLevelDBBackingStore.cpp @@ -136,20 +136,22 @@ PassRefPtr IDBLevelDBBackingStore::open(SecurityOrigin* securit { String pathBase = pathBaseArg; - if (pathBase.isEmpty()) { - ASSERT_NOT_REACHED(); // FIXME: We need to handle this case for incognito and DumpRenderTree. - return PassRefPtr(); - } + OwnPtr comparator = adoptPtr(new Comparator()); + OwnPtr db; - if (!makeAllDirectories(pathBase)) { - LOG_ERROR("Unable to create IndexedDB database path %s", pathBase.utf8().data()); - return PassRefPtr(); + if (pathBase.isEmpty()) + db = LevelDBDatabase::openInMemory(comparator.get()); + else { + if (!makeAllDirectories(pathBase)) { + LOG_ERROR("Unable to create IndexedDB database path %s", pathBase.utf8().data()); + return PassRefPtr(); + } + // FIXME: We should eventually use the same LevelDB database for all origins. + String path = pathByAppendingComponent(pathBase, securityOrigin->databaseIdentifier() + ".indexeddb.leveldb"); + + db = LevelDBDatabase::open(path, comparator.get()); } - // FIXME: We should eventually use the same LevelDB database for all origins. - String path = pathByAppendingComponent(pathBase, securityOrigin->databaseIdentifier() + ".indexeddb.leveldb"); - OwnPtr comparator = adoptPtr(new Comparator()); - OwnPtr db = LevelDBDatabase::open(path, comparator.get()); if (!db) return PassRefPtr(); diff --git a/Source/WebCore/storage/IDBSQLiteBackingStore.cpp b/Source/WebCore/storage/IDBSQLiteBackingStore.cpp index 3eb87ec..116dc82 100644 --- a/Source/WebCore/storage/IDBSQLiteBackingStore.cpp +++ b/Source/WebCore/storage/IDBSQLiteBackingStore.cpp @@ -169,7 +169,7 @@ PassRefPtr IDBSQLiteBackingStore::open(SecurityOrigin* security { RefPtr backingStore(adoptRef(new IDBSQLiteBackingStore(fileIdentifier, factory))); - String path = ":memory:"; + String path = ":memory:"; // in-memory SQLite database. if (!pathBase.isEmpty()) { if (!makeAllDirectories(pathBase)) { // FIXME: Is there any other thing we could possibly do to recover at this point? If so, do it rather than just erroring out. @@ -1012,7 +1012,9 @@ PassRefPtr IDBSQLiteBackingStore::openIndexCursor(int64 bool IDBSQLiteBackingStore::backingStoreExists(SecurityOrigin* securityOrigin, const String& name, const String& pathBase) { - String path = pathByAppendingComponent(pathBase, securityOrigin->databaseIdentifier() + ".indexeddb"); + String path = ":memory:"; // in-memory SQLite database. + if (!pathBase.isEmpty()) + path = pathByAppendingComponent(pathBase, securityOrigin->databaseIdentifier() + ".indexeddb"); SQLiteDatabase db; if (!db.open(path)) return false; diff --git a/Source/WebKit/chromium/ChangeLog b/Source/WebKit/chromium/ChangeLog index cb886ed..416da3f 100644 --- a/Source/WebKit/chromium/ChangeLog +++ b/Source/WebKit/chromium/ChangeLog @@ -1,3 +1,19 @@ +2011-09-29 Hans Wennborg + + IndexedDB: Use LevelDB also for in-memory databases + https://bugs.webkit.org/show_bug.cgi?id=68903 + + Reviewed by Steve Block. + + Don't fall back to SQLite or use a temporary dir for in-memory + databases (Incognito and layout tests); LevelDB supports in-memory + databases now. + + * public/WebIDBFactory.h: + * src/WebIDBFactoryImpl.cpp: + (WebKit::WebIDBFactoryImpl::getDatabaseNames): + (WebKit::WebIDBFactoryImpl::open): + 2011-09-28 Fady Samuel [Chromium] Seperate GTK specific Gyp rules from X11 Gyp rules diff --git a/Source/WebKit/chromium/public/WebIDBFactory.h b/Source/WebKit/chromium/public/WebIDBFactory.h index b1a708b..9c65f2d 100755 --- a/Source/WebKit/chromium/public/WebIDBFactory.h +++ b/Source/WebKit/chromium/public/WebIDBFactory.h @@ -66,7 +66,6 @@ public: // Used for DumpRenderTree tests. WEBKIT_EXPORT static void setOverrideBackingStoreType(BackingStoreType); - WEBKIT_EXPORT static void setTemporaryDatabaseFolder(const WebString& path); }; } // namespace WebKit diff --git a/Source/WebKit/chromium/src/WebIDBFactoryImpl.cpp b/Source/WebKit/chromium/src/WebIDBFactoryImpl.cpp index 666087b..40bec0d 100755 --- a/Source/WebKit/chromium/src/WebIDBFactoryImpl.cpp +++ b/Source/WebKit/chromium/src/WebIDBFactoryImpl.cpp @@ -45,7 +45,6 @@ using namespace WebCore; namespace WebKit { static WebIDBFactory::BackingStoreType overriddenBackingStoreType = WebIDBFactory::DefaultBackingStore; -static WebString tempDatabaseFolder; WebIDBFactory* WebIDBFactory::create() { @@ -57,11 +56,6 @@ void WebIDBFactory::setOverrideBackingStoreType(BackingStoreType type) overriddenBackingStoreType = type; } -void WebIDBFactory::setTemporaryDatabaseFolder(const WebString& path) -{ - tempDatabaseFolder = path; -} - WebIDBFactoryImpl::WebIDBFactoryImpl() : m_idbFactoryBackend(IDBFactoryBackendImpl::create()) { @@ -83,16 +77,6 @@ void WebIDBFactoryImpl::getDatabaseNames(WebIDBCallbacks* callbacks, const WebSe if (backingStoreType == DefaultBackingStore) backingStoreType = LevelDBBackingStore; - if (dataDir.isEmpty() && backingStoreType == LevelDBBackingStore) { - if (!tempDatabaseFolder.isEmpty()) { - // Layout tests provide a temporary folder. - path = tempDatabaseFolder; - } else { - // For incognito mode, fall back to SQLite. - backingStoreType = SQLiteBackingStore; - } - } - m_idbFactoryBackend->getDatabaseNames(IDBCallbacksProxy::create(adoptPtr(callbacks)), origin, 0, path, maximumSize, static_cast(backingStoreType)); } @@ -109,16 +93,6 @@ void WebIDBFactoryImpl::open(const WebString& name, WebIDBCallbacks* callbacks, if (backingStoreType == DefaultBackingStore) backingStoreType = LevelDBBackingStore; - if (dataDir.isEmpty() && backingStoreType == LevelDBBackingStore) { - if (!tempDatabaseFolder.isEmpty()) { - // Layout tests provide a temporary folder. - path = tempDatabaseFolder; - } else { - // For incognito mode, fall back to SQLite. - backingStoreType = SQLiteBackingStore; - } - } - m_idbFactoryBackend->open(name, IDBCallbacksProxy::create(adoptPtr(callbacks)), origin, 0, path, maximumSize, static_cast(backingStoreType)); } diff --git a/Tools/ChangeLog b/Tools/ChangeLog index 3ac7f21..a8ef297 100644 --- a/Tools/ChangeLog +++ b/Tools/ChangeLog @@ -1,3 +1,17 @@ +2011-09-29 Hans Wennborg + + IndexedDB: Use LevelDB also for in-memory databases + https://bugs.webkit.org/show_bug.cgi?id=68903 + + Reviewed by Steve Block. + + Remove the temporary dir that was necessary before LevelDB supported + in-memory databases. + + * DumpRenderTree/chromium/TestShell.cpp: + (TestShell::TestShell): + * DumpRenderTree/chromium/TestShell.h: + 2011-09-28 Xianzhu Wang Run TestWebKitAPI on Chromium buildbots diff --git a/Tools/DumpRenderTree/chromium/TestShell.cpp b/Tools/DumpRenderTree/chromium/TestShell.cpp index 7f3d821..41134f7 100644 --- a/Tools/DumpRenderTree/chromium/TestShell.cpp +++ b/Tools/DumpRenderTree/chromium/TestShell.cpp @@ -136,12 +136,6 @@ TestShell::TestShell(bool testShellMode) // timed-out DRT process was crashed. m_timeout = 30 * 1000; -#if ENABLE(INDEXED_DATABASE) - m_tempIndexedDBDirectory = adoptPtr(webkit_support::CreateScopedTempDirectory()); - m_tempIndexedDBDirectory->CreateUniqueTempDir(); - WebIDBFactory::setTemporaryDatabaseFolder(WebString::fromUTF8(m_tempIndexedDBDirectory->path().c_str())); -#endif - createMainWindow(); } diff --git a/Tools/DumpRenderTree/chromium/TestShell.h b/Tools/DumpRenderTree/chromium/TestShell.h index 8ce4d99..42af2e7 100644 --- a/Tools/DumpRenderTree/chromium/TestShell.h +++ b/Tools/DumpRenderTree/chromium/TestShell.h @@ -235,9 +235,6 @@ private: // Used by the watchdog to know when it's finished. HANDLE m_finishedEvent; #endif - - // Temporary directory for IndexedDB (LevelDB doesn't support in-memory databases.) - OwnPtr m_tempIndexedDBDirectory; }; void platformInit(int*, char***); -- 2.7.4