Modules/tools/MemBenchmark/patterns.h
2023-05-26 01:35:29 +03:00

174 lines
4 KiB
C++

#pragma once
#include "strings.h"
#include <iostream>
#include "collector.h"
tp::alni hash(const tp::string& val);
#include "map.h"
enum class leav_pattern_type {
LINEAR,
RANDOM,
SINE,
CONST,
};
struct child_pattern {
child_pattern() {}
child_pattern(tp::string _name) { name = _name; }
float uppernlim = 1.f;
float lowerlim = 0.f;
float point = 1.f;
tp::string name;
};
struct pattern {
leav_pattern_type type = leav_pattern_type::CONST;
tp::string pattern_name;
tp::Array<child_pattern> regions;
bool build_in = true;
pattern() {
}
tp::alnf get_y(tp::HashMap<pattern*, tp::string>* patterns, tp::alnf x) {
assert(x <= 1.0001f && x >= -0.00001f);
if (!regions.length()) {
return pure_get_y(x);
}
float offset = 0.f;
for (tp::alni i = 0; i < regions.length(); i++) {
tp::alni idx = patterns->presents(regions[i].name);
if (!MAP_VALID_IDX(idx)) {
return 0.f;
}
pattern* child = (*patterns)[idx];
assert(child);
float range = regions[i].point * (1.f - offset);
if (offset + range > x) {
return regions[i].lowerlim +
(child->get_y(patterns, (x - offset) / range) *
(regions[i].uppernlim - regions[i].lowerlim));
}
offset += range;
}
return 0;
}
virtual tp::alnf pure_get_y(tp::alnf x) { return 0; }
~pattern() {}
};
// -------------------- build-in patterns ---------------------------- //
struct const_pattern : pattern {
float val = 1.f;
const_pattern() {
type = leav_pattern_type::CONST;
pattern_name = "const";
build_in = true;
}
tp::alnf pure_get_y(tp::alnf x) override { return val; }
};
struct linear_pattern : pattern {
bool reversed = false;
linear_pattern() {
type = leav_pattern_type::LINEAR;
pattern_name = "linear";
build_in = true;
}
tp::alnf pure_get_y(tp::alnf x) override { return reversed ? 1.f - x : x; }
};
struct random_pattern : pattern {
random_pattern() {
type = leav_pattern_type::RANDOM;
build_in = true;
}
tp::alnf pure_get_y(tp::alnf x) override { return tp::randf(); }
};
// -------------------- build-in patterns end ---------------------------- //
struct pattern_scale {
int items = 0;
int size = 0;
int iterations = 0;
};
class pattern_reader : public test_pattern {
public:
bool init(tp::HashMap<pattern*, tp::string>* p_patterns, pattern* p_lpattern,
pattern* p_opattern, pattern* p_spattern, pattern_scale* p_scale) {
lpattern = p_lpattern;
opattern = p_opattern;
spattern = p_spattern;
scale = p_scale;
patterns = p_patterns;
return verify_rulles();
}
bool verify_rulles() {
if (!lpattern || !opattern || !spattern) {
return false;
}
bool out = true;
out &= scale->items > 0;
out &= scale->size > 0;
out &= scale->iterations > 0;
return out;
}
tp::HashMap<pattern*, tp::string>* patterns;
pattern* lpattern = NULL;
pattern* opattern = NULL;
pattern* spattern = NULL;
pattern_scale* scale = 0;
tp::alnf get_x_val(tp::alni iter) {
tp::alnf out = iter / (tp::alnf)scale->iterations;
return out > 1 ? 1.f : out;
}
tp::alni pick_size(tp::alni iter) override {
return (tp::alni)(scale->size * spattern->get_y(patterns, get_x_val(iter)));
}
tp::alni pick_alloc_count(tp::alni iter) override {
return (tp::alni)(scale->items * lpattern->get_y(patterns, get_x_val(iter)));
}
tp::alni pick_idx(tp::alni iter) override {
tp::alni out = (tp::alni) (scale->items * opattern->get_y(patterns, get_x_val(iter)));
CLAMP(out, 0, scale->items - 1);
return out;
}
tp::alni max_size() override { return scale->size; }
tp::alni max_iterations() override { return scale->iterations; }
tp::alni data_count() override { return scale->iterations; }
};