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

cdc.perfs.core.impl.AbstractMeasure Maven / Gradle / Ivy

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

import cdc.perfs.api.MeasureLevel;
import cdc.perfs.core.Environment;
import cdc.perfs.core.Measure;
import cdc.perfs.core.MeasureStatus;
import cdc.perfs.core.SpanPosition;
import cdc.util.lang.ByteMasks;
import cdc.util.lang.Checks;

/**
 * Base implementation of Measure.
 * 

* Measures are associated to a Context (Thread) and are organized as a forest. * * @author Damien Carbonne */ public abstract class AbstractMeasure implements Measure { /** * Cached values of MeasureStatus to avoid frequent clones. */ private static final MeasureStatus[] MEASURE_STATUS_VALUES = MeasureStatus.values(); /** * Cached values of MeasureLevel to avoid frequent clones. */ private static final MeasureLevel[] MEASURE_LEVEL_VALUES = MeasureLevel.values(); /** Associated source. */ private final SourceImpl source; /** Detail of the measure. Given by the probe at measure initialization. */ private final String details; /** First child measure (is null if no child). */ private AbstractMeasure firstChild = null; /** Next sibling measure (is null if last sibling). */ private AbstractMeasure nextSibling = null; /** Absolute start 'time' of the measure. */ protected final long begin; /** * Absolute end 'time' of the measure. *

* Meaningful when the measure is frozen. */ protected long end; private final int depth; /** * Mask for status and level: *

    *
  • 2 bits for status (3 + null values) *
  • 3 bits for level (6 + null values) *
*/ private byte bits = 0; protected AbstractMeasure(AbstractMeasure parent, AbstractMeasure previous, SourceImpl source, String details, long begin, long end, MeasureStatus status, MeasureLevel level, AbstractContext context) { this.source = source; this.details = details; this.begin = begin; this.end = end; setStatus(status); setLevel(level); if (parent == null) { context.roots.add(this); this.depth = 0; } else if (previous == null) { parent.firstChild = this; this.depth = parent.depth + 1; } else { previous.nextSibling = this; this.depth = parent.depth + 1; } context.incrementMeasuresCount(); source.incrementMeasuresCount(); } @Override public final Environment getEnvironment() { return getSource().getEnvironment(); } @Override public final SourceImpl getSource() { return source; } @Override public final String getDetails() { return details; } protected final void setStatus(MeasureStatus value) { bits = ByteMasks.set(bits, 0, value, MEASURE_STATUS_VALUES, true); } @Override public final MeasureStatus getStatus() { return ByteMasks.get(bits, 0, MEASURE_STATUS_VALUES, true); } private final void setLevel(MeasureLevel value) { bits = ByteMasks.set(bits, 2, value, MEASURE_LEVEL_VALUES, true); } @Override public final MeasureLevel getLevel() { return ByteMasks.get(bits, 2, MEASURE_LEVEL_VALUES, true); } @Override public final String getLabel() { if (details == null) { return getSource().getName(); } else { return getSource().getName() + "." + details; } } @Override public final int getDepth() { return depth; } @Override public final int getHeight() { int max = 0; for (AbstractMeasure child = firstChild; child != null; child = child.nextSibling) { max = Math.max(max, child.getHeight()); } return max + 1; } @Override public final long getAbsoluteBeginNanos() { return begin; } @Override public long getRelativeBeginNanos() { return getEnvironment().toRelative(begin); } @Override public final long getAbsoluteEndNanos() { return end; } @Override public long getAbsoluteEndOrCurrentNanos() { if (getStatus() == MeasureStatus.RUNNING) { return getEnvironment().getCurrentNanos(); } else { return end; } } @Override public final long getRelativeEndNanos() { return getEnvironment().toRelative(end); } @Override public final long getRelativeEndOrCurrentNanos() { if (getStatus() == MeasureStatus.RUNNING) { return getEnvironment().getElapsedNanos(); } else { return getEnvironment().toRelative(end); } } @Override public final AbstractMeasure getFirstChild() { return firstChild; } @Override public final int getChildrenCount() { int count = 0; AbstractMeasure child = firstChild; while (child != null) { count++; child = child.nextSibling; } return count; } @Override public final AbstractMeasure getChild(int index) { int count = 0; AbstractMeasure child = firstChild; while (count < index && child != null) { count++; child = child.nextSibling; } return child; } @Override public final AbstractMeasure getLastChild() { AbstractMeasure child = firstChild; if (child != null) { while (child.nextSibling != null) { child = child.nextSibling; } } return child; } @Override public final AbstractMeasure getNextSibling() { return nextSibling; } @Override public final AbstractMeasure getFirstChild(long inf, long sup) { if (sup < inf) { return null; } else { AbstractMeasure child = firstChild; while (child != null) { if (child.getAbsoluteBeginNanos() <= sup && child.getAbsoluteEndNanos() >= inf) { return child; } child = child.nextSibling; } return null; } } @Override public final AbstractMeasure getFirstSubChild(int level, long inf, long sup) { AbstractMeasure result = this; for (int index = 0; index < level && result != null; index++) { result = result.getFirstChild(inf, sup); } return result; } @Override public final SpanPosition getPosition(long inf, long sup) { if (begin > sup) { return SpanPosition.OUTSIDE; } else { final long cend = getAbsoluteEndOrCurrentNanos(); if (cend < inf) { return SpanPosition.OUTSIDE; } else if (inf <= begin && cend <= sup) { return SpanPosition.INSIDE; } else { return SpanPosition.OVERLAP; } } } public final int compareToNano(long nanos) { if (nanos < begin) { return 1; } else if (nanos > end) { return -1; } else { return 0; } } /** * Remove all children measures if this measure is not RUNNING. */ public final void safeRemoveChildren() { if (getStatus() != MeasureStatus.RUNNING) { removeChildren(); } } private void removeChildren() { if (firstChild != null) { Checks.assertTrue(getStatus() != MeasureStatus.RUNNING, "Unexpected status: {}", getStatus()); for (AbstractMeasure child = firstChild; child != null; child = child.nextSibling) { child.removeChildren(); } AbstractMeasure current = firstChild; final AbstractMeasure next = current.nextSibling; while (current != null) { current.nextSibling = null; current = next; } firstChild = null; } } protected final void freezeLastChild(long end) { AbstractMeasure child = firstChild; if (child != null) { while (child.nextSibling != null) { child = child.nextSibling; } if (child.getStatus() == MeasureStatus.RUNNING) { child.end = end; child.setStatus(MeasureStatus.FROZEN_ON_ERROR); child.freezeLastChild(end); } } } public final int compareToAbsolute(long time) { if (time < begin) { return 1; } else if (time > getAbsoluteEndOrCurrentNanos()) { return -1; } else { return 0; } } @Override public String toString() { return "[" + getSource() + " " + getDetails() + " " + getStatus() + " " + getLevel() + "]"; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy