<commit_before>#include "rdb_protocol/profile.hpp"

#include <inttypes.h>

#include <limits>

#include "errors.hpp"
#include <boost/variant/static_visitor.hpp>

#include "containers/archive/stl_types.hpp"
#include "logger.hpp"
#include "rdb_protocol/math_utils.hpp"
#include "rdb_protocol/datum.hpp"
#include "rdb_protocol/env.hpp"

namespace profile {

start_t::start_t() { }

start_t::start_t(const std::string &description)
    : description_(description), when_(get_ticks()) { }

RDB_IMPL_SERIALIZABLE_2_SINCE_v1_13(start_t, description_, when_);

split_t::split_t() { }

split_t::split_t(size_t n_parallel_jobs)
    : n_parallel_jobs_(n_parallel_jobs) { }

RDB_IMPL_SERIALIZABLE_1_SINCE_v1_13(split_t, n_parallel_jobs_);

sample_t::sample_t() { }

sample_t::sample_t(const std::string &description,
        ticks_t mean_duration, size_t n_samples)
    : description_(description), mean_duration_(mean_duration),
      n_samples_(n_samples)
{ }

RDB_IMPL_SERIALIZABLE_3_SINCE_v1_13(sample_t, description_, mean_duration_, n_samples_);

stop_t::stop_t()
    : when_(get_ticks()) { }

RDB_IMPL_SERIALIZABLE_1_SINCE_v1_13(stop_t, when_);

counted_t<const ql::datum_t> construct_start(
        ticks_t duration, std::string description,
        counted_t<const ql::datum_t> sub_tasks) {
    std::map<std::string, counted_t<const ql::datum_t> > res;
    res["duration(ms)"] = make_counted<const ql::datum_t>(safe_to_double(duration) / MILLION);
    res["description"] = make_counted<const ql::datum_t>(std::move(description));
    res["sub_tasks"] = sub_tasks;
    return make_counted<const ql::datum_t>(std::move(res));
}

counted_t<const ql::datum_t> construct_split(
        counted_t<const ql::datum_t> par_tasks) {
    std::map<std::string, counted_t<const ql::datum_t> > res;
    res["parallel_tasks"] = par_tasks;
    return make_counted<const ql::datum_t>(std::move(res));
}

counted_t<const ql::datum_t> construct_sample(
        const sample_t *sample) {
    std::map<std::string, counted_t<const ql::datum_t> > res;
    double mean_duration = safe_to_double(sample->mean_duration_) / MILLION;
    double n_samples = safe_to_double(sample->n_samples_);
    res["mean_duration(ms)"] = make_counted<const ql::datum_t>(mean_duration);
    res["n_samples"] = make_counted<const ql::datum_t>(n_samples);
    res["description"] = make_counted<const ql::datum_t>(std::string(sample->description_));
    return make_counted<const ql::datum_t>(std::move(res));
}

counted_t<const ql::datum_t> construct_datum(
        event_log_t::const_iterator *begin,
        event_log_t::const_iterator end,
        const ql::configured_limits_t &limits);

class construct_datum_visitor_t : public boost::static_visitor<void> {
public:
    construct_datum_visitor_t(
        event_log_t::const_iterator *begin, event_log_t::const_iterator end,
        const ql::configured_limits_t &limits,
        std::vector<counted_t<const ql::datum_t> > *res)
        : begin_(begin), end_(end), limits_(limits), res_(res) { }

    void operator()(const start_t &start) const {
        (*begin_)++;
        counted_t<const ql::datum_t> sub_tasks = construct_datum(begin_, end_, limits_);
        auto stop = boost::get<stop_t>(&**begin_);
        guarantee(stop);
        res_->push_back(construct_start(
            stop->when_ - start.when_, start.description_, sub_tasks));
        (*begin_)++;
    }
    void operator()(const split_t &split) const {
        (*begin_)++;
        std::vector<counted_t<const ql::datum_t> > parallel_tasks;
        for (size_t i = 0; i < split.n_parallel_jobs_; ++i) {
            parallel_tasks.push_back(construct_datum(begin_, end_, limits_));
            guarantee(boost::get<stop_t>(&**begin_));
            (*begin_)++;
        }
        res_->push_back(construct_split(
            make_counted<const ql::datum_t>(std::move(parallel_tasks), limits_)));
    }
    void operator()(const sample_t &sample) const {
        (*begin_)++;
        res_->push_back(construct_sample(&sample));
    }
    void operator()(const stop_t &) const {
        //Nothing to do here
    }

private:
    event_log_t::const_iterator *begin_;
    event_log_t::const_iterator end_;
    const ql::configured_limits_t &limits_;
    std::vector<counted_t<const ql::datum_t> > *res_;
};

counted_t<const ql::datum_t> construct_datum(
        event_log_t::const_iterator *begin,
        event_log_t::const_iterator end,
        const ql::configured_limits_t &limits) {
    std::vector<counted_t<const ql::datum_t> > res;

    construct_datum_visitor_t visitor(begin, end, limits, &res);
    while (*begin != end && !boost::get<stop_t>(&**begin)) {
        boost::apply_visitor(visitor, **begin);
    }

    return make_counted<const ql::datum_t>(std::move(res), limits);
}

class print_event_log_visitor_t : public boost::static_visitor<void> {
public:
    void operator()(const start_t &start) const {
        logINF("Start: %s.\n", start.description_.c_str());
    }
    void operator()(const split_t &split) const {
        logINF("Split: %zu.\n", split.n_parallel_jobs_);
    }<commit_msg>Per @srh use a pointer for this visitor.<commit_after>#include "rdb_protocol/profile.hpp"

#include <inttypes.h>

#include <limits>

#include "errors.hpp"
#include <boost/variant/static_visitor.hpp>

#include "containers/archive/stl_types.hpp"
#include "logger.hpp"
#include "rdb_protocol/math_utils.hpp"
#include "rdb_protocol/datum.hpp"
#include "rdb_protocol/env.hpp"

namespace profile {

start_t::start_t() { }

start_t::start_t(const std::string &description)
    : description_(description), when_(get_ticks()) { }

RDB_IMPL_SERIALIZABLE_2_SINCE_v1_13(start_t, description_, when_);

split_t::split_t() { }

split_t::split_t(size_t n_parallel_jobs)
    : n_parallel_jobs_(n_parallel_jobs) { }

RDB_IMPL_SERIALIZABLE_1_SINCE_v1_13(split_t, n_parallel_jobs_);

sample_t::sample_t() { }

sample_t::sample_t(const std::string &description,
        ticks_t mean_duration, size_t n_samples)
    : description_(description), mean_duration_(mean_duration),
      n_samples_(n_samples)
{ }

RDB_IMPL_SERIALIZABLE_3_SINCE_v1_13(sample_t, description_, mean_duration_, n_samples_);

stop_t::stop_t()
    : when_(get_ticks()) { }

RDB_IMPL_SERIALIZABLE_1_SINCE_v1_13(stop_t, when_);

counted_t<const ql::datum_t> construct_start(
        ticks_t duration, std::string description,
        counted_t<const ql::datum_t> sub_tasks) {
    std::map<std::string, counted_t<const ql::datum_t> > res;
    res["duration(ms)"] = make_counted<const ql::datum_t>(safe_to_double(duration) / MILLION);
    res["description"] = make_counted<const ql::datum_t>(std::move(description));
    res["sub_tasks"] = sub_tasks;
    return make_counted<const ql::datum_t>(std::move(res));
}

counted_t<const ql::datum_t> construct_split(
        counted_t<const ql::datum_t> par_tasks) {
    std::map<std::string, counted_t<const ql::datum_t> > res;
    res["parallel_tasks"] = par_tasks;
    return make_counted<const ql::datum_t>(std::move(res));
}

counted_t<const ql::datum_t> construct_sample(
        const sample_t *sample) {
    std::map<std::string, counted_t<const ql::datum_t> > res;
    double mean_duration = safe_to_double(sample->mean_duration_) / MILLION;
    double n_samples = safe_to_double(sample->n_samples_);
    res["mean_duration(ms)"] = make_counted<const ql::datum_t>(mean_duration);
    res["n_samples"] = make_counted<const ql::datum_t>(n_samples);
    res["description"] = make_counted<const ql::datum_t>(std::string(sample->description_));
    return make_counted<const ql::datum_t>(std::move(res));
}

counted_t<const ql::datum_t> construct_datum(
        event_log_t::const_iterator *begin,
        event_log_t::const_iterator end,
        const ql::configured_limits_t &limits);

class construct_datum_visitor_t : public boost::static_visitor<void> {
public:
    // N.B.: it is important that the lifetime of this visitor not
    // exceed the lifetime of the limits reference: for example
    // writing construct_datum_visitor_t v(begin, end,
    // ql::configured_limits_t(), &res) is a terrible idea.  When in
    // doubt, use construct_datum, which ensures that its lifetime is
    // a subset of the limits lifetime.
    construct_datum_visitor_t(
        event_log_t::const_iterator *begin, event_log_t::const_iterator end,
        const ql::configured_limits_t *limits,
        std::vector<counted_t<const ql::datum_t> > *res)
        : begin_(begin), end_(end), limits_(limits), res_(res) { }

