package org.sef4j.callstack.stattree.changes; import java.util.function.Function; import org.sef4j.callstack.stats.PerfStats; import org.sef4j.callstack.stats.dto.BasicStatPropTreeValueProviderDef; import org.sef4j.core.helpers.export.ExportFragment; import org.sef4j.core.helpers.export.ExportFragmentsAdder; import org.sef4j.core.helpers.proptree.changes.AbstractPropTreeValueProvider; import org.sef4j.core.helpers.proptree.model.PropTreeNode; import org.sef4j.core.util.factorydef.DependencyObjectCreationContext; /** * collector of changed PerfStats since previous copy, ignoring Pending counts * * this is a "basic" implementation: no optimization to avoid recursing in untouched sub-tree * A better implementation should count occurrences+pending to check when a sub-tree is unmodified. */ public class BasicStatPropTreeValueProvider extends AbstractPropTreeValueProvider<PerfStats> { public static final Function<PropTreeNode, PerfStats> DEFAULT_PERFSTAT_SRC_COPY_EXTRACTOR = new Function<PropTreeNode, PerfStats>() { @Override public PerfStats apply(PropTreeNode t) { PerfStats tmpRes = // t.getOrCreateProp("stats", PerfStats.FACTORY); t.getPropOrNull("stats", PerfStats.class); return (tmpRes != null)? tmpRes.clone() : null; } }; public static final Function<PropTreeNode, PerfStats> DEFAULT_PERFSTAT_PREV_EXTRACTOR = new Function<PropTreeNode, PerfStats>() { @Override public PerfStats apply(PropTreeNode t) { return t.getOrCreateProp("stats", PerfStats.FACTORY); } }; // ------------------------------------------------------------------------ public BasicStatPropTreeValueProvider(PropTreeNode srcRoot) { super(srcRoot, PropTreeNode.newRoot(), DEFAULT_PERFSTAT_SRC_COPY_EXTRACTOR, DEFAULT_PERFSTAT_PREV_EXTRACTOR); } public BasicStatPropTreeValueProvider( PropTreeNode srcRoot, PropTreeNode prevRoot, Function<PropTreeNode, PerfStats> srcValueCopyExtractor, Function<PropTreeNode, PerfStats> prevValueExtractor) { super(srcRoot, prevRoot, srcValueCopyExtractor, prevValueExtractor); } // ------------------------------------------------------------------------ @Override protected void provideFragments(PropTreeNode src, String currPath, ExportFragmentsAdder<PerfStats> out) { PerfStats srcPerfStats = srcValueCopyExtractor.apply(src); // copy new value out.addEntry(new ExportFragment<PerfStats>(this, currPath, srcPerfStats)); } @Override protected void markAndCollectChanges(PropTreeNode src, PropTreeNode prev, String currPath, ExportFragmentsAdder<PerfStats> out) { PerfStats srcPerfStats = srcValueCopyExtractor.apply(src); // copy new value PerfStats prevPerfStats = prevValueExtractor.apply(prev); // by ref if (compareHasChangeCount(srcPerfStats, prevPerfStats)) { prevPerfStats.set(srcPerfStats); out.addEntry(new ExportFragment<PerfStats>(this, currPath, srcPerfStats)); } } protected boolean compareHasChangeCount(PerfStats src, PerfStats prev) { // if (src.getPendingCount() != prev.getPendingCount()) { // return true; // } if (src.getElapsedTimeStats().compareHasChangeCount(prev.getElapsedTimeStats())) { return true; } return false; } // ------------------------------------------------------------------------ public static class Factory extends ExportFragmentsProviderFactory<BasicStatPropTreeValueProviderDef,BasicStatPropTreeValueProvider> { public Factory() { super("BasicStatPropTreeValueProvider", BasicStatPropTreeValueProviderDef.class); } @Override public BasicStatPropTreeValueProvider create( BasicStatPropTreeValueProviderDef def, DependencyObjectCreationContext ctx) { PropTreeNode rootNode = ctx.getOrCreateDependencyByDef("rootNode", def.getRootNodeDef()); return new BasicStatPropTreeValueProvider(rootNode); } } }