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.TimerImpl; 23 : import java.util.Map; 24 : import java.util.concurrent.ConcurrentHashMap; 25 : 26 : /** Abstract timer broken down into buckets by {@link Field} values. */ 27 : abstract class BucketedTimer implements BucketedMetric { 28 : private final DropWizardMetricMaker metrics; 29 : protected final String name; 30 : private final Description.FieldOrdering ordering; 31 : protected final Field<?>[] fields; 32 : protected final TimerImpl total; 33 : private final Map<Object, TimerImpl> cells; 34 15 : private final Object lock = new Object(); 35 : 36 15 : BucketedTimer(DropWizardMetricMaker metrics, String name, Description desc, Field<?>... fields) { 37 15 : this.metrics = metrics; 38 15 : this.name = name; 39 15 : this.ordering = desc.getFieldOrdering(); 40 15 : this.fields = fields; 41 15 : this.total = metrics.newTimerImpl(name + "_total"); 42 15 : this.cells = new ConcurrentHashMap<>(); 43 15 : } 44 : 45 : void doRemove() { 46 0 : for (TimerImpl c : cells.values()) { 47 0 : c.remove(); 48 0 : } 49 0 : total.remove(); 50 0 : metrics.remove(name); 51 0 : } 52 : 53 : TimerImpl forceCreate(Object f1, Object f2) { 54 15 : return forceCreate(ImmutableList.of(f1, f2)); 55 : } 56 : 57 : TimerImpl forceCreate(Object f1, Object f2, Object f3) { 58 15 : return forceCreate(ImmutableList.of(f1, f2, f3)); 59 : } 60 : 61 : TimerImpl forceCreate(Object key) { 62 15 : TimerImpl c = cells.get(key); 63 15 : if (c != null) { 64 15 : return c; 65 : } 66 : 67 15 : synchronized (lock) { 68 15 : c = cells.get(key); 69 15 : if (c == null) { 70 15 : c = metrics.newTimerImpl(submetric(key)); 71 15 : cells.put(key, c); 72 : } 73 15 : return c; 74 : } 75 : } 76 : 77 : private String submetric(Object key) { 78 15 : return DropWizardMetricMaker.name(ordering, name, name(key)); 79 : } 80 : 81 : abstract String name(Object key); 82 : 83 : @Override 84 : public Metric getTotal() { 85 0 : return total.metric; 86 : } 87 : 88 : @Override 89 : public Field<?>[] getFields() { 90 0 : return fields; 91 : } 92 : 93 : @Override 94 : public Map<Object, Metric> getCells() { 95 0 : return Maps.transformValues(cells, t -> t.metric); 96 : } 97 : }