void QueryExecutor::saveState()

in glean/rts/query.cpp [303:344]


void QueryExecutor::saveState(uint64_t *pc, uint64_t *frame) {
  thrift::internal::QueryCont cont;
  std::vector<thrift::internal::KeyIterator> contIters;

  for (auto &iter : iters) {
    thrift::internal::KeyIterator i;
    if (auto fact = iter.iter->get(FactIterator::KeyOnly)) {
      i.type() = iter.type.toWord();
      i.key() = binary::mkString(fact.key());
      i.prefix_size() = static_cast<int64_t>(iter.prefix_size);
      i.first() = iter.first;
    } else {
      // A finished iterator - we have no key to serialize
      i.type() = Pid::invalid().toWord();
    }
    contIters.emplace_back(std::move(i));
  }
  cont.iters() = std::move(contIters);

  std::vector<std::string> contOutputs;
  for (auto &output : outputs) {
    contOutputs.emplace_back(output.string());
  }
  cont.outputs() = std::move(contOutputs);

  thrift::internal::SubroutineState subState;
  subState.code() =
      std::string(reinterpret_cast<const char *>(sub.code.data()),
                  sub.code.size() * sizeof(uint64_t));
  subState.entry() = pc - sub.code.data();
  subState.literals() = sub.literals;
  std::vector<int64_t> locals(sub.locals);
  std::copy(frame + sub.inputs, frame + sub.inputs + sub.locals, locals.data());
  subState.locals() = std::move(locals);
  subState.inputs() = sub.inputs;
  cont.sub() = std::move(subState);
  cont.pid() = pid.toWord();
  if (traverse) {
    cont.traverse() = Subroutine::toThrift(*traverse);
  }
  queryCont = std::move(cont);
};