All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.tencent.polaris.plugins.circuitbreaker.common.stat.Bucket Maven / Gradle / Ivy

/*
 * Tencent is pleased to support the open source community by making Polaris available.
 *
 * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
 *
 * Licensed under the BSD 3-Clause License (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * https://opensource.org/licenses/BSD-3-Clause
 *
 * 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.tencent.polaris.plugins.circuitbreaker.common.stat;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;

/**
 * 单个滑桶具体实现
 *
 * @author andrewshan
 * @date 2019/8/25
 */
public class Bucket {

    /**
     * 统计序列集合,key为资源ID
     */
    private final ResMetricArray metric;

    /**
     * 滑桶的时间范围
     */
    private final TimeRange timeRange;

    /**
     * 滑桶链总长,只有首节点需要
     */
    private final AtomicInteger count = new AtomicInteger(0);

    /**
     * 下一个滑桶
     */
    private final AtomicReference nextBucket = new AtomicReference<>();

    public Bucket(long start, long intervalMs, int metricSize) {
        timeRange = new TimeRange(start, start + intervalMs);
        metric = new ResMetricArray(metricSize);
    }

    public TimeRange getTimeRange() {
        return timeRange;
    }

    public long getMetric(int dimension) {
        return metric.getMetric(dimension);
    }

    public long addMetric(int dimension, long value) {
        return metric.addMetric(dimension, value);
    }

    public void setMetric(int dimension, long value) {
        metric.setMetric(dimension, value);
    }

    public AtomicReference getNextBucket() {
        return nextBucket;
    }

    public AtomicInteger getCount() {
        return count;
    }

    /**
     * 获取最末端的桶
     *
     * @return Bucket
     */
    public Bucket getTailBucket() {
        Bucket head = this;
        Bucket next = head.getNextBucket().get();
        while (null != next) {
            head = next;
            next = head.getNextBucket().get();
        }
        return head;
    }

    /**
     * 计算维度下所有的时间段的值之和
     * 只要startTime或者endTime所存在的区间,或者包含在startTime-endTime之间的区间
     * 比如: 3-----6-----9-----12---15的区间,
     * 对于4-10的时间范围,则返回3-----6-----9-----12
     * 对于2-7的时间范围,则返回3-----6-----9
     *
     * @param dimension 维度下表
     * @param timeRange 时间段
     * @return long
     */
    long calcMetricsBothIncluded(int dimension, TimeRange timeRange) {
        long total = 0L;
        List buckets = new ArrayList<>();
        Bucket next = this;
        while (null != next) {
            TimeRange bucketTimeRange = next.getTimeRange();
            TimePosition posStart = bucketTimeRange.isTimeInBucket(timeRange.getStart());
            TimePosition posEnd = bucketTimeRange.isTimeInBucket(timeRange.getEnd());
            TimePosition posBucketRangeStart = timeRange.isTimeInBucket(bucketTimeRange.getStart());
            TimePosition posBucketRangeEnd = timeRange.isTimeInBucket(bucketTimeRange.getEnd());
            if (posStart == TimePosition.inside || posEnd == TimePosition.inside) {
                buckets.add(next);
            } else if (posBucketRangeStart == TimePosition.inside && posBucketRangeEnd == TimePosition.inside) {
                buckets.add(next);
            }
            next = next.getNextBucket().get();
        }
        for (Bucket bucket : buckets) {
            total += bucket.getMetric(dimension);
        }
        return total;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy