# Global Metrics

path: .metrics.halstead.level
old: 0.04278462654097172
new: 0.015497076023391817
path: .metrics.halstead.n1
old: 14.0
new: 30.0
path: .metrics.halstead.bugs
old: 0.5314237085626363
new: 1.3391459714398186
path: .metrics.halstead.estimated_program_length
old: 400.3789088211551
new: 450.7865019601051
path: .metrics.halstead.length
old: 440.0
new: 619.0
path: .metrics.halstead.N1
old: 243.0
new: 391.0
path: .metrics.halstead.effort
old: 63656.57541264474
new: 254638.32029005303
path: .metrics.halstead.vocabulary
old: 73.0
new: 83.0
path: .metrics.halstead.volume
old: 2723.522805907208
new: 3946.1494080037464
path: .metrics.halstead.N2
old: 197.0
new: 228.0
path: .metrics.halstead.purity_ratio
old: 0.9099520655026252
new: 0.7282495992893459
path: .metrics.halstead.difficulty
old: 23.372881355932204
new: 64.52830188679245
path: .metrics.halstead.n2
old: 59.0
new: 53.0
path: .metrics.halstead.time
old: 3536.4764118135968
new: 14146.573349447392
path: .metrics.cyclomatic.average
old: 1.0
new: 2.466666666666667
path: .metrics.cyclomatic.sum
old: 13.0
new: 37.0
path: .metrics.mi.mi_original
old: 53.626681405006224
new: 29.03979996412295
path: .metrics.mi.mi_sei
old: 27.43150781624711
new: 11.48124136682835
path: .metrics.mi.mi_visual_studio
old: 31.360632400588432
new: 16.98233916030582
path: .metrics.nexits.average
old: 0.5
new: 1.1666666666666667
path: .metrics.nexits.sum
old: 1.0
new: 14.0
path: .metrics.nom.functions
old: 2.0
new: 12.0
path: .metrics.nom.total
old: 2.0
new: 12.0
path: .metrics.nargs.average
old: 1.5
new: 0.4166666666666667
path: .metrics.nargs.sum
old: 3.0
new: 5.0
path: .metrics.cognitive.average
old: 0.0
new: 2.1666666666666665
path: .metrics.cognitive.sum
old: 0.0
new: 26.0
path: .metrics.loc.cloc
old: 10.0
new: 106.0
path: .metrics.loc.sloc
old: 92.0
new: 265.0
path: .metrics.loc.lloc
old: 29.0
new: 73.0
path: .metrics.loc.blank
old: 22.0
new: 23.0
path: .metrics.loc.ploc
old: 60.0
new: 136.0

# Spaces Data

## Minimal test - lines (15, 265)

path: .spaces[0].metrics.loc.ploc
old: 5.0
new: 131.0
path: .spaces[0].metrics.loc.blank
old: 0.0
new: 20.0
path: .spaces[0].metrics.loc.sloc
old: 5.0
new: 251.0
path: .spaces[0].metrics.loc.cloc
old: 0.0
new: 100.0
path: .spaces[0].metrics.loc.lloc
old: 0.0
new: 73.0
path: .spaces[0].metrics.cyclomatic.average
old: 1.0
new: 2.5714285714285716
path: .spaces[0].metrics.cyclomatic.sum
old: 1.0
new: 36.0
path: .spaces[0].metrics.nargs.average
old: null
new: 0.4166666666666667
path: .spaces[0].metrics.nargs.sum
old: 0.0
new: 5.0
path: .spaces[0].metrics.halstead.length
old: 11.0
new: 611.0
path: .spaces[0].metrics.halstead.estimated_program_length
old: 12.754887502163468
new: 415.2849179028711
path: .spaces[0].metrics.halstead.vocabulary
old: 7.0
new: 78.0
path: .spaces[0].metrics.halstead.level
old: 0.6666666666666666
new: 0.014414414414414416
path: .spaces[0].metrics.halstead.n1
old: 3.0
new: 30.0
path: .spaces[0].metrics.halstead.volume
old: 30.880904142633646
new: 3840.3807557248338
path: .spaces[0].metrics.halstead.time
old: 2.573408678552804
new: 14801.467496022797
path: .spaces[0].metrics.halstead.bugs
old: 0.004299318203100795
new: 1.3801626358119514
path: .spaces[0].metrics.halstead.difficulty
old: 1.5
new: 69.375
path: .spaces[0].metrics.halstead.N1
old: 7.0
new: 389.0
path: .spaces[0].metrics.halstead.n2
old: 4.0
new: 48.0
path: .spaces[0].metrics.halstead.purity_ratio
old: 1.1595352274694062
new: 0.6796807166986434
path: .spaces[0].metrics.halstead.effort
old: 46.321356213950466
new: 266426.4149284103
path: .spaces[0].metrics.halstead.N2
old: 4.0
new: 222.0
path: .spaces[0].metrics.mi.mi_sei
old: 107.42182080587256
new: 13.129093249153492
path: .spaces[0].metrics.mi.mi_original
old: 126.86038819798438
new: 30.29036304789001
path: .spaces[0].metrics.mi.mi_visual_studio
old: 74.18736151928911
new: 17.71366260110527
path: .spaces[0].metrics.nexits.average
old: null
new: 1.1666666666666667
path: .spaces[0].metrics.nexits.sum
old: 0.0
new: 14.0
path: .spaces[0].metrics.cognitive.sum
old: 0.0
new: 26.0
path: .spaces[0].metrics.cognitive.average
old: null
new: 2.1666666666666665
path: .spaces[0].metrics.nom.functions
old: 0.0
new: 12.0
path: .spaces[0].metrics.nom.total
old: 0.0
new: 12.0

