Commit 7178d37a authored by Hiro's avatar Hiro 🏄
Browse files

Parse stats line in network status vote

parent 99446749
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -132,6 +132,14 @@ public interface NetworkStatusEntry extends Serializable {
   */
  SortedMap<String, SortedSet<Long>> getProtocols();

  /**
   * Return the various statistics that an authority has computed for
   * this relay. Each stats is represented as a key + value.
   *
   * @since 2.20.0
   */
  SortedMap<String, Double> getStats();

  /**
   * Return the bandwidth weight of this server or -1 if the status entry
   * didn't contain a bandwidth line.
@@ -184,4 +192,3 @@ public interface NetworkStatusEntry extends Serializable {
   */
  String getMasterKeyEd25519();
}
+0 −1
Original line number Diff line number Diff line
@@ -491,4 +491,3 @@ public interface RelayNetworkStatusVote extends Descriptor {
   */
  String getDigestSha1Hex();
}
+1 −0
Original line number Diff line number Diff line
@@ -176,6 +176,7 @@ public enum Key {
  SNOWFLAKE_IPS_TOTAL("snowflake-ips-total"),
  SNOWFLAKE_IPS_WEBEXT("snowflake-ips-webext"),
  SNOWFLAKE_STATS_END("snowflake-stats-end"),
  STATS("stats"),
  TRANSPORT("transport"),
  TUNNELLED_DIR_SERVER("tunnelled-dir-server"),
  UPTIME("uptime"),
+35 −2
Original line number Diff line number Diff line
@@ -67,7 +67,7 @@ public class NetworkStatusEntryImpl implements NetworkStatusEntry {
  }

  private Set<Key> atMostOnceKeys = EnumSet.of(
      Key.S, Key.V, Key.PR, Key.W, Key.P);
      Key.S, Key.V, Key.PR, Key.W, Key.P, Key.STATS);

  private void parsedAtMostOnceKey(Key key)
      throws DescriptorParseException {
@@ -122,6 +122,9 @@ public class NetworkStatusEntryImpl implements NetworkStatusEntry {
        case ID:
          this.parseIdLine(line, parts);
          break;
        case STATS:
          this.parseStatsLine(line, parts);
          break;
        default:
          if (this.unrecognizedLines == null) {
            this.unrecognizedLines = new ArrayList<>();
@@ -197,12 +200,36 @@ public class NetworkStatusEntryImpl implements NetworkStatusEntry {
    }
  }

  /**
   * In the following methods `line` is passed twice in the function call
   * parseProtocolVersions(line, lineNoOpt, partsNoOpt) and
   * parseStats(line, lineNoOpt, partsNoOpt)
   * This is because line and lineNoOpt may represent slightly different
   * versions of the same string.
   *
   * <p>The line argument is the original string that the function is parsing,
   * while the lineNoOpt argument is a modified version of line that has any
   * optional parts removed.
   * The function checks whether an entry for the lineNoOpt key already exists
   * in the parsed map before parsing the line.
   * If an entry exists, the function immediately returns the
   * corresponding SortedMap without re-parsing the line.
   * By passing both line and lineNoOpt to the function, the caller ensures that
   * the function can distinguish between different versions of the same string
   * and correctly handle cases where the same line is parsed multiple times.
   */
  private void parsePrLine(String line, String[] parts)
      throws DescriptorParseException {
    this.parsedAtMostOnceKey(Key.PR);
    this.protocols = ParseHelper.parseProtocolVersions(line, line, parts);
  }

  private void parseStatsLine(String line, String[] parts)
      throws DescriptorParseException {
    this.parsedAtMostOnceKey(Key.STATS);
    this.stats = ParseHelper.parseStats(line, line, parts);
  }

  private void parseWLine(String line, String[] parts)
      throws DescriptorParseException {
    this.parsedAtMostOnceKey(Key.W);
@@ -376,6 +403,13 @@ public class NetworkStatusEntryImpl implements NetworkStatusEntry {
    return this.protocols;
  }

  private SortedMap<String, Double> stats;

  @Override
  public SortedMap<String, Double> getStats() {
    return this.stats;
  }

  private long bandwidth = -1L;

  @Override
@@ -418,4 +452,3 @@ public class NetworkStatusEntryImpl implements NetworkStatusEntry {
    return this.masterKeyEd25519;
  }
}
+23 −1
Original line number Diff line number Diff line
@@ -537,5 +537,27 @@ public class ParseHelper {
    }
    return parsedProtocolVersions.get(lineNoOpt);
  }

  private static Map<String, SortedMap<String, Double>>
      parsedStats = new HashMap<>();

  protected static SortedMap<String, Double> parseStats(
      String line, String lineNoOpt, String[] partsNoOpt)
      throws DescriptorParseException {
    if (!parsedProtocolVersions.containsKey(lineNoOpt)) {
      SortedMap<String, Double> parsed = new TreeMap<>();
      try {
        for (int i = 1; i < partsNoOpt.length; i++) {
          String[] part = partsNoOpt[i].split("=");
          Double stats = Double.parseDouble(part[1]);
          parsed.put(part[0], stats);
        }

      } catch (ArrayIndexOutOfBoundsException | NumberFormatException e) {
        throw new DescriptorParseException("Invalid line '" + line + "'.", e);
      }
      parsedStats.put(lineNoOpt, Collections.unmodifiableSortedMap(parsed));
    }
    return parsedStats.get(lineNoOpt);
  }
}
Loading