VirtualBox

Changeset 49646 in vbox for trunk/src


Ignore:
Timestamp:
Nov 25, 2013 6:32:18 PM (11 years ago)
Author:
vboxsync
Message:

FE/Qt: Medium enumeration mechanism: Unify/reuse handling code used for different Main events.

Location:
trunk/src/VBox/Frontends/VirtualBox/src/medium
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMedium.cpp

    r49557 r49646  
    366366}
    367367
     368void UIMedium::updateParentID()
     369{
     370    m_strParentID = nullID();
     371    if (m_type == UIMediumType_HardDisk)
     372    {
     373        CMedium parentMedium = m_medium.GetParent();
     374        if (!parentMedium.isNull())
     375            m_strParentID = parentMedium.GetId();
     376    }
     377}
     378
    368379UIMedium UIMedium::parent() const
    369380{
  • trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMedium.h

    r49557 r49646  
    199199
    200200    /* API: Parent/Root stuff: */
     201    void updateParentID();
    201202    QString parentID() const { return m_strParentID; }
    202203    QString rootID() const { return m_strRootID; }
  • trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMediumEnumerator.cpp

    r49645 r49646  
    175175            strMachineID.toAscii().constData()));
    176176
    177     /* Compose a map of previous usage: */
    178     QStringList oldUsage;
    179     foreach (const QString &strMediumID, mediumIDs())
    180     {
    181         const UIMedium &uimedium = m_mediums[strMediumID];
    182         const QList<QString> &machineIDs = uimedium.curStateMachineIds();
    183         if (machineIDs.contains(strMachineID))
    184             oldUsage << strMediumID;
    185     }
    186     LogRel(("UIMediumEnumerator:  Old usage: %s\n", oldUsage.isEmpty() ? "<empty>" : oldUsage.join(", ").toAscii().constData()));
    187 
    188     /* Compose a map of current usage: */
    189     QStringList newUsage;
    190     QMap<QString, CMedium> newMediumMap;
    191     CMachine machine = vboxGlobal().virtualBox().FindMachine(strMachineID);
    192     if (!machine.isNull())
    193     {
    194         foreach (const CMediumAttachment &attachment, machine.GetMediumAttachments())
    195         {
    196             CMedium cmedium = attachment.GetMedium();
    197             if (!cmedium.isNull())
    198             {
    199                 const QString &strMediumID = cmedium.GetId();
    200                 newMediumMap.insert(strMediumID, cmedium);
    201                 newUsage << strMediumID;
    202             }
    203         }
    204     }
    205     LogRel(("UIMediumEnumerator:  New usage: %s\n", newUsage.isEmpty() ? "<empty>" : newUsage.join(", ").toAscii().constData()));
    206 
    207     /* Manipulations over the sets: */
    208     QSet<QString> oldSet = oldUsage.toSet();
    209     QSet<QString> newSet = newUsage.toSet();
     177    /* Gather previously used UIMedium IDs: */
     178    QStringList previousUIMediumIDs;
     179    calculateCachedUsage(strMachineID, previousUIMediumIDs, true);
     180    LogRel(("UIMediumEnumerator:  Old usage: %s\n",
     181            previousUIMediumIDs.isEmpty() ? "<empty>" : previousUIMediumIDs.join(", ").toAscii().constData()));
     182
     183    /* Gather currently used CMediums and their IDs: */
     184    CMediumMap currentCMediums;
     185    QStringList currentCMediumIDs;
     186    calculateActualUsage(strMachineID, currentCMediums, currentCMediumIDs);
     187    LogRel(("UIMediumEnumerator:  New usage: %s\n",
     188            currentCMediumIDs.isEmpty() ? "<empty>" : currentCMediumIDs.join(", ").toAscii().constData()));
     189
     190    /* Determine excluded/included mediums: */
     191    QSet<QString> oldSet = previousUIMediumIDs.toSet();
     192    QSet<QString> newSet = currentCMediumIDs.toSet();
    210193    QSet<QString> excludedSet = oldSet - newSet;
    211194    QSet<QString> includedSet = newSet - oldSet;
     
    213196    QStringList includedList = includedSet.toList();
    214197    if (!excludedList.isEmpty())
    215         LogRel(("UIMediumEnumerator:  Items excluded from machine usage: %s\n", excludedList.join(", ").toAscii().constData()));
     198        LogRel(("UIMediumEnumerator:  Items excluded from usage: %s\n", excludedList.join(", ").toAscii().constData()));
    216199    if (!includedList.isEmpty())
    217         LogRel(("UIMediumEnumerator:  Items included into machine usage: %s\n", includedList.join(", ").toAscii().constData()));
    218 
    219     /* For each of excluded items: */
    220     foreach (const QString &strExcludedMediumID, excludedList)
    221     {
    222         /* Make sure this medium still in our map: */
    223         if (!m_mediums.contains(strExcludedMediumID))
    224             continue;
    225 
    226         /* Get excluded UIMedium: */
    227         const UIMedium &uimedium = m_mediums[strExcludedMediumID];
    228 
    229         /* Delete UIMedium if CMedium was closed already: */
    230         CMedium cmedium = uimedium.medium();
    231         if (cmedium.GetId().isNull() || !cmedium.isOk())
    232         {
    233             /* Delete this medium: */
    234             m_mediums.remove(strExcludedMediumID);
    235             LogRel(("UIMediumEnumerator:  Medium with key={%s} closed and deleted (before enumeration).\n", strExcludedMediumID.toAscii().constData()));
    236             /* And notify listener about delete: */
    237             emit sigMediumDeleted(strExcludedMediumID);
    238             continue;
    239         }
    240 
    241         /* Enumerate UIMedium: */
    242         createMediumEnumerationTask(uimedium);
    243     }
    244 
    245     /* For each of included items: */
    246     foreach (const QString &strIncludedMediumID, includedList)
    247     {
    248         /* Create UIMedium if it is not in our map: */
    249         if (!m_mediums.contains(strIncludedMediumID))
    250         {
    251             /* Insert medium: */
    252             const CMedium &cmedium = newMediumMap[strIncludedMediumID];
    253             UIMedium uimedium(cmedium, UIMediumDefs::mediumTypeToLocal(cmedium.GetDeviceType()));
    254             m_mediums[strIncludedMediumID] = uimedium;
    255             LogRel(("UIMediumEnumerator:  Medium with key={%s} created and inserted.\n", strIncludedMediumID.toAscii().constData()));
    256             /* And notify listener about creation: */
    257             emit sigMediumCreated(strIncludedMediumID);
    258         }
    259 
    260         /* Enumerate UIMedium: */
    261         createMediumEnumerationTask(m_mediums[strIncludedMediumID]);
    262     }
     200        LogRel(("UIMediumEnumerator:  Items included into usage: %s\n", includedList.join(", ").toAscii().constData()));
     201
     202    /* Update cache for excluded UIMediums: */
     203    recacheFromCachedUsage(excludedList);
     204
     205    /* Update cache for included CMediums: */
     206    recacheFromActualUsage(currentCMediums, includedList);
    263207
    264208    LogRel(("UIMediumEnumerator: Machine (or snapshot) event processed, ID = %s\n",
     
    272216            strMachineID.toAscii().constData()));
    273217
    274     /* Was machine registered? */
     218    /* Machine was registered: */
    275219    if (fRegistered)
    276220    {
    277         /* Compose a map of current usage: */
    278         QStringList usage;
    279         QMap<QString, CMedium> mediumMap;
    280         CMachine machine = vboxGlobal().virtualBox().FindMachine(strMachineID);
    281         if (!machine.isNull())
    282         {
    283             foreach (const CMediumAttachment &attachment, machine.GetMediumAttachments())
    284             {
    285                 CMedium cmedium = attachment.GetMedium();
    286                 if (!cmedium.isNull())
    287                 {
    288                     const QString &strMediumID = cmedium.GetId();
    289                     mediumMap.insert(strMediumID, cmedium);
    290                     usage << strMediumID;
    291                 }
    292             }
    293         }
    294         LogRel(("UIMediumEnumerator:  Usage: %s\n", usage.isEmpty() ? "<empty>" : usage.join(", ").toAscii().constData()));
    295 
    296         /* For each of related items: */
    297         foreach (const QString &strMediumID, usage)
    298         {
    299             /* Create UIMedium if it is not in our map: */
    300             if (!m_mediums.contains(strMediumID))
    301             {
    302                 /* Insert medium: */
    303                 const CMedium &cmedium = mediumMap[strMediumID];
    304                 UIMedium uimedium(cmedium, UIMediumDefs::mediumTypeToLocal(cmedium.GetDeviceType()));
    305                 m_mediums[strMediumID] = uimedium;
    306                 LogRel(("UIMediumEnumerator:  Medium with key={%s} created and inserted.\n", strMediumID.toAscii().constData()));
    307                 /* And notify listener about creation: */
    308                 emit sigMediumCreated(strMediumID);
    309             }
    310 
    311             /* Enumerate UIMedium: */
    312             createMediumEnumerationTask(m_mediums[strMediumID]);
    313         }
    314     }
    315 
    316     /* Was machine unregistered? */
     221        /* Gather currently used CMediums and their IDs: */
     222        CMediumMap currentCMediums;
     223        QStringList currentCMediumIDs;
     224        calculateActualUsage(strMachineID, currentCMediums, currentCMediumIDs);
     225        LogRel(("UIMediumEnumerator:  New usage: %s\n",
     226                currentCMediumIDs.isEmpty() ? "<empty>" : currentCMediumIDs.join(", ").toAscii().constData()));
     227        /* Update cache with currently used CMediums: */
     228        recacheFromActualUsage(currentCMediums, currentCMediumIDs);
     229    }
     230    /* Machine was unregistered: */
    317231    else
    318232    {
    319         /* Compose a map of previous usage: */
    320         QStringList usage;
    321         foreach (const QString &strMediumID, mediumIDs())
    322         {
    323             const UIMedium &uimedium = m_mediums[strMediumID];
    324             const QList<QString> &machineIDs = uimedium.machineIds();
    325             if (machineIDs.contains(strMachineID))
    326                 usage << strMediumID;
    327         }
    328         LogRel(("UIMediumEnumerator:  Usage: %s\n", usage.isEmpty() ? "<empty>" : usage.join(", ").toAscii().constData()));
    329 
    330         /* For each of related items: */
    331         foreach (const QString &strMediumID, usage)
    332         {
    333             /* Make sure this medium still in our map: */
    334             if (!m_mediums.contains(strMediumID))
    335                 continue;
    336 
    337             /* Get excluded UIMedium: */
    338             const UIMedium &uimedium = m_mediums[strMediumID];
    339 
    340             /* Delete UIMedium if CMedium was closed already: */
    341             CMedium cmedium = uimedium.medium();
    342             if (cmedium.GetId().isNull() || !cmedium.isOk())
    343             {
    344                 /* Delete this medium: */
    345                 m_mediums.remove(strMediumID);
    346                 LogRel(("UIMediumEnumerator:  Medium with key={%s} closed and deleted (before enumeration).\n", strMediumID.toAscii().constData()));
    347                 /* And notify listener about delete: */
    348                 emit sigMediumDeleted(strMediumID);
    349                 continue;
    350             }
    351 
    352             /* Enumerate UIMedium: */
    353             createMediumEnumerationTask(uimedium);
    354         }
     233        /* Gather previously used UIMedium IDs: */
     234        QStringList previousUIMediumIDs;
     235        calculateCachedUsage(strMachineID, previousUIMediumIDs, false /* take into account current state only */);
     236        LogRel(("UIMediumEnumerator:  Old usage: %s\n",
     237                previousUIMediumIDs.isEmpty() ? "<empty>" : previousUIMediumIDs.join(", ").toAscii().constData()));
     238        /* Update cache for previously used UIMediums: */
     239        recacheFromCachedUsage(previousUIMediumIDs);
    355240    }
    356241
     
    485370}
    486371
     372/**
     373 * Calculates last known UIMedium <i>usage</i> based on cached data.
     374 * @param strMachineID describes the machine we are calculating <i>usage</i> for.
     375 * @param previousUIMediumIDs receives UIMedium IDs used in cached data.
     376 * @param fTakeIntoAccountCurrentStateOnly defines whether we should take into accound current VM state only.
     377 */
     378void UIMediumEnumerator::calculateCachedUsage(const QString &strMachineID, QStringList &previousUIMediumIDs, bool fTakeIntoAccountCurrentStateOnly) const
     379{
     380    /* For each the UIMedium ID cache have: */
     381    foreach (const QString &strMediumID, mediumIDs())
     382    {
     383        /* Get corresponding UIMedium: */
     384        const UIMedium &uimedium = m_mediums[strMediumID];
     385        /* Get the list of the machines this UIMedium attached to.
     386         * Take into account current-state only if necessary. */
     387        const QList<QString> &machineIDs = fTakeIntoAccountCurrentStateOnly ?
     388                                           uimedium.curStateMachineIds() : uimedium.machineIds();
     389        /* Add this UIMedium ID to previous usage if necessary: */
     390        if (machineIDs.contains(strMachineID))
     391            previousUIMediumIDs << strMediumID;
     392    }
     393}
     394
     395/**
     396 * Calculates new CMedium <i>usage</i> based on actual data.
     397 * @param strMachineID describes the machine we are calculating <i>usage</i> for.
     398 * @param currentCMediums receives CMedium used in actual data.
     399 * @param currentCMediumIDs receives CMedium IDs used in actual data.
     400 */
     401void UIMediumEnumerator::calculateActualUsage(const QString &strMachineID, CMediumMap &currentCMediums, QStringList &currentCMediumIDs) const
     402{
     403    /* Search for corresponding machine: */
     404    CMachine machine = vboxGlobal().virtualBox().FindMachine(strMachineID);
     405    AssertReturnVoid(!machine.isNull());
     406
     407    /* For each the attachment machine have: */
     408    foreach (const CMediumAttachment &attachment, machine.GetMediumAttachments())
     409    {
     410        /* Get corresponding CMedium: */
     411        CMedium cmedium = attachment.GetMedium();
     412        if (!cmedium.isNull())
     413        {
     414            /* Make sure that CMedium was not yet closed: */
     415            const QString strCMediumID = cmedium.GetId();
     416            if (cmedium.isOk() && !strCMediumID.isNull())
     417            {
     418                /* Add this CMedium to current usage: */
     419                currentCMediums.insert(strCMediumID, cmedium);
     420                currentCMediumIDs << strCMediumID;
     421            }
     422        }
     423    }
     424}
     425
     426/**
     427 * Updates cache using known changes in cached data.
     428 * @param previousUIMediumIDs reflects UIMedium IDs used in cached data.
     429 */
     430void UIMediumEnumerator::recacheFromCachedUsage(const QStringList &previousUIMediumIDs)
     431{
     432    /* For each of previously used UIMedium ID: */
     433    foreach (const QString &strMediumID, previousUIMediumIDs)
     434    {
     435        /* Make sure this ID still in our map: */
     436        if (m_mediums.contains(strMediumID))
     437        {
     438            /* Get corresponding UIMedium: */
     439            UIMedium &uimedium = m_mediums[strMediumID];
     440
     441            /* If corresponding CMedium still exists: */
     442            CMedium cmedium = uimedium.medium();
     443            if (!cmedium.GetId().isNull() && cmedium.isOk())
     444            {
     445                /* Refresh UIMedium parent first of all: */
     446                uimedium.updateParentID();
     447                /* Enumerate corresponding UIMedium: */
     448                createMediumEnumerationTask(uimedium);
     449            }
     450            /* If corresponding CMedium was closed already: */
     451            else
     452            {
     453                /* Uncache corresponding UIMedium: */
     454                m_mediums.remove(strMediumID);
     455                LogRel(("UIMediumEnumerator:  Medium with key={%s} uncached.\n", strMediumID.toAscii().constData()));
     456
     457                /* And notify listeners: */
     458                emit sigMediumDeleted(strMediumID);
     459            }
     460        }
     461    }
     462}
     463
     464/**
     465 * Updates cache using known changes in actual data.
     466 * @param currentCMediums reflects CMedium used in actual data.
     467 * @param currentCMediumIDs reflects CMedium IDs used in actual data.
     468 */
     469void UIMediumEnumerator::recacheFromActualUsage(const CMediumMap &currentCMediums, const QStringList &currentCMediumIDs)
     470{
     471    /* For each of currently used CMedium ID: */
     472    foreach (const QString &strCMediumID, currentCMediumIDs)
     473    {
     474        /* If that ID is not in our map: */
     475        if (!m_mediums.contains(strCMediumID))
     476        {
     477            /* Create new UIMedium: */
     478            const CMedium &cmedium = currentCMediums[strCMediumID];
     479            UIMedium uimedium(cmedium, UIMediumDefs::mediumTypeToLocal(cmedium.GetDeviceType()));
     480            QString strUIMediumKey = uimedium.key();
     481
     482            /* Cache created UIMedium: */
     483            m_mediums.insert(strUIMediumKey, uimedium);
     484            LogRel(("UIMediumEnumerator:  Medium with key={%s} cached.\n", strUIMediumKey.toAscii().constData()));
     485
     486            /* And notify listeners: */
     487            emit sigMediumCreated(strUIMediumKey);
     488        }
     489
     490        /* Enumerate corresponding UIMedium: */
     491        createMediumEnumerationTask(m_mediums[strCMediumID]);
     492    }
     493}
     494
    487495
    488496#include "UIMediumEnumerator.moc"
  • trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMediumEnumerator.h

    r49589 r49646  
    2727class UIThreadPool;
    2828class UITask;
     29
     30/* Typedefs: */
     31typedef QMap<QString, CMedium> CMediumMap;
    2932
    3033/* Medium-enumerator prototype.
     
    7982    void addHardDisksToMap(const CMediumVector &inputMediums, UIMediumMap &outputMediums);
    8083
     84    /* Helpers: Medium re-caching stuff: */
     85    void calculateCachedUsage(const QString &strMachineID, QStringList &previousUIMediumIDs, bool fTakeIntoAccountCurrentStateOnly) const;
     86    void calculateActualUsage(const QString &strMachineID, CMediumMap &currentCMediums, QStringList &currentCMediumIDs) const;
     87    void recacheFromCachedUsage(const QStringList &previousUIMediumIDs);
     88    void recacheFromActualUsage(const CMediumMap &currentCMediums, const QStringList &currentCMediumIDs);
     89
    8190    /* Variables: */
    8291    UIThreadPool *m_pThreadPool;
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette