# Global Metrics

path: .metrics.nexits.average
old: 2.0142857142857142
new: 0.25
path: .metrics.nexits.sum
old: 141.0
new: 2.0
path: .metrics.nargs.sum
old: 132.0
new: 4.0
path: .metrics.nargs.average
old: 1.8857142857142857
new: 0.5
path: .metrics.nom.functions
old: 70.0
new: 8.0
path: .metrics.nom.total
old: 70.0
new: 8.0
path: .metrics.cyclomatic.average
old: 3.019704433497537
new: 1.4545454545454546
path: .metrics.cyclomatic.sum
old: 613.0
new: 16.0
path: .metrics.halstead.n1
old: 44.0
new: 20.0
path: .metrics.halstead.purity_ratio
old: 0.8659731102324333
new: 1.3057665717171565
path: .metrics.halstead.n2
old: 1675.0
new: 59.0
path: .metrics.halstead.effort
old: 29494288.666020885
new: 45759.0376072761
path: .metrics.halstead.volume
old: 225619.19894223296
new: 2092.8552083947984
path: .metrics.halstead.time
old: 1638571.592556716
new: 2542.168755959783
path: .metrics.halstead.N1
old: 11040.0
new: 203.0
path: .metrics.halstead.estimated_program_length
old: 18179.373503109473
new: 433.5145018100959
path: .metrics.halstead.vocabulary
old: 1719.0
new: 79.0
path: .metrics.halstead.level
old: 0.007649589433976051
new: 0.04573643410852713
path: .metrics.halstead.N2
old: 9953.0
new: 129.0
path: .metrics.halstead.bugs
old: 31.820282397066077
new: 0.42644530093727623
path: .metrics.halstead.difficulty
old: 130.72597014925373
new: 21.864406779661017
path: .metrics.halstead.length
old: 20993.0
new: 332.0
path: .metrics.cognitive.sum
old: 222.0
new: 6.0
path: .metrics.cognitive.average
old: 3.1714285714285713
new: 0.75
path: .metrics.loc.cloc
old: 509.0
new: 21.0
path: .metrics.loc.sloc
old: 3783.0
new: 124.0
path: .metrics.loc.blank
old: 548.0
new: 22.0
path: .metrics.loc.lloc
old: 1010.0
new: 21.0
path: .metrics.loc.ploc
old: 2726.0
new: 81.0
path: .metrics.mi.mi_sei
old: -228.09818648550748
new: 27.06033083280625
path: .metrics.mi.mi_visual_studio
old: 0.0
new: 28.930268434864814
path: .metrics.mi.mi_original
old: -167.54835678178793
new: 49.47075902361884

# Spaces Data

## Minimal test - lines (54, 122)

path: .spaces[1].metrics.cyclomatic.average
old: 1.0
new: 1.625
path: .spaces[1].metrics.cyclomatic.sum
old: 1.0
new: 13.0
path: .spaces[1].metrics.halstead.volume
old: 193.26196660226543
new: 1394.1994768403622
path: .spaces[1].metrics.halstead.n2
old: 17.0
new: 38.0
path: .spaces[1].metrics.halstead.level
old: 0.5
new: 0.04130434782608696
path: .spaces[1].metrics.halstead.estimated_program_length
old: 77.48686830125577
new: 285.8598074086035
path: .spaces[1].metrics.halstead.vocabulary
old: 21.0
new: 58.0
path: .spaces[1].metrics.halstead.time
old: 21.47355184469616
new: 1875.239062416861
path: .spaces[1].metrics.halstead.n1
old: 4.0
new: 20.0
path: .spaces[1].metrics.halstead.length
old: 44.0
new: 238.0
path: .spaces[1].metrics.halstead.N1
old: 27.0
new: 146.0
path: .spaces[1].metrics.halstead.purity_ratio
old: 1.7610651886649038
new: 1.2010916277672417
path: .spaces[1].metrics.halstead.effort
old: 386.5239332045309
new: 33754.3031235035
path: .spaces[1].metrics.halstead.bugs
old: 0.017687359596150577
new: 0.34814875201072787
path: .spaces[1].metrics.halstead.N2
old: 17.0
new: 92.0
path: .spaces[1].metrics.halstead.difficulty
old: 2.0
new: 24.210526315789473
path: .spaces[1].metrics.nexits.sum
old: 0.0
new: 1.0
path: .spaces[1].metrics.nexits.average
old: null
new: 0.14285714285714285
path: .spaces[1].metrics.nargs.sum
old: 0.0
new: 4.0
path: .spaces[1].metrics.nargs.average
old: null
new: 0.5714285714285714
path: .spaces[1].metrics.nom.functions
old: 0.0
new: 7.0
path: .spaces[1].metrics.nom.total
old: 0.0
new: 7.0
path: .spaces[1].metrics.mi.mi_sei
old: 82.18937417692922
new: 41.27500061639172
path: .spaces[1].metrics.mi.mi_visual_studio
old: 45.06934253100026
new: 36.12226964964965
path: .spaces[1].metrics.mi.mi_original
old: 77.06857572801044
new: 61.769081100900905
path: .spaces[1].metrics.cognitive.average
old: null
new: 0.8571428571428571
path: .spaces[1].metrics.cognitive.sum
old: 0.0
new: 6.0
path: .spaces[1].metrics.loc.sloc
old: 60.0
new: 69.0
path: .spaces[1].metrics.loc.blank
old: 6.0
new: 9.0
path: .spaces[1].metrics.loc.cloc
old: 36.0
new: 9.0
path: .spaces[1].metrics.loc.ploc
old: 18.0
new: 51.0
path: .spaces[1].metrics.loc.lloc
old: 0.0
new: 20.0

### Code

    class nsCategoryCache final {
     public:
      explicit nsCategoryCache(const char* aCategory) : mCategoryName(aCategory) {
        MOZ_ASSERT(NS_IsMainThread());
      }
      ~nsCategoryCache() {
        MOZ_ASSERT(NS_IsMainThread());
        if (mObserver) {
          mObserver->ListenerDied();
        }
      }

      void GetEntries(nsCOMArray& aResult) {
        MOZ_ASSERT(NS_IsMainThread());
        LazyInit();

        AddEntries(aResult);
      }

      /**
       * This function returns an nsCOMArray of interface pointers to the cached
       * category enries for the requested category.  This was added in order to be
       * used in call sites where the overhead of excessive allocations can be
       * unacceptable.  See bug 1360971 for an example.
       */
      const nsCOMArray& GetCachedEntries() {
        MOZ_ASSERT(NS_IsMainThread());
        LazyInit();

        if (mCachedEntries.IsEmpty()) {
          AddEntries(mCachedEntries);
        }
        return mCachedEntries;
      }

     private:
      void LazyInit() {
        // Lazy initialization, so that services in this category can't
        // cause reentrant getService (bug 386376)
        if (!mObserver) {
          mObserver = new nsCategoryObserver(mCategoryName);
          mObserver->SetListener(nsCategoryCache::OnCategoryChanged, this);
        }
      }

      void AddEntries(nsCOMArray& aResult) {
        for (auto iter = mObserver->GetHash().Iter(); !iter.Done(); iter.Next()) {
          nsISupports* entry = iter.UserData();
          nsCOMPtr service = do_QueryInterface(entry);
          if (service) {
            aResult.AppendElement(service.forget());
          }
        }
      }

      static void OnCategoryChanged(void* aClosure) {
        MOZ_ASSERT(NS_IsMainThread());
        auto self = static_cast*>(aClosure);
        self->mCachedEntries.Clear();
      }

     private:
      // Not to be implemented
      nsCategoryCache(const nsCategoryCache&);

      nsCString mCategoryName;
      RefPtr mObserver;
      nsCOMArray mCachedEntries;
    };

## Minimal test - lines (22, 44)

path: .spaces[0].metrics.cyclomatic.sum
old: 1.0
new: 2.0
path: .spaces[0].metrics.nexits.sum
old: 0.0
new: 1.0
path: .spaces[0].metrics.nexits.average
old: null
new: 1.0
path: .spaces[0].metrics.nargs.average
old: null
new: 0.0
path: .spaces[0].metrics.nom.functions
old: 0.0
new: 1.0
path: .spaces[0].metrics.nom.total
old: 0.0
new: 1.0
path: .spaces[0].metrics.halstead.vocabulary
old: 1.0
new: 33.0
path: .spaces[0].metrics.halstead.effort
old: 0.0
new: 3113.111799375503
path: .spaces[0].metrics.halstead.purity_ratio
old: null
new: 1.690727698587598
path: .spaces[0].metrics.halstead.N2
old: 1.0
new: 27.0
path: .spaces[0].metrics.halstead.bugs
old: 0.0
new: 0.07106818490699429
path: .spaces[0].metrics.halstead.difficulty
old: 0.0
new: 7.714285714285714
path: .spaces[0].metrics.halstead.estimated_program_length
old: null
new: 135.25821588700785
path: .spaces[0].metrics.halstead.N1
old: 0.0
new: 53.0
path: .spaces[0].metrics.halstead.time
old: 0.0
new: 172.95065552086126
path: .spaces[0].metrics.halstead.n1
old: 0.0
new: 12.0
path: .spaces[0].metrics.halstead.n2
old: 1.0
new: 21.0
path: .spaces[0].metrics.halstead.volume
old: 0.0
new: 403.5515295486763
path: .spaces[0].metrics.halstead.length
old: 1.0
new: 80.0
path: .spaces[0].metrics.halstead.level
old: null
new: 0.12962962962962962
path: .spaces[0].metrics.mi.mi_visual_studio
old: null
new: 51.77977306126645
path: .spaces[0].metrics.mi.mi_original
old: null
new: 88.54341193476563
path: .spaces[0].metrics.mi.mi_sei
old: null
new: 52.2439290284712
path: .spaces[0].metrics.cognitive.average
old: null
new: 0.0
path: .spaces[0].metrics.loc.ploc
old: 1.0
new: 19.0
path: .spaces[0].metrics.loc.blank
old: 0.0
new: 4.0
path: .spaces[0].metrics.loc.sloc
old: 1.0
new: 23.0
path: .spaces[0].metrics.loc.lloc
old: 0.0
new: 1.0

### Code

    class nsCategoryObserver final : public nsIObserver {
      ~nsCategoryObserver();

     public:
      explicit nsCategoryObserver(const nsACString& aCategory);

      void ListenerDied();
      void SetListener(void(aCallback)(void*), void* aClosure);
      nsInterfaceHashtable& GetHash() {
        return mHash;
      }

      NS_DECL_ISUPPORTS
      NS_DECL_NSIOBSERVER
     private:
      void RemoveObservers();

      nsInterfaceHashtable mHash;
      nsCString mCategory;
      void (*mCallback)(void*);
      void* mClosure;
      bool mObserversRemoved;
    };