github.com/m3db/m3@v1.5.0/src/metrics/encoding/protobuf/reset.go (about)

     1  // Copyright (c) 2018 Uber Technologies, Inc.
     2  //
     3  // Permission is hereby granted, free of charge, to any person obtaining a copy
     4  // of this software and associated documentation files (the "Software"), to deal
     5  // in the Software without restriction, including without limitation the rights
     6  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     7  // copies of the Software, and to permit persons to whom the Software is
     8  // furnished to do so, subject to the following conditions:
     9  //
    10  // The above copyright notice and this permission notice shall be included in
    11  // all copies or substantial portions of the Software.
    12  //
    13  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    14  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    15  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    16  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    17  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    18  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    19  // THE SOFTWARE.
    20  
    21  package protobuf
    22  
    23  import (
    24  	"github.com/m3db/m3/src/metrics/generated/proto/metricpb"
    25  )
    26  
    27  // ReuseMetricWithMetadatasProto allows for zero-alloc reuse of
    28  // *metricpb.MetricWithMetadatas by deep resetting the internal slices
    29  // and when using gogoprotobuf's unmarshal function will reuse the slices
    30  // and byte buffers already allocated on the message itself.
    31  //
    32  // It is required to use nullable: false annotations so that it does not
    33  // use pointer types for slices on the message to achieve zero alloc resets.
    34  //
    35  // The methods resets the metric with metadatas proto, and in particular
    36  // message fields that are slices because the `Unmarshal` generated
    37  // from gogoprotobuf simply append a new entry at the end of the slice, and
    38  // as such, the fields with slice types need to be reset to be zero-length.
    39  // NB: reset only needs to be done to the top-level slice fields as the individual
    40  // items in the slice are created afresh during unmarshaling.
    41  func ReuseMetricWithMetadatasProto(pb *metricpb.MetricWithMetadatas) {
    42  	if pb == nil {
    43  		return
    44  	}
    45  	pb.Type = metricpb.MetricWithMetadatas_UNKNOWN
    46  	resetCounterWithMetadatasProto(pb.CounterWithMetadatas)
    47  	resetBatchTimerWithMetadatasProto(pb.BatchTimerWithMetadatas)
    48  	resetGaugeWithMetadatasProto(pb.GaugeWithMetadatas)
    49  	resetForwardedMetricWithMetadataProto(pb.ForwardedMetricWithMetadata)
    50  	resetTimedMetricWithMetadataProto(pb.TimedMetricWithMetadata)
    51  	resetTimedMetricWithMetadatasProto(pb.TimedMetricWithMetadatas)
    52  	resetTimedMetricWithStoragePolicyProto(pb.TimedMetricWithStoragePolicy)
    53  }
    54  
    55  // ReuseAggregatedMetricProto allows for zero-alloc reuse of
    56  // *metricpb.AggregatedMetric
    57  func ReuseAggregatedMetricProto(pb *metricpb.AggregatedMetric) {
    58  	if pb == nil {
    59  		return
    60  	}
    61  	resetTimedMetricWithStoragePolicyProto(&pb.Metric)
    62  	pb.EncodeNanos = 0
    63  }
    64  
    65  func resetCounterWithMetadatasProto(pb *metricpb.CounterWithMetadatas) {
    66  	if pb == nil {
    67  		return
    68  	}
    69  	resetCounter(&pb.Counter)
    70  	resetMetadatas(&pb.Metadatas)
    71  }
    72  
    73  func resetBatchTimerWithMetadatasProto(pb *metricpb.BatchTimerWithMetadatas) {
    74  	if pb == nil {
    75  		return
    76  	}
    77  	resetBatchTimer(&pb.BatchTimer)
    78  	resetMetadatas(&pb.Metadatas)
    79  }
    80  
    81  func resetGaugeWithMetadatasProto(pb *metricpb.GaugeWithMetadatas) {
    82  	if pb == nil {
    83  		return
    84  	}
    85  	resetGauge(&pb.Gauge)
    86  	resetMetadatas(&pb.Metadatas)
    87  }
    88  
    89  func resetForwardedMetricWithMetadataProto(pb *metricpb.ForwardedMetricWithMetadata) {
    90  	if pb == nil {
    91  		return
    92  	}
    93  	resetForwardedMetric(&pb.Metric)
    94  	resetForwardMetadata(&pb.Metadata)
    95  }
    96  
    97  func resetTimedMetricWithMetadataProto(pb *metricpb.TimedMetricWithMetadata) {
    98  	if pb == nil {
    99  		return
   100  	}
   101  	resetTimedMetric(&pb.Metric)
   102  	resetTimedMetadata(&pb.Metadata)
   103  }
   104  
   105  func resetTimedMetricWithMetadatasProto(pb *metricpb.TimedMetricWithMetadatas) {
   106  	if pb == nil {
   107  		return
   108  	}
   109  	resetTimedMetric(&pb.Metric)
   110  	resetMetadatas(&pb.Metadatas)
   111  }
   112  
   113  func resetTimedMetricWithStoragePolicyProto(pb *metricpb.TimedMetricWithStoragePolicy) {
   114  	if pb == nil {
   115  		return
   116  	}
   117  	resetTimedMetric(&pb.TimedMetric)
   118  	pb.StoragePolicy.Reset()
   119  }
   120  
   121  func resetCounter(pb *metricpb.Counter) {
   122  	if pb == nil {
   123  		return
   124  	}
   125  	pb.Id = pb.Id[:0]
   126  	pb.Value = 0
   127  	pb.Annotation = pb.Annotation[:0]
   128  	pb.ClientTimeNanos = 0
   129  }
   130  
   131  func resetBatchTimer(pb *metricpb.BatchTimer) {
   132  	if pb == nil {
   133  		return
   134  	}
   135  	pb.Id = pb.Id[:0]
   136  	pb.Values = pb.Values[:0]
   137  	pb.Annotation = pb.Annotation[:0]
   138  	pb.ClientTimeNanos = 0
   139  }
   140  
   141  func resetGauge(pb *metricpb.Gauge) {
   142  	if pb == nil {
   143  		return
   144  	}
   145  	pb.Id = pb.Id[:0]
   146  	pb.Value = 0.0
   147  	pb.Annotation = pb.Annotation[:0]
   148  	pb.ClientTimeNanos = 0
   149  }
   150  
   151  func resetForwardedMetric(pb *metricpb.ForwardedMetric) {
   152  	if pb == nil {
   153  		return
   154  	}
   155  	pb.Type = metricpb.MetricType_UNKNOWN
   156  	pb.Id = pb.Id[:0]
   157  	pb.TimeNanos = 0
   158  	pb.Values = pb.Values[:0]
   159  	pb.PrevValues = pb.PrevValues[:0]
   160  	pb.Annotation = pb.Annotation[:0]
   161  	pb.Version = 0
   162  }
   163  
   164  func resetTimedMetric(pb *metricpb.TimedMetric) {
   165  	if pb == nil {
   166  		return
   167  	}
   168  	pb.Type = metricpb.MetricType_UNKNOWN
   169  	pb.Id = pb.Id[:0]
   170  	pb.TimeNanos = 0
   171  	pb.Value = 0
   172  	pb.Annotation = pb.Annotation[:0]
   173  }
   174  
   175  func resetMetadatas(pb *metricpb.StagedMetadatas) {
   176  	pb.Reuse()
   177  }
   178  
   179  func resetForwardMetadata(pb *metricpb.ForwardMetadata) {
   180  	if pb == nil {
   181  		return
   182  	}
   183  	pb.AggregationId.Reset()
   184  	pb.StoragePolicy.Reset()
   185  	pb.Pipeline.Ops = pb.Pipeline.Ops[:0]
   186  	pb.SourceId = 0
   187  	pb.NumForwardedTimes = 0
   188  	pb.ResendEnabled = false
   189  }
   190  
   191  func resetTimedMetadata(pb *metricpb.TimedMetadata) {
   192  	if pb == nil {
   193  		return
   194  	}
   195  	pb.AggregationId.Reset()
   196  	pb.StoragePolicy.Reset()
   197  }