FOLLY_NOINLINE TrieArray fillOwnership()

in glean/rts/ownership.cpp [49:114]


FOLLY_NOINLINE TrieArray<Uset> fillOwnership(
    OwnershipUnitIterator* iter,
    uint32_t& numUnits) {
  struct Stats {
    size_t units = 0;
    size_t intervals = 0;

    void bump(size_t curUnits, size_t is) {
      units = curUnits;
      const auto old_intervals = intervals;
      intervals += is;
      if ((old_intervals / 5000000) != (intervals / 5000000)) {
        dump();
      }
    }

    void dump() {
      LOG(INFO)
        << units << " units, "
        << intervals << " intervals";
    }
  };

  TrieArray<Uset> utrie;
  uint32_t last_unit = 0;
  uint32_t max_unit = 0;
  Stats stats;
  while(const auto d = iter->get()) {
    const auto data = d.value();
    CHECK_GE(data.unit,last_unit);

    utrie.insert(
      data.ids.begin(),
      data.ids.end(),
      [&](Uset * FOLLY_NULLABLE prev, uint32_t refs) {
        if (prev != nullptr) {
          if (prev->refs == refs) {
            // Do an in-place append if possible (determined via reference
            // count).
            prev->exp.set.append(data.unit);
            return prev;
          } else {
            auto entry = std::make_unique<Uset>(
                SetU32(prev->exp.set, SetU32::copy_capacity), refs);
            entry->exp.set.append(data.unit);
            prev->refs -= refs;
            return entry.release();
          }
        } else {
          auto entry = std::make_unique<Uset>(SetU32(), refs);
          entry->exp.set.append(data.unit);
          return entry.release();
        }
      }
    );

    max_unit = std::max(data.unit, max_unit);
    stats.bump(max_unit, data.ids.size());
    last_unit = data.unit;
  }

  stats.dump();

  numUnits = max_unit + 1;
  return utrie;
}