Changeset 249333 in webkit


Ignore:
Timestamp:
Aug 30, 2019 10:19:38 AM (5 years ago)
Author:
sihui_liu@apple.com
Message:

IndexedDB: update size of database when database operation is completed
https://bugs.webkit.org/show_bug.cgi?id=201057

Reviewed by Youenn Fablet.

Currently when a database operation was completed, we re-computed the disk usage of the origin. This computation
listed all databases in the origin directory and read the size of each database file, which was very inefficient
because the completed operation should only affect one database.

This patch makes UniqueIDBDatabase keep track of database size and reports size change to QuotaUser.

Tested PerformanceTests/IndexedDB/basic/objectstore-add.html on release build minibrowser. This change makes
the test over 50% faster.

  • Modules/indexeddb/server/IDBBackingStore.h:
  • Modules/indexeddb/server/IDBServer.cpp:

(WebCore::IDBServer::IDBServer::QuotaUser::increaseSpaceUsed):
(WebCore::IDBServer::IDBServer::QuotaUser::decreaseSpaceUsed):
(WebCore::IDBServer::IDBServer::computeSpaceUsedForOrigin):
(WebCore::IDBServer::IDBServer::increaseSpaceUsed):
(WebCore::IDBServer::IDBServer::decreaseSpaceUsed):
(WebCore::IDBServer::IDBServer::setSpaceUsed): Deleted.

  • Modules/indexeddb/server/IDBServer.h:
  • Modules/indexeddb/server/MemoryIDBBackingStore.cpp:

(WebCore::IDBServer::MemoryIDBBackingStore::databaseSize const):
(WebCore::IDBServer::MemoryIDBBackingStore::close):
(WebCore::IDBServer::MemoryIDBBackingStore::databasesSizeForOrigin const): Deleted.

  • Modules/indexeddb/server/MemoryIDBBackingStore.h:
  • Modules/indexeddb/server/SQLiteIDBBackingStore.cpp:

(WebCore::IDBServer::SQLiteIDBBackingStore::databasesSizeForDirectory):
(WebCore::IDBServer::SQLiteIDBBackingStore::databaseSize const):
(WebCore::IDBServer::SQLiteIDBBackingStore::close):
(WebCore::IDBServer::SQLiteIDBBackingStore::databasesSizeForFolder): Deleted.
(WebCore::IDBServer::SQLiteIDBBackingStore::databasesSizeForOrigin const): Deleted.

  • Modules/indexeddb/server/SQLiteIDBBackingStore.h:
  • Modules/indexeddb/server/UniqueIDBDatabase.cpp:

(WebCore::IDBServer::UniqueIDBDatabase::deleteBackingStore):
(WebCore::IDBServer::UniqueIDBDatabase::shutdownForClose):
(WebCore::IDBServer::UniqueIDBDatabase::didShutdownForClose):
(WebCore::IDBServer::UniqueIDBDatabase::didDeleteBackingStore):
(WebCore::IDBServer::UniqueIDBDatabase::openBackingStore):
(WebCore::IDBServer::UniqueIDBDatabase::didOpenBackingStore):
(WebCore::IDBServer::UniqueIDBDatabase::postDatabaseTaskReply):
(WebCore::IDBServer::UniqueIDBDatabase::updateSpaceUsedIfNeeded):

  • Modules/indexeddb/server/UniqueIDBDatabase.h:
