Global Metrics

path: .metrics.nargs.average
old: 1.2857142857142858
new: 1.125

path: .metrics.nexits.average
old: 1.0
new: 1.625

path: .metrics.nexits.sum
old: 7.0
new: 13.0

path: .metrics.nom.total
old: 7.0
new: 8.0

path: .metrics.nom.functions
old: 7.0
new: 8.0

path: .metrics.loc.cloc
old: 4.0
new: 32.0

path: .metrics.loc.blank
old: 16.0
new: 44.0

path: .metrics.loc.ploc
old: 67.0
new: 144.0

path: .metrics.loc.sloc
old: 87.0
new: 220.0

path: .metrics.loc.lloc
old: 31.0
new: 68.0

path: .metrics.cognitive.average
old: 1.0
new: 2.75

path: .metrics.cognitive.sum
old: 7.0
new: 22.0

path: .metrics.cyclomatic.average
old: 1.625
new: 2.636363636363636

path: .metrics.cyclomatic.sum
old: 13.0
new: 29.0

path: .metrics.halstead.time
old: 2067.978116302355
new: 4891.340962546153

path: .metrics.halstead.volume
old: 1974.092408330412
new: 3963.891896920519

path: .metrics.halstead.n1
old: 19.0
new: 20.0

path: .metrics.halstead.N2
old: 131.0
new: 231.0

path: .metrics.halstead.N1
old: 177.0
new: 339.0

path: .metrics.halstead.n2
old: 66.0
new: 104.0

path: .metrics.halstead.difficulty
old: 18.85606060606061
new: 22.21153846153846

path: .metrics.halstead.vocabulary
old: 85.0
new: 124.0

path: .metrics.halstead.effort
old: 37223.60609344239
new: 88044.13732583074

path: .metrics.halstead.level
old: 0.05303334672559261
new: 0.045021645021645025

path: .metrics.halstead.purity_ratio
old: 1.55727478776976
new: 1.3741829694463523

path: .metrics.halstead.bugs
old: 0.3716131221703835
new: 0.6596988195322527

path: .metrics.halstead.estimated_program_length
old: 479.6406346330861
new: 783.2842925844208

path: .metrics.halstead.length
old: 308.0
new: 570.0

path: .metrics.mi.mi_visual_studio
old: 32.86865234697531
new: 19.807794915194183

path: .metrics.mi.mi_original
old: 56.20539551332779
new: 33.871329304982055

path: .metrics.mi.mi_sei
old: 23.015373736850904
new: 3.9708285663079823

Spaces Data

Minimal test - lines (37, 220)

path: .spaces[0].metrics.cyclomatic.average
old: 1.0
new: 2.8

path: .spaces[0].metrics.cyclomatic.sum
old: 1.0
new: 28.0

path: .spaces[0].metrics.halstead.volume
old: 57.3594000115385
new: 3744.278250365938

path: .spaces[0].metrics.halstead.difficulty
old: 3.5
new: 23.333333333333332

path: .spaces[0].metrics.halstead.effort
old: 200.75790004038475
new: 87366.49250853855

path: .spaces[0].metrics.halstead.length
old: 16.0
new: 549.0

path: .spaces[0].metrics.halstead.n2
old: 6.0
new: 93.0

path: .spaces[0].metrics.halstead.time
old: 11.153216668910265
new: 4853.694028252142

path: .spaces[0].metrics.halstead.purity_ratio
old: 1.938721875540867
new: 1.2651736454112823

path: .spaces[0].metrics.halstead.bugs
old: 0.011428621282029669
new: 0.656309482292443

path: .spaces[0].metrics.halstead.N2
old: 7.0
new: 217.0

path: .spaces[0].metrics.halstead.estimated_program_length
old: 31.019550008653873
new: 694.5803313307941

path: .spaces[0].metrics.halstead.n1
old: 6.0
new: 20.0

path: .spaces[0].metrics.halstead.N1
old: 9.0
new: 332.0

path: .spaces[0].metrics.halstead.level
old: 0.2857142857142857
new: 0.04285714285714286

path: .spaces[0].metrics.halstead.vocabulary
old: 12.0
new: 113.0

path: .spaces[0].metrics.nargs.average
old: 1.0
new: 1.125

path: .spaces[0].metrics.nargs.sum
old: 1.0
new: 9.0

path: .spaces[0].metrics.mi.mi_original
old: 138.4844646467577
new: 37.292523126745834

path: .spaces[0].metrics.mi.mi_sei
old: 124.191818253432
new: 4.242074460347954

path: .spaces[0].metrics.mi.mi_visual_studio
old: 80.98506704488753
new: 21.808493056576513

path: .spaces[0].metrics.nom.total
old: 1.0
new: 8.0

path: .spaces[0].metrics.nom.functions
old: 1.0
new: 8.0

path: .spaces[0].metrics.nexits.average
old: 0.0
new: 1.625

path: .spaces[0].metrics.nexits.sum
old: 0.0
new: 13.0

path: .spaces[0].metrics.cognitive.average
old: 0.0
new: 2.75

path: .spaces[0].metrics.cognitive.sum
old: 0.0
new: 22.0

path: .spaces[0].metrics.loc.sloc
old: 2.0
new: 184.0

path: .spaces[0].metrics.loc.blank
old: 0.0
new: 38.0

path: .spaces[0].metrics.loc.cloc
old: 0.0
new: 18.0

path: .spaces[0].metrics.loc.lloc
old: 0.0
new: 68.0

path: .spaces[0].metrics.loc.ploc
old: 2.0
new: 128.0

Code

