SystemMaybe Fs::readRespressureFromLines()

in src/oomd/util/Fs.cpp [369:444]


SystemMaybe<ResourcePressure> Fs::readRespressureFromLines(
    const std::vector<std::string>& lines,
    PressureType type) {
  auto type_name = pressureTypeToString(type);
  size_t pressure_line_index = 0;
  switch (type) {
    case PressureType::SOME:
      pressure_line_index = 0;
      break;
    case PressureType::FULL:
      pressure_line_index = 1;
      break;
  }

  switch (getPsiFormat(lines)) {
    case PsiFormat::UPSTREAM: {
      // Upstream v4.16+ format
      //
      // some avg10=0.22 avg60=0.17 avg300=1.11 total=58761459
      // full avg10=0.22 avg60=0.16 avg300=1.08 total=58464525
      std::vector<std::string> toks =
          Util::split(lines[pressure_line_index], ' ');
      if (toks[0] != type_name) {
        return SYSTEM_ERROR(EINVAL);
      }
      std::vector<std::string> avg10 = Util::split(toks[1], '=');
      if (avg10[0] != "avg10") {
        return SYSTEM_ERROR(EINVAL);
      }
      std::vector<std::string> avg60 = Util::split(toks[2], '=');
      if (avg60[0] != "avg60") {
        return SYSTEM_ERROR(EINVAL);
      }
      std::vector<std::string> avg300 = Util::split(toks[3], '=');
      if (avg300[0] != "avg300") {
        return SYSTEM_ERROR(EINVAL);
      }
      std::vector<std::string> total = Util::split(toks[4], '=');
      if (total[0] != "total") {
        return SYSTEM_ERROR(EINVAL);
      }

      return ResourcePressure{
          std::stof(avg10[1]),
          std::stof(avg60[1]),
          std::stof(avg300[1]),
          std::chrono::microseconds(std::stoull(total[1])),
      };
    }
    case PsiFormat::EXPERIMENTAL: {
      // Old experimental format
      //
      // aggr 316016073
      // some 0.00 0.03 0.05
      // full 0.00 0.03 0.05
      std::vector<std::string> toks =
          Util::split(lines[pressure_line_index + 1], ' ');
      if (toks[0] != type_name) {
        return SYSTEM_ERROR(EINVAL);
      }

      return ResourcePressure{
          std::stof(toks[1]),
          std::stof(toks[2]),
          std::stof(toks[3]),
          std::nullopt,
      };
    }
    case PsiFormat::MISSING:
      // Missing the control file
      return SYSTEM_ERROR(ENOENT);
    case PsiFormat::INVALID:
      return SYSTEM_ERROR(EINVAL);
  }
  __builtin_unreachable();
}