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

com.yahoo.concurrent.LocalInstance Maven / Gradle / Ivy

// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.concurrent;

import com.yahoo.concurrent.ThreadLocalDirectory.ObservableUpdater;
import com.yahoo.concurrent.ThreadLocalDirectory.Updater;

/**
 * Only for use along with ThreadLocalDirectory. A thread local data container
 * instance. The class is visible to avoid indirection through the internal
 * {@link ThreadLocal} in ThreadLocalDirectory if possible, but has no user
 * available methods.
 *
 * @param  the structure to insert produced data into
 * @param  type of produced data to insert from each participating thread
 * @author Steinar Knutsen
 */
public final class LocalInstance {

    /**
     * The current generation of data produced from a single thread, where
     * generation is the period between two subsequent calls to
     * ThreadLocalDirectory.fetch().
     */
    private AGGREGATOR current;

    // see comment on setRegistered(boolean) for locking explanation
    private boolean isRegistered = false;
    private final Object lock = new Object();

    LocalInstance(Updater updater) {
        current = updater.createGenerationInstance(null);
    }

    boolean update(SAMPLE x, Updater updater) {
        synchronized (lock) {
            current = updater.update(current, x);
            return isRegistered;
        }
    }

    AGGREGATOR getAndReset(Updater updater) {
        AGGREGATOR previous;
        synchronized (lock) {
            previous = current;
            current = updater.createGenerationInstance(previous);
            setRegistered(false);
        }
        return previous;
    }

    AGGREGATOR copyCurrent(ObservableUpdater updater) {
        AGGREGATOR view;
        synchronized (lock) {
            view = updater.copy(current);
        }
        return view;
    }

    // This is either set by the putting thread or the fetching thread. If
    // it is set by the putting thread, then there is no memory barrier,
    // because it is only _read_ in the putting thread. If it is set by the
    // fetching thread, then the memory barrier is this.lock. This
    // roundabout way is to avoid creating many-to-many memory barrier and
    // locking relationships.
    void setRegistered(boolean isRegistered) {
        this.isRegistered = isRegistered;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy