github.com/aigarnetwork/aigar@v0.0.0-20191115204914-d59a6eb70f8e/metrics/gauge.go (about)

     1  //  Copyright 2018 The go-ethereum Authors
     2  //  Copyright 2019 The go-aigar Authors
     3  //  This file is part of the go-aigar library.
     4  //
     5  //  The go-aigar library is free software: you can redistribute it and/or modify
     6  //  it under the terms of the GNU Lesser General Public License as published by
     7  //  the Free Software Foundation, either version 3 of the License, or
     8  //  (at your option) any later version.
     9  //
    10  //  The go-aigar library is distributed in the hope that it will be useful,
    11  //  but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    13  //  GNU Lesser General Public License for more details.
    14  //
    15  //  You should have received a copy of the GNU Lesser General Public License
    16  //  along with the go-aigar library. If not, see <http://www.gnu.org/licenses/>.
    17  
    18  package metrics
    19  
    20  import "sync/atomic"
    21  
    22  // Gauges hold an int64 value that can be set arbitrarily.
    23  type Gauge interface {
    24  	Snapshot() Gauge
    25  	Update(int64)
    26  	Dec(int64)
    27  	Inc(int64)
    28  	Value() int64
    29  }
    30  
    31  // GetOrRegisterGauge returns an existing Gauge or constructs and registers a
    32  // new StandardGauge.
    33  func GetOrRegisterGauge(name string, r Registry) Gauge {
    34  	if nil == r {
    35  		r = DefaultRegistry
    36  	}
    37  	return r.GetOrRegister(name, NewGauge).(Gauge)
    38  }
    39  
    40  // NewGauge constructs a new StandardGauge.
    41  func NewGauge() Gauge {
    42  	if !Enabled {
    43  		return NilGauge{}
    44  	}
    45  	return &StandardGauge{0}
    46  }
    47  
    48  // NewRegisteredGauge constructs and registers a new StandardGauge.
    49  func NewRegisteredGauge(name string, r Registry) Gauge {
    50  	c := NewGauge()
    51  	if nil == r {
    52  		r = DefaultRegistry
    53  	}
    54  	r.Register(name, c)
    55  	return c
    56  }
    57  
    58  // NewFunctionalGauge constructs a new FunctionalGauge.
    59  func NewFunctionalGauge(f func() int64) Gauge {
    60  	if !Enabled {
    61  		return NilGauge{}
    62  	}
    63  	return &FunctionalGauge{value: f}
    64  }
    65  
    66  // NewRegisteredFunctionalGauge constructs and registers a new StandardGauge.
    67  func NewRegisteredFunctionalGauge(name string, r Registry, f func() int64) Gauge {
    68  	c := NewFunctionalGauge(f)
    69  	if nil == r {
    70  		r = DefaultRegistry
    71  	}
    72  	r.Register(name, c)
    73  	return c
    74  }
    75  
    76  // GaugeSnapshot is a read-only copy of another Gauge.
    77  type GaugeSnapshot int64
    78  
    79  // Snapshot returns the snapshot.
    80  func (g GaugeSnapshot) Snapshot() Gauge { return g }
    81  
    82  // Update panics.
    83  func (GaugeSnapshot) Update(int64) {
    84  	panic("Update called on a GaugeSnapshot")
    85  }
    86  
    87  // Dec panics.
    88  func (GaugeSnapshot) Dec(int64) {
    89  	panic("Dec called on a GaugeSnapshot")
    90  }
    91  
    92  // Inc panics.
    93  func (GaugeSnapshot) Inc(int64) {
    94  	panic("Inc called on a GaugeSnapshot")
    95  }
    96  
    97  // Value returns the value at the time the snapshot was taken.
    98  func (g GaugeSnapshot) Value() int64 { return int64(g) }
    99  
   100  // NilGauge is a no-op Gauge.
   101  type NilGauge struct{}
   102  
   103  // Snapshot is a no-op.
   104  func (NilGauge) Snapshot() Gauge { return NilGauge{} }
   105  
   106  // Update is a no-op.
   107  func (NilGauge) Update(v int64) {}
   108  
   109  // Dec is a no-op.
   110  func (NilGauge) Dec(i int64) {}
   111  
   112  // Inc is a no-op.
   113  func (NilGauge) Inc(i int64) {}
   114  
   115  // Value is a no-op.
   116  func (NilGauge) Value() int64 { return 0 }
   117  
   118  // StandardGauge is the standard implementation of a Gauge and uses the
   119  // sync/atomic package to manage a single int64 value.
   120  type StandardGauge struct {
   121  	value int64
   122  }
   123  
   124  // Snapshot returns a read-only copy of the gauge.
   125  func (g *StandardGauge) Snapshot() Gauge {
   126  	return GaugeSnapshot(g.Value())
   127  }
   128  
   129  // Update updates the gauge's value.
   130  func (g *StandardGauge) Update(v int64) {
   131  	atomic.StoreInt64(&g.value, v)
   132  }
   133  
   134  // Value returns the gauge's current value.
   135  func (g *StandardGauge) Value() int64 {
   136  	return atomic.LoadInt64(&g.value)
   137  }
   138  
   139  // Dec decrements the gauge's current value by the given amount.
   140  func (g *StandardGauge) Dec(i int64) {
   141  	atomic.AddInt64(&g.value, -i)
   142  }
   143  
   144  // Inc increments the gauge's current value by the given amount.
   145  func (g *StandardGauge) Inc(i int64) {
   146  	atomic.AddInt64(&g.value, i)
   147  }
   148  
   149  // FunctionalGauge returns value from given function
   150  type FunctionalGauge struct {
   151  	value func() int64
   152  }
   153  
   154  // Value returns the gauge's current value.
   155  func (g FunctionalGauge) Value() int64 {
   156  	return g.value()
   157  }
   158  
   159  // Snapshot returns the snapshot.
   160  func (g FunctionalGauge) Snapshot() Gauge { return GaugeSnapshot(g.Value()) }
   161  
   162  // Update panics.
   163  func (FunctionalGauge) Update(int64) {
   164  	panic("Update called on a FunctionalGauge")
   165  }
   166  
   167  // Dec panics.
   168  func (FunctionalGauge) Dec(int64) {
   169  	panic("Dec called on a FunctionalGauge")
   170  }
   171  
   172  // Inc panics.
   173  func (FunctionalGauge) Inc(int64) {
   174  	panic("Inc called on a FunctionalGauge")
   175  }