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

cdc.perfs.core.AbstractContext Maven / Gradle / Ivy

There is a newer version: 0.52.0
Show newest version
package cdc.perfs.core;

import java.util.ArrayList;
import java.util.List;

import cdc.perfs.Context;
import cdc.perfs.Measure;
import cdc.perfs.Position;
import cdc.util.time.TimeMeasureMode;

/**
 * Base implementation of Context.
 *
 * @author Damien Carbonne
 *
 */
public abstract class AbstractContext implements Context {
    /**
     * Environment to which this context is attached.
     */
    final AbstractEnvironment environment;

    /** Id of the context. */
    private final int id;

    private final String name;

    /** List of root measures. */
    final List roots = new ArrayList<>();

    /** Number of measures in this context. */
    private int measuresCount = 0;

    void incrementMeasuresCount() {
        measuresCount++;
        environment.fireContextChanged(this);
    }

    protected AbstractContext(AbstractEnvironment environment,
                              int id,
                              String name) {
        this.environment = environment;
        this.id = id;
        this.name = name;
    }

    @Override
    public AbstractEnvironment getEnvironment() {
        return environment;
    }

    @Override
    public final int getId() {
        return id;
    }

    @Override
    public final String getName() {
        return name;
    }

    @Override
    public final int getRootMeasuresCount() {
        return roots.size();
    }

    @Override
    public final Measure getRootMeasure(int index) {
        return roots.get(index);
    }

    @Override
    public final Measure getMeasure(long time,
                                    TimeMeasureMode mode,
                                    long epsilon,
                                    int depth) {
        if (epsilon < 0) {
            throw new IllegalArgumentException("Negative epsilon");
        }

        // Do all computations using absolute times
        final long atime = environment.toAbsolute(time, mode);

        // Lower time bound
        final long inf = atime - epsilon;
        // Higher time bound
        final long sup = atime + epsilon;

        final int index = getRootMeasureIndex(atime, TimeMeasureMode.ABSOLUTE, Position.EQUAL);
        final Measure root;

        if (index >= 0) {
            // An exact matching root (level = 0) measure has been found
            root = getRootMeasure(index);
        } else {
            // No exact matching root measure was found
            // Try to use tolerance
            final int first = getRootMeasureIndex(inf, TimeMeasureMode.ABSOLUTE, Position.GREATER_OR_EQUAL);
            final int last = getRootMeasureIndex(sup, TimeMeasureMode.ABSOLUTE, Position.LESS_OR_EQUAL);

            if (first <= last) {
                // Choose the measure that is approximatively in the middle
                // This may not be the best choice, but it should suffice
                root = getRootMeasure((first + last) / 2);
            } else {
                root = null;
            }
        }

        if (root == null) {
            return null;
        } else {
            Measure sub = root.getFirstSubChild(depth, inf, sup);
            if (sub == null) {
                return null;
            } else {
                while (sub != null) {
                    if (sub.getAbsoluteBeginNanos() <= sup && sub.getAbsoluteEndOrCurrentNanos() >= inf) {
                        return sub;
                    }
                    sub = sub.getNextSibling();
                }
                return null;
            }
        }
    }

    @Override
    public final int getRootMeasureIndex(long time,
                                         TimeMeasureMode mode,
                                         Position position) {
        int low = 0;
        int high = roots.size() - 1;

        while (low <= high) {
            final int mid = (low + high) >>> 1;
            final AbstractMeasure measure = roots.get(mid);
            final int compare = measure.compareToAbsolute(environment.toAbsolute(time, mode));

            if (compare < 0) {
                low = mid + 1;
            } else if (compare > 0) {
                high = mid - 1;
            } else {
                return mid; // Found a matching root
            }
        }

        // No root was found

        switch (position) {
        case GREATER_OR_EQUAL:
            return roots.isEmpty() ? -1 : low;
        case LESS_OR_EQUAL:
            return high;
        case EQUAL:
        default:
            return -1;
        }
    }

    @Override
    public final int getMeasuresCount() {
        return measuresCount;
    }

    @Override
    public String toString() {
        return getClass().getSimpleName() + "-" + getId();
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy