Package jline.io

Class LineResultRecorder

java.lang.Object
jline.io.LineResultRecorder

public final class LineResultRecorder extends Object
Capture the result tables a run produces, with the solver that produced them.

WHY THIS EXISTS. Cross-codebase parity is asserted against one shared golden per example (goldens/baselines/*.json), keyed by SOLVER NAME. The only way to recover that key used to be scraping the banner an example printed above each table -- one regex dialect per codebase, and a value truncated to the digits the printer showed. The recorder supplies the same attribution BY CONSTRUCTION and at full precision. It is the Java twin of python/line_solver/result_recorder.py, matlab/src/io/LineResultRecorder.m and cpp/examples/parity_recorder.h.

WHERE IT HOOKS. Every result table in the JAR is materialised by one of a dozen public getters on NetworkSolver and its ensemble counterparts, and each of those wraps its body in around(java.lang.Object, java.lang.String, jline.io.LineResultRecorder.Body<T>). So an example that merely calls solver.getAvgTable() is recorded without being touched -- which is what lets the 100-odd twins already in jline.examples.java answer for the JAVA parity row unchanged.

ONE ENTRY PER OUTERMOST CALL. The ensemble solvers drive a layer solver's getter of the same name, and recording both would file every layer's table beside the ensemble's own. around(java.lang.Object, java.lang.String, jline.io.LineResultRecorder.Body<T>) counts the nesting and records only as the outermost call returns.

IT IS OFF unless enable(java.lang.String) was called or LINE_RECORD_RESULTS=1 is set, and then it costs one boolean test per getter.

THE STATE IS PROCESS-WIDE AND UNSYNCHRONISED, which is correct for what asks for it: a twin runs one example in one process on one thread, and the nesting count only means anything within that thread. A caller that drove several solves concurrently in one process would interleave their records; do not enable it there.

  • Method Details

    • isEnabled

      public static boolean isEnabled()
      True when a run asked to record. Nothing below costs anything when false.
    • enable

      public static void enable(String file)
      Turn recording on and direct the dump at file.
    • enableFromEnv

      public static void enableFromEnv()
      Turn recording on when LINE_RECORD_RESULTS=1 asked for it.
    • around

      public static <T> T around(Object solver, String view, LineResultRecorder.Body<T> body)
      Run one result getter, recording what it returned.

      The nesting count is what keeps an ensemble solve one record rather than one per layer: only the outermost getter files a table.

      Type Parameters:
      T - the table type the getter returns
      Parameters:
      solver - the solver whose getter this is
      view - which table this is: avg, node, chain, ...
      body - the getter's own body
      Returns:
      exactly what body returned
    • scalar

      public static void scalar(String solver, String row, String col, double value)
      Record a labelled scalar the example DERIVED.

      Some goldens hold a quantity no result table carries -- a state probability, a phase-type moment, a cache hit rate. They are recorded as one-row tables so everything downstream handles a single shape, and marked derived so the comparator scores them at the precision the example's own format string wrote rather than at a table's five printed digits.

      Parameters:
      solver - the golden's key for this quantity
      row - the golden's first label column for it
      col - the golden's second label column for it
      value - the quantity
    • scalar

      public static void scalar(String solver, String row, String col, String metric, double value)
      The same, under the metric column the golden files it in.

      Almost every derived golden is filed under QLen, which is what the scraper that generated them used for a labelled scalar. A few are not -- cdf_respt_populations holds response times under RespT -- and the caller must name the column the golden actually uses, because the comparator joins on it.

    • bareScalar

      public static void bareScalar(double value)
      Record a bare scalar an example prints with no label at all.

      The goldens key these OPT / OptResult / Value, which is the shape the scraper that generated them read a lone float in; recording that shape is a transcription of the golden and not a new naming scheme.

    • note

      public static void note(String solver, String why)
      Record a refusal the run made BY NAME.

      A refusal is a fact about the port and is a named skip downstream; a table that simply never arrived is a failure. The two must not look alike, which is why this is recorded rather than only printed.

    • document

      public static com.google.gson.JsonObject document()
      Everything recorded so far, as the wire document. Public for tests.
    • dump

      public static boolean dump()
      Write the JSON dump to the path enable(java.lang.String) was given. No-op when off.
    • solverLabel

      public static String solverLabel(Object solver)
      The golden's key for this solver, or null when it is not one we key by.

      A LAYERED or ENVIRONMENT solve is qualified by the member solver it drove -- LN(NC), ENV(FLD) -- because that is how several goldens spell it and because the two are genuinely different computations. The comparator reconciles the qualified and bare spellings against the golden's own key; recording the member is what gives it the evidence to do so safely.

    • solverMethod

      public static String solverMethod(Object solver)
      The method this solver resolved, or default when it pinned none.