    void operator()(const start_t &start) const {
        (*begin_)++;
        counted_t<const ql::datum_t> sub_tasks = construct_datum(begin_, end_, *limits_);
        auto stop = boost::get<stop_t>(&**begin_);
        guarantee(stop);
        res_->push_back(construct_start(
            stop->when_ - start.when_, start.description_, sub_tasks));
        (*begin_)++;
    }
    void operator()(const split_t &split) const {
        (*begin_)++;
        std::vector<counted_t<const ql::datum_t> > parallel_tasks;
        for (size_t i = 0; i < split.n_parallel_jobs_; ++i) {
            parallel_tasks.push_back(construct_datum(begin_, end_, *limits_));
            guarantee(boost::get<stop_t>(&**begin_));
            (*begin_)++;
        }
        res_->push_back(construct_split(
            make_counted<const ql::datum_t>(std::move(parallel_tasks), *limits_)));
    }
    void operator()(const sample_t &sample) const {
        (*begin_)++;
        res_->push_back(construct_sample(&sample));
    }
    void operator()(const stop_t &) const {
        //Nothing to do here
    }

private:
    event_log_t::const_iterator *begin_;
    event_log_t::const_iterator end_;
    const ql::configured_limits_t *limits_;
    std::vector<counted_t<const ql::datum_t> > *res_;
};

counted_t<const ql::datum_t> construct_datum(
        event_log_t::const_iterator *begin,
        event_log_t::const_iterator end,
        const ql::configured_limits_t &limits) {
    std::vector<counted_t<const ql::datum_t> > res;

    construct_datum_visitor_t visitor(begin, end, &limits, &res);
    while (*begin != end && !boost::get<stop_t>(&**begin)) {
        boost::apply_visitor(visitor, **begin);
    }

    return make_counted<const ql::datum_t>(std::move(res), limits);
}

class print_event_log_visitor_t : public boost::static_visitor<void> {
public:
    void operator()(const start_t &start) const {
        logINF("Start: %s.\n", start.description_.c_str());
    }
    void operator()(const split_t &split) const {
        logINF("Split: %zu.\n", split.n_parallel_jobs_);
    }
{'fraction_non_alphanumeric': 0.13979920439477173, 'fraction_numerical': 0.0032203068763023298, 'mean_word_length': 4.5080855503390715, 'pattern_counts': {'":': 0, '<': 85, '<?xml version=': 0, '>': 97, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2238956', 'n_tokens_mistral': 3802, 'n_tokens_neox': 3782, 'n_words': 610}