Global Metrics

path: .metrics.cognitive.sum
old: 17.0
new: 0.0

path: .metrics.cognitive.average
old: 0.7391304347826086
new: 0.0

path: .metrics.nom.functions
old: 23.0
new: 1.0

path: .metrics.nom.total
old: 23.0
new: 1.0

path: .metrics.mi.mi_visual_studio
old: 11.956827281437182
new: 35.07713845630129

path: .metrics.mi.mi_sei
old: -5.807683198267682
new: 57.66216621297251

path: .metrics.mi.mi_original
old: 20.44617465125758
new: 59.98190676027521

path: .metrics.nargs.average
old: 1.0434782608695652
new: 0.0

path: .metrics.nargs.sum
old: 24.0
new: 0.0

path: .metrics.nexits.sum
old: 15.0
new: 0.0

path: .metrics.nexits.average
old: 0.6521739130434783
new: 0.0

path: .metrics.cyclomatic.sum
old: 41.0
new: 5.0

path: .metrics.cyclomatic.average
old: 1.5185185185185186
new: 1.0

path: .metrics.halstead.n2
old: 173.0
new: 30.0

path: .metrics.halstead.level
old: 0.03148030206532618
new: 0.10989010989010987

path: .metrics.halstead.N2
old: 379.0
new: 42.0

path: .metrics.halstead.bugs
old: 1.245608174514433
new: 0.09471559303873006

path: .metrics.halstead.vocabulary
old: 202.0
new: 43.0

path: .metrics.halstead.volume
old: 7191.060582303935
new: 526.3476812061035

path: .metrics.halstead.purity_ratio
old: 1.519778628583443
new: 2.0135302495266987

path: .metrics.halstead.length
old: 939.0
new: 97.0

path: .metrics.halstead.n1
old: 29.0
new: 13.0

path: .metrics.halstead.estimated_program_length
old: 1427.0721322398529
new: 195.31243420408975

path: .metrics.halstead.N1
old: 560.0
new: 55.0

path: .metrics.halstead.effort
old: 228430.48225463164
new: 4789.763898975541

path: .metrics.halstead.time
old: 12690.582347479536
new: 266.0979943875301

path: .metrics.halstead.difficulty
old: 31.765895953757227
new: 9.1

path: .metrics.loc.cloc
old: 96.0
new: 69.0

path: .metrics.loc.lloc
old: 71.0
new: 1.0

path: .metrics.loc.ploc
old: 205.0
new: 28.0

path: .metrics.loc.blank
old: 50.0
new: 21.0

path: .metrics.loc.sloc
old: 351.0
new: 118.0

Spaces Data

Minimal test - lines (21, 116)

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

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

path: .spaces[0].metrics.halstead.vocabulary
old: 199.0
new: 41.0

path: .spaces[0].metrics.halstead.N1
old: 560.0
new: 55.0

path: .spaces[0].metrics.halstead.bugs
old: 1.2485374028090848
new: 0.08944119419259149

path: .spaces[0].metrics.halstead.difficulty
old: 32.07058823529412
new: 8.821428571428571

path: .spaces[0].metrics.halstead.n1
old: 29.0
new: 13.0

path: .spaces[0].metrics.halstead.volume
old: 7147.880644828855
new: 498.2523364294818

path: .spaces[0].metrics.halstead.N2
old: 376.0
new: 38.0

path: .spaces[0].metrics.halstead.n2
old: 170.0
new: 28.0

path: .spaces[0].metrics.halstead.purity_ratio
old: 1.496237081198834
new: 1.9646414425101837

path: .spaces[0].metrics.halstead.level
old: 0.031181217901687455
new: 0.11336032388663968

path: .spaces[0].metrics.halstead.time
old: 12735.374273074156
new: 244.18318868667063

path: .spaces[0].metrics.halstead.length
old: 936.0
new: 93.0

path: .spaces[0].metrics.halstead.estimated_program_length
old: 1400.4779080021087
new: 182.71165415344709

path: .spaces[0].metrics.halstead.effort
old: 229236.7369153348
new: 4395.297396360072

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

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

path: .spaces[0].metrics.nargs.average
old: 1.0434782608695652
new: 0.0

path: .spaces[0].metrics.nargs.sum
old: 24.0
new: 0.0

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

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

path: .spaces[0].metrics.cyclomatic.sum
old: 40.0
new: 4.0

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

path: .spaces[0].metrics.mi.mi_sei
old: -6.431246161101214
new: 64.01370615562831

path: .spaces[0].metrics.mi.mi_original
old: 22.563738185370383
new: 63.8398047267838

path: .spaces[0].metrics.mi.mi_visual_studio
old: 13.195168529456366
new: 37.33321913847006

path: .spaces[0].metrics.loc.ploc
old: 199.0
new: 22.0

path: .spaces[0].metrics.loc.sloc
old: 313.0
new: 96.0

path: .spaces[0].metrics.loc.blank
old: 48.0
new: 13.0

path: .spaces[0].metrics.loc.lloc
old: 71.0
new: 1.0

path: .spaces[0].metrics.loc.cloc
old: 66.0
new: 61.0

Code

namespace mozilla {

// A ThrottledEventQueue is an event target that can be used to throttle
// events being dispatched to another base target.  It maintains its
// own queue of events and only dispatches one at a time to the wrapped
// target.  This can be used to avoid flooding the base target.
//
// Flooding is avoided via a very simple principle.  Runnables dispatched
// to the ThrottledEventQueue are only dispatched to the base target
// one at a time.  Only once that runnable has executed will we dispatch
// the next runnable to the base target.  This in effect makes all
// runnables passing through the ThrottledEventQueue yield to other work
// on the base target.
//
// ThrottledEventQueue keeps runnables waiting to be dispatched to the
// base in its own internal queue.  Code can query the length of this
// queue using IsEmpty() and Length().  Further, code implement back
// pressure by checking the depth of the queue and deciding to stop
// issuing runnables if they see the ThrottledEventQueue is backed up.
// Code running on other threads could even use AwaitIdle() to block
// all operation until the ThrottledEventQueue drains.
//
// Note, this class is similar to TaskQueue, but also differs in a few
// ways.  First, it is a very simple nsIEventTarget implementation.  It
// does not use the AbstractThread API.
//
// In addition, ThrottledEventQueue currently dispatches its next
// runnable to the base target *before* running the current event.  This
// allows the event code to spin the event loop without stalling the
// ThrottledEventQueue.  In contrast, TaskQueue only dispatches its next
// runnable after running the current event.  That approach is necessary
// for TaskQueue in order to work with thread pool targets.
//
// So, if you are targeting a thread pool you probably want a TaskQueue.
// If you are targeting a single thread or other non-concurrent event
// target, you probably want a ThrottledEventQueue.
//
// If you drop a ThrottledEventQueue while its queue still has events to be run,
// they will continue to be dispatched as usual to the base. Only once the last
// event has run will all the ThrottledEventQueue's memory be freed.
class ThrottledEventQueue final : public nsISerialEventTarget {
  class Inner;
  RefPtr mInner;

  explicit ThrottledEventQueue(already_AddRefed aInner);
  ~ThrottledEventQueue() = default;

 public:
  // Create a ThrottledEventQueue for the given target.
  static already_AddRefed Create(
      nsISerialEventTarget* aBaseTarget, const char* aName,
      uint32_t aPriority = nsIRunnablePriority::PRIORITY_NORMAL);

  // Determine if there are any events pending in the queue.
  bool IsEmpty() const;

  // Determine how many events are pending in the queue.
  uint32_t Length() const;

  already_AddRefed GetEvent();

  // Block the current thread until the queue is empty. This may not be called
  // on the main thread or the base target. The ThrottledEventQueue must not be
  // paused.
  void AwaitIdle() const;

  // If |aIsPaused| is true, pause execution of events from this queue. No
  // events from this queue will be run until this is called with |aIsPaused|
  // false.
  //
  // To un-pause a ThrottledEventQueue, we need to dispatch a runnable to the
  // underlying event target. That operation may fail, so this method is
  // fallible as well.
  //
  // Note that, although ThrottledEventQueue's behavior is descibed as queueing
  // events on the base target, an event queued on a TEQ is never actually moved
  // to any other queue. What is actually dispatched to the base is an
  // "executor" event which, when run, removes an event from the TEQ and runs it
  // immediately. This means that you can pause a TEQ even after the executor
  // has been queued on the base target, and even so, no events from the TEQ
  // will run. When the base target gets around to running the executor, the
  // executor will see that the TEQ is paused, and do nothing.
  [[nodiscard]] nsresult SetIsPaused(bool aIsPaused);

  // Return true if this ThrottledEventQueue is paused.
  bool IsPaused() const;

  NS_DECL_THREADSAFE_ISUPPORTS
  NS_DECL_NSIEVENTTARGET_FULL

  NS_DECLARE_STATIC_IID_ACCESSOR(NS_THROTTLEDEVENTQUEUE_IID);
};

NS_DEFINE_STATIC_IID_ACCESSOR(ThrottledEventQueue, NS_THROTTLEDEVENTQUEUE_IID);

}  // namespace mozilla

Minimal test - lines (61, 112)

path: .spaces[0].spaces[0].metrics.nargs.average
old: 1.0434782608695652
new: 0.0

path: .spaces[0].spaces[0].metrics.nargs.sum
old: 24.0
new: 0.0

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

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

path: .spaces[0].spaces[0].metrics.halstead.bugs
old: 1.248658420113468
new: 0.08079718838226968

path: .spaces[0].spaces[0].metrics.halstead.N2
old: 375.0
new: 34.0

path: .spaces[0].spaces[0].metrics.halstead.volume
old: 7125.819083154355
new: 443.9737863844289

path: .spaces[0].spaces[0].metrics.halstead.estimated_program_length
old: 1391.6300735903887
new: 170.3171490075026

path: .spaces[0].spaces[0].metrics.halstead.difficulty
old: 32.17455621301775
new: 8.5

path: .spaces[0].spaces[0].metrics.halstead.level
old: 0.031080459770114945
new: 0.1176470588235294

path: .spaces[0].spaces[0].metrics.halstead.effort
old: 229270.0666547444
new: 3773.7771842676457

path: .spaces[0].spaces[0].metrics.halstead.N1
old: 559.0
new: 50.0

path: .spaces[0].spaces[0].metrics.halstead.n2
old: 169.0
new: 26.0

path: .spaces[0].spaces[0].metrics.halstead.purity_ratio
old: 1.4899679588762191
new: 2.0275851072321736

path: .spaces[0].spaces[0].metrics.halstead.length
old: 934.0
new: 84.0

path: .spaces[0].spaces[0].metrics.halstead.n1
old: 29.0
new: 13.0

path: .spaces[0].spaces[0].metrics.halstead.time
old: 12737.225925263578
new: 209.6542880148692

path: .spaces[0].spaces[0].metrics.halstead.vocabulary
old: 198.0
new: 39.0

path: .spaces[0].spaces[0].metrics.mi.mi_sei
old: -6.147450544588793
new: 75.10528115379276

path: .spaces[0].spaces[0].metrics.mi.mi_visual_studio
old: 13.39980061013963
new: 43.626825175266035

path: .spaces[0].spaces[0].metrics.mi.mi_original
old: 22.913659043338768
new: 74.60187104970493

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

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

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

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

path: .spaces[0].spaces[0].metrics.loc.blank
old: 49.0
new: 10.0

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

path: .spaces[0].spaces[0].metrics.loc.cloc
old: 65.0
new: 23.0

path: .spaces[0].spaces[0].metrics.loc.sloc
old: 311.0
new: 52.0

path: .spaces[0].spaces[0].metrics.loc.ploc
old: 197.0
new: 19.0

path: .spaces[0].spaces[0].metrics.cyclomatic.sum
old: 39.0
new: 3.0

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

Code

class ThrottledEventQueue final : public nsISerialEventTarget {
  class Inner;
  RefPtr mInner;

  explicit ThrottledEventQueue(already_AddRefed aInner);
  ~ThrottledEventQueue() = default;

 public:
  // Create a ThrottledEventQueue for the given target.
  static already_AddRefed Create(
      nsISerialEventTarget* aBaseTarget, const char* aName,
      uint32_t aPriority = nsIRunnablePriority::PRIORITY_NORMAL);

  // Determine if there are any events pending in the queue.
  bool IsEmpty() const;

  // Determine how many events are pending in the queue.
  uint32_t Length() const;

  already_AddRefed GetEvent();

  // Block the current thread until the queue is empty. This may not be called
  // on the main thread or the base target. The ThrottledEventQueue must not be
  // paused.
  void AwaitIdle() const;

  // If |aIsPaused| is true, pause execution of events from this queue. No
  // events from this queue will be run until this is called with |aIsPaused|
  // false.
  //
  // To un-pause a ThrottledEventQueue, we need to dispatch a runnable to the
  // underlying event target. That operation may fail, so this method is
  // fallible as well.
  //
  // Note that, although ThrottledEventQueue's behavior is descibed as queueing
  // events on the base target, an event queued on a TEQ is never actually moved
  // to any other queue. What is actually dispatched to the base is an
  // "executor" event which, when run, removes an event from the TEQ and runs it
  // immediately. This means that you can pause a TEQ even after the executor
  // has been queued on the base target, and even so, no events from the TEQ
  // will run. When the base target gets around to running the executor, the
  // executor will see that the TEQ is paused, and do nothing.
  [[nodiscard]] nsresult SetIsPaused(bool aIsPaused);

  // Return true if this ThrottledEventQueue is paused.
  bool IsPaused() const;

  NS_DECL_THREADSAFE_ISUPPORTS
  NS_DECL_NSIEVENTTARGET_FULL

  NS_DECLARE_STATIC_IID_ACCESSOR(NS_THROTTLEDEVENTQUEUE_IID);
};

Minimal test - lines (62, 62)

