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

io.streamnative.pulsar.handlers.kop.stats.LocalData Maven / Gradle / Ivy

There is a newer version: 4.0.0.4
Show newest version
/**
 * Copyright (c) 2019 - 2024 StreamNative, Inc.. All Rights Reserved.
 */
/**
 * 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 io.streamnative.pulsar.handlers.kop.stats;

import com.yahoo.sketches.quantiles.DoublesSketch;
import com.yahoo.sketches.quantiles.DoublesSketchBuilder;
import com.yahoo.sketches.quantiles.DoublesUnion;
import io.netty.util.concurrent.FastThreadLocalThread;
import java.lang.ref.WeakReference;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.StampedLock;

public class LocalData {

    private final DoublesSketch successSketch = new DoublesSketchBuilder().build();
    private final DoublesSketch failSketch = new DoublesSketchBuilder().build();
    private final Lock lock = new StampedLock().asWriteLock();
    // Keep a weak reference to the owner thread so that we can remove the LocalData when the thread
    // is not alive anymore or has been garbage collected.
    // This reference isn't needed when the owner thread is a FastThreadLocalThread and will be null in that case.
    // The removal is handled by FastThreadLocal#onRemoval when the owner thread is a FastThreadLocalThread.
    private final WeakReference ownerThreadReference;

    public LocalData(Thread ownerThread) {
        if (ownerThread instanceof FastThreadLocalThread) {
            ownerThreadReference = null;
        } else {
            ownerThreadReference = new WeakReference<>(ownerThread);
        }
    }

    public void updateSuccessSketch(double value) {
        lock.lock();
        try {
            successSketch.update(value);
        } finally {
            lock.unlock();
        }
    }

    public void updateFailedSketch(double value) {
        lock.lock();
        try {
            failSketch.update(value);
        } finally {
            lock.unlock();
        }
    }

    public void record(DoublesUnion aggregateSuccess, DoublesUnion aggregateFail) {
        lock.lock();
        try {
            aggregateSuccess.update(successSketch);
            successSketch.reset();
            aggregateFail.update(failSketch);
            failSketch.reset();
        } finally {
            lock.unlock();
        }
    }

    public boolean shouldRemove() {
        if (ownerThreadReference == null) {
            // the owner is a FastThreadLocalThread which handles the removal using FastThreadLocal#onRemoval
            return false;
        } else {
            Thread ownerThread = ownerThreadReference.get();
            if (ownerThread == null) {
                // the thread has already been garbage collected, LocalData should be removed
                return true;
            } else {
                // the thread isn't alive anymore, LocalData should be removed
                return !ownerThread.isAlive();
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy