com.facebook.stats.CompositeGaugeCounter.java Source code

Java tutorial

Introduction

Here is the source code for com.facebook.stats.CompositeGaugeCounter.java

Source

/*
 * Copyright (C) 2012 Facebook, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.facebook.stats;

import org.joda.time.DateTime;
import org.joda.time.ReadableDateTime;
import org.joda.time.ReadableDuration;

import java.util.Arrays;
import java.util.Iterator;

/**
 * Keeps a list of gauge counters (see AbstractCompositeCounter)
 * that look like one summarized gauge counter.
 */
public class CompositeGaugeCounter extends AbstractCompositeSum<GaugeCounter> implements GaugeCounter {
    private final GaugeCounterFactory gaugeCounterFactory;

    public CompositeGaugeCounter(ReadableDuration maxLength, ReadableDuration maxChunkLength,
            GaugeCounterFactory gaugeCounterFactory) {
        super(maxLength, maxChunkLength);
        this.gaugeCounterFactory = gaugeCounterFactory;
    }

    public CompositeGaugeCounter(ReadableDuration maxLength, GaugeCounterFactory gaugeCounterFactory) {
        super(maxLength);
        this.gaugeCounterFactory = gaugeCounterFactory;
    }

    public CompositeGaugeCounter(ReadableDuration maxLength) {
        this(maxLength, DefaultGaugeCounterFactory.INSTANCE);
    }

    public synchronized CompositeEventCounterIf<GaugeCounter> add(long delta, long nsamples, ReadableDateTime start,
            ReadableDateTime end) {
        GaugeCounter counter = nextCounter(start, end);
        counter.add(delta, nsamples);
        return addEventCounter(counter);
    }

    /**
     * mirrors AbstractCompositeCounter:add()
     */
    @Override
    public void add(long delta, long nsamples) {
        DateTime now = new DateTime();
        GaugeCounter last;

        synchronized (this) {
            if (getMostRecentCounter() == null || !now.isBefore(getMostRecentCounter().getEnd())) {
                addEventCounter(nextCounter(now, now.plus(getMaxChunkLength())));
            }
            last = getMostRecentCounter();
        }
        last.add(delta, nsamples);
    }

    /**
     * mirrors AbstractCompositeCounter:getValue()
     */
    @Override
    public synchronized long getSamples() {
        long nsamples = 0L;

        trimIfNeeded();

        Iterator<GaugeCounter> counterIterator = getEventCounters().iterator();
        boolean first = true;
        while (counterIterator.hasNext()) {
            GaugeCounter counter = counterIterator.next();
            nsamples += counter.getSamples();

            if (first) {
                // if there is at least one counter that is partially expired
                if (getWindowStart().isAfter(counter.getStart())) {
                    // adjust for partial expiration
                    nsamples -= (long) (getExpiredFraction(counter) * counter.getSamples());
                }
                first = false;
            }
        }

        return nsamples;
    }

    public synchronized long getAverage() {
        long nsamples = getSamples();
        if (nsamples == 0) {
            return 0;
        }
        long value = getValue();
        return value / nsamples;
    }

    @Override
    protected GaugeCounter nextCounter(ReadableDateTime start, ReadableDateTime end) {
        return gaugeCounterFactory.create(start, end);
    }

    @Override
    public GaugeCounter merge(GaugeCounter counter) {
        // special case to handle merging of 2 composite counters
        if (counter instanceof CompositeGaugeCounter) {
            return internalMerge(((CompositeGaugeCounter) counter).getEventCounters(),
                    new CompositeGaugeCounter(getMaxLength(), getMaxChunkLength(), gaugeCounterFactory));
        } else {
            return internalMerge(Arrays.asList(counter),
                    new CompositeGaugeCounter(getMaxLength(), getMaxChunkLength(), gaugeCounterFactory));
        }
    }
}