### Code

    namespace mozilla {
    namespace detail {

    /**
     * Standard constructor
     * @param deallocator, called by Erase and ~nsDequeBase
     */
    nsDequeBase::nsDequeBase() {
      MOZ_COUNT_CTOR(nsDequeBase);
      mOrigin = mSize = 0;
      mData = mBuffer;  // don't allocate space until you must
      mCapacity = sizeof(mBuffer) / sizeof(mBuffer[0]);
      memset(mData, 0, mCapacity * sizeof(mBuffer[0]));
    }

    /**
     * Destructor
     */
    nsDequeBase::~nsDequeBase() {
      MOZ_COUNT_DTOR(nsDequeBase);

      if (mData && mData != mBuffer) {
        free(mData);
      }
      mData = nullptr;
    }

    size_t nsDequeBase::SizeOfExcludingThis(
        mozilla::MallocSizeOf aMallocSizeOf) const {
      size_t size = 0;
      if (mData != mBuffer) {
        size += aMallocSizeOf(mData);
      }

      return size;
    }

    /**
     * Remove all items from container without destroying them.
     */
    void nsDequeBase::Empty() {
      if (mSize && mData) {
        memset(mData, 0, mCapacity * sizeof(*mData));
      }
      mSize = 0;
      mOrigin = 0;
    }

    /**
     * This method quadruples the size of the deque
     * Elements in the deque are resequenced so that elements
     * in the deque are stored sequentially
     *
     * @return  whether growing succeeded
     */
    bool nsDequeBase::GrowCapacity() {
      mozilla::CheckedInt newCapacity = mCapacity;
      newCapacity *= 4;

      NS_ASSERTION(newCapacity.isValid(), "Overflow");
      if (!newCapacity.isValid()) {
        return false;
      }

      // Sanity check the new byte size.
      mozilla::CheckedInt newByteSize = newCapacity;
      newByteSize *= sizeof(void*);

      NS_ASSERTION(newByteSize.isValid(), "Overflow");
      if (!newByteSize.isValid()) {
        return false;
      }

      void** temp = (void**)malloc(newByteSize.value());
      if (!temp) {
        return false;
      }

      // Here's the interesting part: You can't just move the elements
      // directly (in situ) from the old buffer to the new one.
      // Since capacity has changed, the old origin doesn't make
      // sense anymore. It's better to resequence the elements now.

      memcpy(temp, mData + mOrigin, sizeof(void*) * (mCapacity - mOrigin));
      memcpy(temp + (mCapacity - mOrigin), mData, sizeof(void*) * mOrigin);

      if (mData != mBuffer) {
        free(mData);
      }

      mCapacity = newCapacity.value();
      mOrigin = 0;  // now realign the origin...
      mData = temp;

      return true;
    }

    /**
     * This method adds an item to the end of the deque.
     * This operation has the potential to cause the
     * underlying buffer to resize.
     *
     * @param   aItem: new item to be added to deque
     */
    bool nsDequeBase::Push(void* aItem, const fallible_t&) {
      if (mSize == mCapacity && !GrowCapacity()) {
        return false;
      }
      mData[modulus(mOrigin + mSize, mCapacity)] = aItem;
      mSize++;
      return true;
    }

    /**
     * This method adds an item to the front of the deque.
     * This operation has the potential to cause the
     * underlying buffer to resize.
     *
     * --Commments for GrowCapacity() case
     * We've grown and shifted which means that the old
     * final element in the deque is now the first element
     * in the deque.  This is temporary.
     * We haven't inserted the new element at the front.
     *
     * To continue with the idea of having the front at zero
     * after a grow, we move the old final item (which through
     * the voodoo of mOrigin-- is now the first) to its final
     * position which is conveniently the old length.
     *
     * Note that this case only happens when the deque is full.
     * [And that pieces of this magic only work if the deque is full.]
     * picture:
     *   [ABCDEFGH] @[mOrigin:3]:D.
     * Task: PushFront("Z")
     * shift mOrigin so, @[mOrigin:2]:C
     * stretch and rearrange: (mOrigin:0)
     *   [CDEFGHAB ________ ________ ________]
     * copy: (The second C is currently out of bounds)
     *   [CDEFGHAB C_______ ________ ________]
     * later we will insert Z:
     *   [ZDEFGHAB C_______ ________ ________]
     * and increment size: 9. (C is no longer out of bounds)
     * --
     * @param   aItem: new item to be added to deque
     */
    bool nsDequeBase::PushFront(void* aItem, const fallible_t&) {
      if (mOrigin == 0) {
        mOrigin = mCapacity - 1;
      } else {
        mOrigin--;
      }

      if (mSize == mCapacity) {
        if (!GrowCapacity()) {
          return false;
        }
        /* Comments explaining this are above*/
        mData[mSize] = mData[mOrigin];
      }
      mData[mOrigin] = aItem;
      mSize++;
      return true;
    }

    /**
     * Remove and return the last item in the container.
     *
     * @return  ptr to last item in container
     */
    void* nsDequeBase::Pop() {
      void* result = nullptr;
      if (mSize > 0) {
        --mSize;
        size_t offset = modulus(mSize + mOrigin, mCapacity);
        result = mData[offset];
        mData[offset] = nullptr;
        if (!mSize) {
          mOrigin = 0;
        }
      }
      return result;
    }

    /**
     * This method gets called you want to remove and return
     * the first member in the container.
     *
     * @return  last item in container
     */
    void* nsDequeBase::PopFront() {
      void* result = nullptr;
      if (mSize > 0) {
        NS_ASSERTION(mOrigin < mCapacity, "Error: Bad origin");
        result = mData[mOrigin];
        mData[mOrigin++] = nullptr;  // zero it out for debugging purposes.
        mSize--;
        // Cycle around if we pop off the end
        // and reset origin if when we pop the last element
        if (mCapacity == mOrigin || !mSize) {
          mOrigin = 0;
        }
      }
      return result;
    }

    /**
     * This method gets called you want to peek at the bottom
     * member without removing it.
     *
     * @return  last item in container
     */
    void* nsDequeBase::Peek() const {
      void* result = nullptr;
      if (mSize > 0) {
        result = mData[modulus(mSize - 1 + mOrigin, mCapacity)];
      }
      return result;
    }

    /**
     * This method gets called you want to peek at the topmost
     * member without removing it.
     *
     * @return  last item in container
     */
    void* nsDequeBase::PeekFront() const {
      void* result = nullptr;
      if (mSize > 0) {
        result = mData[mOrigin];
      }
      return result;
    }

    /**
     * Call this to retrieve the ith element from this container.
     * Keep in mind that accessing the underlying elements is
     * done in a relative fashion. Object 0 is not necessarily
     * the first element (the first element is at mOrigin).
     *
     * @param   aIndex : 0 relative offset of item you want
     * @return  void* or null
     */
    void* nsDequeBase::ObjectAt(size_t aIndex) const {
      void* result = nullptr;
      if (aIndex < mSize) {
        result = mData[modulus(mOrigin + aIndex, mCapacity)];
      }
      return result;
    }
    }  // namespace detail
    }  // namespace mozilla