Line data Source code
1 : // Copyright (C) 2015 The Android Open Source Project 2 : // 3 : // Licensed under the Apache License, Version 2.0 (the "License"); 4 : // you may not use this file except in compliance with the License. 5 : // You may obtain a copy of the License at 6 : // 7 : // http://www.apache.org/licenses/LICENSE-2.0 8 : // 9 : // Unless required by applicable law or agreed to in writing, software 10 : // distributed under the License is distributed on an "AS IS" BASIS, 11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 : // See the License for the specific language governing permissions and 13 : // limitations under the License. 14 : 15 : package com.google.gerrit.metrics.dropwizard; 16 : 17 : import com.codahale.metrics.Metric; 18 : import com.google.common.collect.ImmutableList; 19 : import com.google.common.collect.Maps; 20 : import com.google.gerrit.metrics.Description; 21 : import com.google.gerrit.metrics.Field; 22 : import com.google.gerrit.metrics.dropwizard.DropWizardMetricMaker.CounterImpl; 23 : import java.util.Map; 24 : import java.util.concurrent.ConcurrentHashMap; 25 : 26 : /** Abstract counter broken down into buckets by {@link Field} values. */ 27 : abstract class BucketedCounter implements BucketedMetric { 28 : private final DropWizardMetricMaker metrics; 29 : private final String name; 30 : private final boolean isRate; 31 : private final Description.FieldOrdering ordering; 32 : protected final Field<?>[] fields; 33 : protected final CounterImpl total; 34 : private final Map<Object, CounterImpl> cells; 35 16 : private final Object lock = new Object(); 36 : 37 : BucketedCounter( 38 16 : DropWizardMetricMaker metrics, String name, Description desc, Field<?>... fields) { 39 16 : this.metrics = metrics; 40 16 : this.name = name; 41 16 : this.isRate = desc.isRate(); 42 16 : this.ordering = desc.getFieldOrdering(); 43 16 : this.fields = fields; 44 16 : this.total = metrics.newCounterImpl(name + "_total", isRate); 45 16 : this.cells = new ConcurrentHashMap<>(); 46 16 : } 47 : 48 : void doRemove() { 49 0 : for (CounterImpl c : cells.values()) { 50 0 : c.remove(); 51 0 : } 52 0 : total.remove(); 53 0 : metrics.remove(name); 54 0 : } 55 : 56 : CounterImpl forceCreate(Object f1, Object f2) { 57 15 : return forceCreate(ImmutableList.of(f1, f2)); 58 : } 59 : 60 : CounterImpl forceCreate(Object f1, Object f2, Object f3) { 61 6 : return forceCreate(ImmutableList.of(f1, f2, f3)); 62 : } 63 : 64 : CounterImpl forceCreate(Object key) { 65 16 : CounterImpl c = cells.get(key); 66 16 : if (c != null) { 67 15 : return c; 68 : } 69 : 70 16 : synchronized (lock) { 71 16 : c = cells.get(key); 72 16 : if (c == null) { 73 16 : c = metrics.newCounterImpl(submetric(key), isRate); 74 16 : cells.put(key, c); 75 : } 76 16 : return c; 77 : } 78 : } 79 : 80 : private String submetric(Object key) { 81 16 : return DropWizardMetricMaker.name(ordering, name, name(key)); 82 : } 83 : 84 : abstract String name(Object key); 85 : 86 : @Override 87 : public Metric getTotal() { 88 0 : return total.metric; 89 : } 90 : 91 : @Override 92 : public Field<?>[] getFields() { 93 0 : return fields; 94 : } 95 : 96 : @Override 97 : public Map<Object, Metric> getCells() { 98 0 : return Maps.transformValues(cells, c -> c.metric); 99 : } 100 : }