namespace mozilla {
namespace docshell {

//-----------------------------------------------------------------------------
// OfflineCacheUpdateGlue::nsISupports
//-----------------------------------------------------------------------------

NS_IMPL_ISUPPORTS(OfflineCacheUpdateGlue, nsIOfflineCacheUpdate,
                  nsIOfflineCacheUpdateObserver, nsISupportsWeakReference)

//-----------------------------------------------------------------------------
// OfflineCacheUpdateGlue 
//-----------------------------------------------------------------------------

OfflineCacheUpdateGlue::OfflineCacheUpdateGlue() : mCoalesced(false) {
  LOG(("OfflineCacheUpdateGlue::OfflineCacheUpdateGlue [%p]", this));
}

OfflineCacheUpdateGlue::~OfflineCacheUpdateGlue() {
  LOG(("OfflineCacheUpdateGlue::~OfflineCacheUpdateGlue [%p]", this));
}

nsIOfflineCacheUpdate* OfflineCacheUpdateGlue::EnsureUpdate() {
  if (!mUpdate) {
    mUpdate = new nsOfflineCacheUpdate();
    LOG(("OfflineCacheUpdateGlue [%p] is using update [%p]", this,
         mUpdate.get()));

    mUpdate->SetCookieJarSettings(mCookieJarSettings);
  }

  return mUpdate;
}

NS_IMETHODIMP
OfflineCacheUpdateGlue::Schedule() {
  nsCOMPtr observerService =
      mozilla::services::GetObserverService();
  if (observerService) {
    LOG(("Calling offline-cache-update-added"));
    observerService->NotifyObservers(static_cast(this),
                                     "offline-cache-update-added", nullptr);
    LOG(("Done offline-cache-update-added"));
  }

  if (!EnsureUpdate()) return NS_ERROR_NULL_POINTER;

  // Do not use weak reference, we must survive!
  mUpdate->AddObserver(this, false);

  if (mCoalesced)  // already scheduled
    return NS_OK;

  return mUpdate->Schedule();
}

NS_IMETHODIMP
OfflineCacheUpdateGlue::Init(nsIURI* aManifestURI, nsIURI* aDocumentURI,
                             nsIPrincipal* aLoadingPrincipal,
                             Document* aDocument, nsIFile* aCustomProfileDir) {
  nsresult rv;

  nsAutoCString originSuffix;
  rv = aLoadingPrincipal->GetOriginSuffix(originSuffix);
  NS_ENSURE_SUCCESS(rv, rv);

  nsOfflineCacheUpdateService* service =
      nsOfflineCacheUpdateService::EnsureService();
  if (service) {
    service->FindUpdate(aManifestURI, originSuffix, aCustomProfileDir,
                        getter_AddRefs(mUpdate));
    mCoalesced = !!mUpdate;
  }

  if (!EnsureUpdate()) return NS_ERROR_NULL_POINTER;

  mDocumentURI = aDocumentURI;
  mLoadingPrincipal = aLoadingPrincipal;

  if (aDocument) SetDocument(aDocument);

  if (mCoalesced) {  // already initialized
    LOG(("OfflineCacheUpdateGlue %p coalesced with update %p", this,
         mUpdate.get()));
    return NS_OK;
  }

  rv = mUpdate->Init(aManifestURI, aDocumentURI, aLoadingPrincipal, nullptr,
                     aCustomProfileDir);

  mUpdate->SetCookieJarSettings(mCookieJarSettings);

  return rv;
}

void OfflineCacheUpdateGlue::SetDocument(Document* aDocument) {
  // The design is one document for one cache update on the content process.
  NS_ASSERTION(!mDocument,
               "Setting more then a single document on an instance of "
               "OfflineCacheUpdateGlue");

  LOG(("Document %p added to update glue %p", aDocument, this));

  // Add document only if it was not loaded from an offline cache.
  // If it were loaded from an offline cache then it has already
  // been associated with it and must not be again cached as
  // implicit (which are the reasons we collect documents here).
  if (!aDocument) return;

  mCookieJarSettings = aDocument->CookieJarSettings();

  nsIChannel* channel = aDocument->GetChannel();
  nsCOMPtr appCacheChannel =
      do_QueryInterface(channel);
  if (!appCacheChannel) return;

  bool loadedFromAppCache;
  appCacheChannel->GetLoadedFromApplicationCache(&loadedFromAppCache);
  if (loadedFromAppCache) return;

  if (EnsureUpdate()) {
    mUpdate->StickDocument(mDocumentURI);
  }

  mDocument = aDocument;
}

NS_IMETHODIMP
OfflineCacheUpdateGlue::UpdateStateChanged(nsIOfflineCacheUpdate* aUpdate,
                                           uint32_t state) {
  if (state == nsIOfflineCacheUpdateObserver::STATE_FINISHED) {
    LOG(("OfflineCacheUpdateGlue got STATE_FINISHED [%p]", this));

    nsCOMPtr observerService =
        mozilla::services::GetObserverService();
    if (observerService) {
      LOG(("Calling offline-cache-update-completed"));
      observerService->NotifyObservers(
          static_cast(this),
          "offline-cache-update-completed", nullptr);
      LOG(("Done offline-cache-update-completed"));
    }

    aUpdate->RemoveObserver(this);
  }

  return NS_OK;
}

NS_IMETHODIMP
OfflineCacheUpdateGlue::ApplicationCacheAvailable(
    nsIApplicationCache* aApplicationCache) {
  NS_ENSURE_ARG(aApplicationCache);

  // Check that the document that requested this update was
  // previously associated with an application cache.  If not, it
  // should be associated with the new one.
  if (!mDocument) {
    return NS_OK;
  }

  nsCOMPtr existingCache;
  nsresult rv = mDocument->GetApplicationCache(getter_AddRefs(existingCache));
  NS_ENSURE_SUCCESS(rv, rv);

  if (!existingCache) {
    if (LOG_ENABLED()) {
      nsAutoCString clientID;
      if (aApplicationCache) {
        aApplicationCache->GetClientID(clientID);
      }
      LOG(("Update %p: associating app cache %s to document %p", this,
           clientID.get(), mDocument.get()));
    }

    rv = mDocument->SetApplicationCache(aApplicationCache);
    NS_ENSURE_SUCCESS(rv, rv);
  }

  return NS_OK;
}

}  // namespace docshell
}  // namespace mozilla