Location:
trunk/Source/WebCore
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r249332 r249333  
     12019-08-30  Sihui Liu  <sihui_liu@apple.com>
     2
     3        IndexedDB: update size of database when database operation is completed
     4        https://bugs.webkit.org/show_bug.cgi?id=201057
     5
     6        Reviewed by Youenn Fablet.
     7
     8        Currently when a database operation was completed, we re-computed the disk usage of the origin. This computation
     9        listed all databases in the origin directory and read the size of each database file, which was very inefficient
     10        because the completed operation should only affect one database.
     11
     12        This patch makes UniqueIDBDatabase keep track of database size and reports size change to QuotaUser.
     13
     14        Tested PerformanceTests/IndexedDB/basic/objectstore-add.html on release build minibrowser. This change makes
     15        the test over 50% faster.
     16
     17        * Modules/indexeddb/server/IDBBackingStore.h:
     18        * Modules/indexeddb/server/IDBServer.cpp:
     19        (WebCore::IDBServer::IDBServer::QuotaUser::increaseSpaceUsed):
     20        (WebCore::IDBServer::IDBServer::QuotaUser::decreaseSpaceUsed):
     21        (WebCore::IDBServer::IDBServer::computeSpaceUsedForOrigin):
     22        (WebCore::IDBServer::IDBServer::increaseSpaceUsed):
     23        (WebCore::IDBServer::IDBServer::decreaseSpaceUsed):
     24        (WebCore::IDBServer::IDBServer::setSpaceUsed): Deleted.
     25        * Modules/indexeddb/server/IDBServer.h:
     26        * Modules/indexeddb/server/MemoryIDBBackingStore.cpp:
     27        (WebCore::IDBServer::MemoryIDBBackingStore::databaseSize const):
     28        (WebCore::IDBServer::MemoryIDBBackingStore::close):
     29        (WebCore::IDBServer::MemoryIDBBackingStore::databasesSizeForOrigin const): Deleted.
     30        * Modules/indexeddb/server/MemoryIDBBackingStore.h:
     31        * Modules/indexeddb/server/SQLiteIDBBackingStore.cpp:
     32        (WebCore::IDBServer::SQLiteIDBBackingStore::databasesSizeForDirectory):
     33        (WebCore::IDBServer::SQLiteIDBBackingStore::databaseSize const):
     34        (WebCore::IDBServer::SQLiteIDBBackingStore::close):
     35        (WebCore::IDBServer::SQLiteIDBBackingStore::databasesSizeForFolder): Deleted.
     36        (WebCore::IDBServer::SQLiteIDBBackingStore::databasesSizeForOrigin const): Deleted.
     37        * Modules/indexeddb/server/SQLiteIDBBackingStore.h:
     38        * Modules/indexeddb/server/UniqueIDBDatabase.cpp:
     39        (WebCore::IDBServer::UniqueIDBDatabase::deleteBackingStore):
     40        (WebCore::IDBServer::UniqueIDBDatabase::shutdownForClose):
     41        (WebCore::IDBServer::UniqueIDBDatabase::didShutdownForClose):
     42        (WebCore::IDBServer::UniqueIDBDatabase::didDeleteBackingStore):
     43        (WebCore::IDBServer::UniqueIDBDatabase::openBackingStore):
     44        (WebCore::IDBServer::UniqueIDBDatabase::didOpenBackingStore):
     45        (WebCore::IDBServer::UniqueIDBDatabase::postDatabaseTaskReply):
     46        (WebCore::IDBServer::UniqueIDBDatabase::updateSpaceUsedIfNeeded):
     47        * Modules/indexeddb/server/UniqueIDBDatabase.h:
     48
    1492019-08-30  Alicia Boya García  <aboya@igalia.com>
    250
  • trunk/Source/WebCore/Modules/indexeddb/server/IDBBackingStore.h

    r248856 r249333  
    100100    virtual bool isEphemeral() = 0;
    101101
    102     virtual uint64_t databasesSizeForOrigin() const = 0;
     102    virtual void close() = 0;
     103    virtual uint64_t databaseSize() const = 0;
    103104
    104105    virtual bool hasTransaction(const IDBResourceIdentifier&) const = 0;
  • trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.cpp

    r249313 r249333  
    733733}
    734734
     735void IDBServer::QuotaUser::increaseSpaceUsed(uint64_t size)
     736{
     737    if (!m_isInitialized)
     738        return;
     739    ASSERT(m_spaceUsed + size > m_spaceUsed);
     740    m_spaceUsed += size;
     741}
     742void IDBServer::QuotaUser::decreaseSpaceUsed(uint64_t size)
     743{
     744    if (!m_isInitialized)
     745        return;
     746    ASSERT(m_spaceUsed >= size);
     747    m_spaceUsed -= size;
     748}
     749
    735750void IDBServer::QuotaUser::whenInitialized(CompletionHandler<void()>&& callback)
    736751{
     
    773788    auto oldVersionOriginDirectory = IDBDatabaseIdentifier::databaseDirectoryRelativeToRoot(origin.topOrigin, origin.clientOrigin, databaseDirectoryPath, "v0");
    774789    auto newVersionOriginDirectory = IDBDatabaseIdentifier::databaseDirectoryRelativeToRoot(origin.topOrigin, origin.clientOrigin, databaseDirectoryPath, "v1");
    775     auto size = SQLiteIDBBackingStore::databasesSizeForFolder(oldVersionOriginDirectory) + SQLiteIDBBackingStore::databasesSizeForFolder(newVersionOriginDirectory);
     790    auto size = SQLiteIDBBackingStore::databasesSizeForDirectory(oldVersionOriginDirectory) + SQLiteIDBBackingStore::databasesSizeForDirectory(newVersionOriginDirectory);
    776791
    777792    postDatabaseTaskReply(createCrossThreadTask(*this, &IDBServer::finishComputingSpaceUsedForOrigin, origin, size));
     
    800815}
    801816
    802 void IDBServer::setSpaceUsed(const ClientOrigin& origin, uint64_t taskSize)
    803 {
    804     ensureQuotaUser(origin).setSpaceUsed(taskSize);
     817void IDBServer::increaseSpaceUsed(const ClientOrigin& origin, uint64_t size)
     818{
     819    ensureQuotaUser(origin).increaseSpaceUsed(size);
     820}
     821
     822void IDBServer::decreaseSpaceUsed(const ClientOrigin& origin, uint64_t size)
     823{
     824    ensureQuotaUser(origin).decreaseSpaceUsed(size);
    805825}
    806826
  • trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.h

    r249313 r249333  
    117117    void increasePotentialSpaceUsed(const ClientOrigin&, uint64_t taskSize);
    118118    void decreasePotentialSpaceUsed(const ClientOrigin&, uint64_t taskSize);
    119     void setSpaceUsed(const ClientOrigin&, uint64_t spaceUsed);
     119    void increaseSpaceUsed(const ClientOrigin&, uint64_t size);
     120    void decreaseSpaceUsed(const ClientOrigin&, uint64_t size);
    120121    void resetSpaceUsed(const ClientOrigin&);
    121122
     
    161162            m_estimatedSpaceIncrease -= decrease;
    162163        }
     164        void increaseSpaceUsed(uint64_t size);
     165        void decreaseSpaceUsed(uint64_t size);
    163166
    164167        void initializeSpaceUsed(uint64_t spaceUsed);
  • trunk/Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.cpp

    r248846 r249333  
    596596}
    597597
    598 uint64_t MemoryIDBBackingStore::databasesSizeForOrigin() const
     598uint64_t MemoryIDBBackingStore::databaseSize() const
    599599{
    600600    // FIXME: Implement this.
     
    602602}
    603603
     604void MemoryIDBBackingStore::close()
     605{
     606}
     607
    604608} // namespace IDBServer
    605609} // namespace WebCore
  • trunk/Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.h

    r248856 r249333  
    8080    bool isEphemeral() final { return true; }
    8181
    82     uint64_t databasesSizeForOrigin() const final;
    83 
    8482    void removeObjectStoreForVersionChangeAbort(MemoryObjectStore&);
    8583    void restoreObjectStoreForVersionChangeAbort(Ref<MemoryObjectStore>&&);
     
    8987private:
    9088    RefPtr<MemoryObjectStore> takeObjectStoreByIdentifier(uint64_t identifier);
     89   
     90    uint64_t databaseSize() const final;
     91    void close() final;
    9192
    9293    IDBDatabaseIdentifier m_identifier;
  • trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp

    r249313 r249333  
    846846}
    847847
    848 uint64_t SQLiteIDBBackingStore::databasesSizeForFolder(const String& folder)
     848uint64_t SQLiteIDBBackingStore::databasesSizeForDirectory(const String& directory)
    849849{
    850850    uint64_t diskUsage = 0;
    851     for (auto& directory : FileSystem::listDirectory(folder, "*")) {
    852         for (auto& file : FileSystem::listDirectory(directory, "*.sqlite3"_s))
     851    for (auto& dbDirectory : FileSystem::listDirectory(directory, "*")) {
     852        for (auto& file : FileSystem::listDirectory(dbDirectory, "*.sqlite3"_s))
    853853            diskUsage += SQLiteFileSystem::getDatabaseFileSize(file);
    854854    }
     
    856856}
    857857
    858 uint64_t SQLiteIDBBackingStore::databasesSizeForOrigin() const
    859 {
    860     auto databaseRootDirectory = this->databaseRootDirectoryIsolatedCopy();
    861     String oldVersionOriginDirectory = m_identifier.databaseDirectoryRelativeToRoot(databaseRootDirectory, "v0");
    862     String newVersionOriginDirectory = m_identifier.databaseDirectoryRelativeToRoot(databaseRootDirectory, "v1");
    863     return databasesSizeForFolder(oldVersionOriginDirectory) + databasesSizeForFolder(newVersionOriginDirectory);
     858uint64_t SQLiteIDBBackingStore::databaseSize() const
     859{
     860    ASSERT(!isMainThread());
     861    return SQLiteFileSystem::getDatabaseFileSize(fullDatabasePath());
    864862}
    865863
     
    25942592}
    25952593
     2594void SQLiteIDBBackingStore::close()
     2595{
     2596    closeSQLiteDB();
     2597}
     2598
    25962599void SQLiteIDBBackingStore::closeSQLiteDB()
    25972600{
  • trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.h

    r249313 r249333  
    8383    void deleteBackingStore() final;
    8484
    85     uint64_t databasesSizeForOrigin() const final;
    86 
    8785    bool supportsSimultaneousTransactions() final { return false; }
    8886    bool isEphemeral() final { return false; }
     
    9593
    9694    static String databaseNameFromEncodedFilename(const String&);
    97     static uint64_t databasesSizeForFolder(const String& folder);
     95    static uint64_t databasesSizeForDirectory(const String& directory);
    9896
    9997    String databaseDirectory() const { return m_databaseDirectory; };
     
    136134
    137135    void closeSQLiteDB();
     136    void close() final;
     137   
     138    uint64_t databaseSize() const final;
    138139
    139140    enum class SQL : size_t {
  • trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp

    r248899 r249333  
    345345    if (m_backingStore) {
    346346        m_backingStore->deleteBackingStore();
     347        m_newDatabaseSize = m_backingStore->databaseSize();
     348
    347349        m_backingStore = nullptr;
    348350        m_backingStoreSupportsSimultaneousTransactions = false;
     
    350352    } else {
    351353        auto backingStore = m_server->createBackingStore(identifier);
     354        m_currentDatabaseSize = backingStore->databaseSize();
    352355
    353356        IDBDatabaseInfo databaseInfo;
     
    358361        deletedVersion = databaseInfo.version();
    359362        backingStore->deleteBackingStore();
     363        m_newDatabaseSize = backingStore->databaseSize();
    360364    }
    361365
     
    392396
    393397    LOG(IndexedDB, "(db) UniqueIDBDatabase::shutdownForClose");
     398
     399    if (m_backingStore) {
     400        m_backingStore->close();
     401        m_newDatabaseSize = m_backingStore->databaseSize();
     402    }
    394403
    395404    m_backingStore = nullptr;
     
    410419    ASSERT(m_databaseReplyQueue.isEmpty());
    411420    m_databaseReplyQueue.kill();
     421
     422    updateSpaceUsedIfNeeded();
    412423}
    413424
     
    440451        m_currentOpenDBRequest = nullptr;
    441452    }
     453
     454    updateSpaceUsedIfNeeded();
    442455
    443456    m_deleteBackingStoreInProgress = false;
     
    774787    m_backingStoreIsEphemeral = m_backingStore->isEphemeral();
    775788
     789    // QuotaUser should have initiliazed storage usage, which contains the
     790    // size of this database.
     791    m_currentDatabaseSize = m_backingStore->databaseSize();
     792
    776793    IDBDatabaseInfo databaseInfo;
    777794    auto error = m_backingStore->getOrEstablishDatabaseInfo(databaseInfo);
     
    790807    ASSERT(m_isOpeningBackingStore);
    791808    m_isOpeningBackingStore = false;
     809
     810    updateSpaceUsedIfNeeded();
    792811
    793812    if (m_hardClosedForUserDelete)
     
    21112130void UniqueIDBDatabase::postDatabaseTaskReply(CrossThreadTask&& task)
    21122131{
    2113     // FIXME: We might want to compute total size only for modification operations.
    21142132    if (m_backingStore)
    2115         m_databasesSizeForOrigin = m_backingStore->databasesSizeForOrigin();
     2133        m_newDatabaseSize = m_backingStore->databaseSize();
     2134
    21162135    m_databaseReplyQueue.append(WTFMove(task));
    21172136    m_server->postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::executeNextDatabaseTaskReply));
     
    22552274}
    22562275
    2257 void UniqueIDBDatabase::updateSpaceUsedIfNeeded(uint64_t callbackIdentifier)
    2258 {
    2259     auto iterator = m_pendingSpaceIncreasingTasks.find(callbackIdentifier);
    2260     if (iterator == m_pendingSpaceIncreasingTasks.end())
    2261         return;
    2262 
    2263     m_server->decreasePotentialSpaceUsed(m_identifier.origin(), iterator->value);
    2264     m_server->setSpaceUsed(m_identifier.origin(), m_databasesSizeForOrigin);
    2265     m_pendingSpaceIncreasingTasks.remove(iterator);
     2276void UniqueIDBDatabase::updateSpaceUsedIfNeeded(Optional<uint64_t> optionalCallbackIdentifier)
     2277{
     2278    ASSERT(isMainThread());
     2279
     2280    if (optionalCallbackIdentifier) {
     2281        uint64_t callbackIdentifier = optionalCallbackIdentifier.value();
     2282        auto iterator = m_pendingSpaceIncreasingTasks.find(callbackIdentifier);
     2283        if (iterator != m_pendingSpaceIncreasingTasks.end()) {
     2284            m_server->decreasePotentialSpaceUsed(m_identifier.origin(), iterator->value);
     2285            m_pendingSpaceIncreasingTasks.remove(iterator);
     2286        }
     2287    }
     2288
     2289    uint64_t databaseSize = m_newDatabaseSize;
     2290    if (databaseSize != m_currentDatabaseSize) {
     2291        if (databaseSize > m_currentDatabaseSize)
     2292            m_server->increaseSpaceUsed(m_identifier.origin(), databaseSize - m_currentDatabaseSize);
     2293        else
     2294            m_server->decreaseSpaceUsed(m_identifier.origin(), m_currentDatabaseSize - databaseSize);
     2295        m_currentDatabaseSize = databaseSize;
     2296    }
    22662297}
    22672298
  • trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h

    r248856 r249333  
    250250    void requestSpace(uint64_t taskSize, const char* errorMessage, CompletionHandler<void(Optional<IDBError>&&)>&&);
    251251    void waitForRequestSpaceCompletion(CompletionHandler<void(Optional<IDBError>&&)>&&);
    252     void updateSpaceUsedIfNeeded(uint64_t callbackIdentifier);
     252    void updateSpaceUsedIfNeeded(Optional<uint64_t> optionalCallbackIdentifier = WTF::nullopt);
    253253
    254254    Ref<IDBServer> m_server;
     
    304304
    305305    HashMap<uint64_t, uint64_t> m_pendingSpaceIncreasingTasks;
    306     uint64_t m_databasesSizeForOrigin { 0 };
     306    uint64_t m_currentDatabaseSize { 0 };
     307    uint64_t m_newDatabaseSize { 0 };
    307308};
    308309
Note: See TracChangeset for help on using the changeset viewer.