path: .spaces[0].spaces[0].spaces[0].metrics.halstead.purity_ratio
old: 1.7012050593046013
new: null

path: .spaces[0].spaces[0].spaces[0].metrics.halstead.N2
old: 2.0
new: 1.0

path: .spaces[0].spaces[0].spaces[0].metrics.halstead.length
old: 8.0
new: 1.0

path: .spaces[0].spaces[0].spaces[0].metrics.halstead.bugs
old: 0.0048876146417121315
new: 0.0

path: .spaces[0].spaces[0].spaces[0].metrics.halstead.estimated_program_length
old: 13.60964047443681
new: null

path: .spaces[0].spaces[0].spaces[0].metrics.halstead.difficulty
old: 2.5
new: 0.0

path: .spaces[0].spaces[0].spaces[0].metrics.halstead.level
old: 0.4
new: null

path: .spaces[0].spaces[0].spaces[0].metrics.halstead.n1
old: 5.0
new: 0.0

path: .spaces[0].spaces[0].spaces[0].metrics.halstead.N1
old: 6.0
new: 0.0

path: .spaces[0].spaces[0].spaces[0].metrics.halstead.volume
old: 22.458839376460833
new: 0.0

path: .spaces[0].spaces[0].spaces[0].metrics.halstead.effort
old: 56.14709844115208
new: 0.0

path: .spaces[0].spaces[0].spaces[0].metrics.halstead.vocabulary
old: 7.0
new: 1.0

path: .spaces[0].spaces[0].spaces[0].metrics.halstead.n2
old: 2.0
new: 1.0

path: .spaces[0].spaces[0].spaces[0].metrics.halstead.time
old: 3.1192832467306713
new: 0.0

path: .spaces[0].spaces[0].spaces[0].metrics.nexits.average
old: 1.0
new: null

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

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

path: .spaces[0].spaces[0].spaces[0].metrics.nargs.average
old: 0.0
new: null

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

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

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

path: .spaces[0].spaces[0].spaces[0].metrics.mi.mi_visual_studio
old: 90.4030653691422
new: null

path: .spaces[0].spaces[0].spaces[0].metrics.mi.mi_sei
old: 147.42610035996177
new: null

path: .spaces[0].spaces[0].spaces[0].metrics.mi.mi_original
old: 154.58924178123317
new: null

Code

  class Inner;

Minimal test - lines (66, 66)

path: .spaces[0].spaces[0].spaces[1].metrics.mi.mi_visual_studio
old: 71.017821898286
new: 91.5288617268536

path: .spaces[0].spaces[0].spaces[1].metrics.mi.mi_original
old: 121.44047544606906
new: 156.51435355291963

path: .spaces[0].spaces[0].spaces[1].metrics.mi.mi_sei
old: 99.60253955663347
new: 150.2034495661308

path: .spaces[0].spaces[0].spaces[1].metrics.halstead.n1
old: 8.0
new: 5.0

path: .spaces[0].spaces[0].spaces[1].metrics.halstead.volume
old: 87.56916320732489
new: 15.509775004326936

path: .spaces[0].spaces[0].spaces[1].metrics.halstead.N1
old: 15.0
new: 5.0

path: .spaces[0].spaces[0].spaces[1].metrics.halstead.estimated_program_length
old: 39.50977500432694
new: 11.60964047443681

path: .spaces[0].spaces[0].spaces[1].metrics.halstead.vocabulary
old: 14.0
new: 6.0

path: .spaces[0].spaces[0].spaces[1].metrics.halstead.purity_ratio
old: 1.717816304535954
new: 1.9349400790728015

path: .spaces[0].spaces[0].spaces[1].metrics.halstead.N2
old: 8.0
new: 1.0

path: .spaces[0].spaces[0].spaces[1].metrics.halstead.length
old: 23.0
new: 6.0

path: .spaces[0].spaces[0].spaces[1].metrics.halstead.time
old: 25.946418728096265
new: 2.1541354172676304

path: .spaces[0].spaces[0].spaces[1].metrics.halstead.effort
old: 467.0355371057327
new: 38.77443751081734

path: .spaces[0].spaces[0].spaces[1].metrics.halstead.difficulty
old: 5.333333333333333
new: 2.5

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

path: .spaces[0].spaces[0].spaces[1].metrics.halstead.bugs
old: 0.02006528643365642
new: 0.00381864321284214

path: .spaces[0].spaces[0].spaces[1].metrics.halstead.level
old: 0.1875
new: 0.4

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

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

path: .spaces[0].spaces[0].spaces[1].metrics.loc.sloc
old: 5.0
new: 1.0

path: .spaces[0].spaces[0].spaces[1].metrics.loc.ploc
old: 5.0
new: 1.0

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

Code

  ~ThrottledEventQueue() = default;