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 }