<commit_before>
#pragma once

#include "Werk/Math/OrderStatistics.hpp"
#include "Werk/Math/SummaryStatistics.hpp"

namespace werk
{

class Profile
{
public:

	Profile(uint64_t sampleSize = 100) : _sampleSize(sampleSize) { }

	uint64_t sampleSize() const { return _sampleSize; }
	const OrderStatistics<uint64_t> &orderStatistics() const { return _orderStatistics; }
	const SummaryStatistics<uint64_t> &f50Statistics() const { return _f50Statistics; }
	const SummaryStatistics<uint64_t> &f75Statistics() const { return _f75Statistics; }
	const SummaryStatistics<uint64_t> &f90Statistics() const { return _f90Statistics; }
	const SummaryStatistics<uint64_t> &f95Statistics() const { return _f95Statistics; }
	const SummaryStatistics<uint64_t> &f99Statistics() const { return _f99Statistics; }

	void start(uint64_t time) {
		_startTime = time;
	}
	void stop(uint64_t time) {
		//Started?
		if (_startTime == 0) {
			return;
		}

		//Sample
		uint64_t delta = time - _startTime;
		_orderStatistics.sample(delta);
		_startTime = 0;

		//Bin done?
		if (_orderStatistics.count() >= _sampleSize) {
			_f50Statistics.sample(_orderStatistics.fractile(0.50));
			_f75Statistics.sample(_orderStatistics.fractile(0.75));
			_f90Statistics.sample(_orderStatistics.fractile(0.90));
			_f95Statistics.sample(_orderStatistics.fractile(0.95));
			_f99Statistics.sample(_orderStatistics.fractile(0.99));
			_orderStatistics.reset();
		}
	}
	void restart(uint64_t time) {
		stop(time);
		start(time);
	}

	void reset() {
		_startTime = 0;
		_orderStatistics.reset();
		_f50Statistics.reset();
		_f75Statistics.reset();
		_f90Statistics.reset();
		_f95Statistics.reset();
		_f99Statistics.reset();
	}

private:

	//Current state
	uint64_t _startTime = 0;

	//Samples used for approximating fractiles efficiently
	uint64_t _sampleSize;
	OrderStatistics<uint64_t> _orderStatistics;

	//Statistics taken from samples of the order statstics every _sampleSize samples<commit_msg>Expose forced sampling of the fractiles in the Profile class<commit_after>
#pragma once

#include "Werk/Math/OrderStatistics.hpp"
#include "Werk/Math/SummaryStatistics.hpp"

namespace werk
{

class Profile
{
public:

	Profile(uint64_t sampleSize = 100) : _sampleSize(sampleSize) { }

	uint64_t sampleSize() const { return _sampleSize; }
	const OrderStatistics<uint64_t> &orderStatistics() const { return _orderStatistics; }
	const SummaryStatistics<uint64_t> &f50Statistics() const { return _f50Statistics; }
	const SummaryStatistics<uint64_t> &f75Statistics() const { return _f75Statistics; }
	const SummaryStatistics<uint64_t> &f90Statistics() const { return _f90Statistics; }
	const SummaryStatistics<uint64_t> &f95Statistics() const { return _f95Statistics; }
	const SummaryStatistics<uint64_t> &f99Statistics() const { return _f99Statistics; }

	void start(uint64_t time) {
		_startTime = time;
	}
	void stop(uint64_t time) {
		//Started?
		if (_startTime == 0) {
			return;
		}

		//Sample
		uint64_t delta = time - _startTime;
		_orderStatistics.sample(delta);
		_startTime = 0;

		//Bin done?
		if (_orderStatistics.count() >= _sampleSize) {
			sampleFractiles();
		}
	}
	void restart(uint64_t time) {
		stop(time);
		start(time);
	}

	void sampleFractiles() {
		if (_orderStatistics.count() == 0) {
			return;
		}

		_f50Statistics.sample(_orderStatistics.fractile(0.50));
		_f75Statistics.sample(_orderStatistics.fractile(0.75));
		_f90Statistics.sample(_orderStatistics.fractile(0.90));
		_f95Statistics.sample(_orderStatistics.fractile(0.95));
		_f99Statistics.sample(_orderStatistics.fractile(0.99));
		_orderStatistics.reset();
	}
	void reset() {
		_startTime = 0;
		_orderStatistics.reset();
		_f50Statistics.reset();
		_f75Statistics.reset();
		_f90Statistics.reset();
		_f95Statistics.reset();
		_f99Statistics.reset();
	}

private:

	//Current state
	uint64_t _startTime = 0;

	//Samples used for approximating fractiles efficiently
	uint64_t _sampleSize;
	OrderStatistics<uint64_t> _orderStatistics;

	//Statistics taken from samples of the order statstics every _sampleSize samples
{'fraction_non_alphanumeric': 0.1127003699136868, 'fraction_numerical': 0.04562268803945746, 'mean_word_length': 5.2592592592592595, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 19, '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': '4798990', 'n_tokens_mistral': 1525, 'n_tokens_neox': 1340, 'n_words': 277}