Source/WebCore/ChangeLog

 12012-09-07 Joshua Bell <jsbell@chromium.org>
 2
 3 IndexedDB: IDBFactory.deleteDatabase() is slow
 4 https://bugs.webkit.org/show_bug.cgi?id=96036
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 The deleteDatabase() operation is implemented by creating a LevelDBTansaction to accumulate
 9 the records to delete, then committing it. The transaction is a tree of key/operation pairs.
 10 As each (key, delete) entry is added to the tree compares need to be made, potentially
 11 requiring full key decodes. Since this temporary transaction is never read from, this is
 12 overkill.
 13
 14 Add a new "write only" transaction type that simply wraps a write batch, which provides
 15 transaction integrity but avoids the insertion overhead.
 16
 17 No new tests - no functional changes, only perf improvement.
 18
 19 * Modules/indexeddb/IDBLevelDBBackingStore.cpp:
 20 (WebCore::IDBLevelDBBackingStore::deleteDatabase): Use new write-only transaction type.
 21 * platform/leveldb/LevelDBTransaction.cpp:
 22 (WebCore::LevelDBWriteOnlyTransaction::create):
 23 (WebCore):
 24 (WebCore::LevelDBWriteOnlyTransaction::LevelDBWriteOnlyTransaction):
 25 (WebCore::LevelDBWriteOnlyTransaction::~LevelDBWriteOnlyTransaction):
 26 (WebCore::LevelDBWriteOnlyTransaction::put):
 27 (WebCore::LevelDBWriteOnlyTransaction::remove):
 28 (WebCore::LevelDBWriteOnlyTransaction::commit):
 29 (WebCore::LevelDBWriteOnlyTransaction::rollback):
 30 * platform/leveldb/LevelDBTransaction.h:
 31 (WebCore):
 32 (LevelDBWriteOnlyTransaction):
 33
1342012-09-03 Sam Weinig <sam@webkit.org>
235
336 Part 1 of removing PlatformString.h, move remaining functions to new homes

Source/WebCore/Modules/indexeddb/IDBLevelDBBackingStore.cpp

@@static bool deleteRange(LevelDBTransaction* transaction, const Vector<char>& beg
360360bool IDBLevelDBBackingStore::deleteDatabase(const String& name)
361361{
362362 IDB_TRACE("IDBLevelDBBackingStore::deleteDatabase");
363  RefPtr<LevelDBTransaction> transaction = LevelDBTransaction::create(m_db.get());
 363 RefPtr<LevelDBWriteOnlyTransaction> transaction = LevelDBWriteOnlyTransaction::create(m_db.get());
364364
365365 int64_t databaseId;
366366 String version;

@@bool IDBLevelDBBackingStore::deleteDatabase(const String& name)
372372
373373 const Vector<char> startKey = DatabaseMetaDataKey::encode(databaseId, DatabaseMetaDataKey::OriginName);
374374 const Vector<char> stopKey = DatabaseMetaDataKey::encode(databaseId + 1, DatabaseMetaDataKey::OriginName);
375  if (!deleteRange(transaction.get(), startKey, stopKey)) {
376  transaction->rollback();
377  return false;
 375 OwnPtr<LevelDBIterator> it = m_db->createIterator();
 376 for (it->seek(startKey); it->isValid() && compareKeys(it->key(), stopKey) < 0; it->next()) {
 377 if (!transaction->remove(it->key())) {
 378 transaction->rollback();
 379 return false;
 380 }
378381 }
379382
380383 const Vector<char> key = DatabaseNameKey::encode(m_identifier, name);

Source/WebCore/platform/leveldb/LevelDBTransaction.cpp

@@void LevelDBTransaction::notifyIteratorsOfTreeChange()
485485 }
486486}
487487
 488PassRefPtr<LevelDBWriteOnlyTransaction> LevelDBWriteOnlyTransaction::create(LevelDBDatabase* db)
 489{
 490 return adoptRef(new LevelDBWriteOnlyTransaction(db));
 491}
 492
 493LevelDBWriteOnlyTransaction::LevelDBWriteOnlyTransaction(LevelDBDatabase* db)
 494 : m_db(db)
 495 , m_writeBatch(LevelDBWriteBatch::create())
 496 , m_finished(false)
 497{
 498}
 499
 500LevelDBWriteOnlyTransaction::~LevelDBWriteOnlyTransaction()
 501{
 502 m_writeBatch->clear();
 503}
 504
 505bool LevelDBWriteOnlyTransaction::put(const LevelDBSlice& key, const Vector<char>& value)
 506{
 507 ASSERT(!m_finished);
 508 m_writeBatch->put(key, value);
 509 return true;
 510}
 511
 512bool LevelDBWriteOnlyTransaction::remove(const LevelDBSlice& key)
 513{
 514 ASSERT(!m_finished);
 515 m_writeBatch->remove(key);
 516 return true;
 517}
 518
 519bool LevelDBWriteOnlyTransaction::commit()
 520{
 521 ASSERT(!m_finished);
 522
 523 if (!m_db->write(*m_writeBatch))
 524 return false;
 525
 526 m_finished = true;
 527 m_writeBatch->clear();
 528 return true;
 529}
 530
 531void LevelDBWriteOnlyTransaction::rollback()
 532{
 533 ASSERT(!m_finished);
 534 m_finished = true;
 535 m_writeBatch->clear();
 536}
 537
488538} // namespace WebCore
489539
490540#endif // USE(LEVELDB)

Source/WebCore/platform/leveldb/LevelDBTransaction.h

4343namespace WebCore {
4444
4545class LevelDBDatabase;
 46class LevelDBWriteBatch;
4647
4748using WTF::AVLTree;
4849

@@private:
169170 HashSet<TransactionIterator*> m_iterators;
170171};
171172
 173class LevelDBWriteOnlyTransaction : public RefCounted<LevelDBWriteOnlyTransaction> {
 174public:
 175 static PassRefPtr<LevelDBWriteOnlyTransaction> create(LevelDBDatabase*);
 176
 177 ~LevelDBWriteOnlyTransaction();
 178 bool put(const LevelDBSlice& key, const Vector<char>& value);
 179 bool remove(const LevelDBSlice& key);
 180 bool commit();
 181 void rollback();
 182
 183private:
 184 LevelDBWriteOnlyTransaction(LevelDBDatabase*);
 185
 186 bool set(const LevelDBSlice& key, const Vector<char>& value, bool deleted);
 187
 188 LevelDBDatabase* m_db;
 189 OwnPtr<LevelDBWriteBatch> m_writeBatch;
 190 bool m_finished;
 191};
 192
172193}
173194
174195#endif // USE(LEVELDB)