Требуется написать классы для проведения над логами операции схлопывания (reduce).
Каждый такой класс имеет префикс Local::Reducer. Отвечает за непосредственно схлопывания, но абстрагирован от способа получения и парсинга данных.
Параметры конструктора:
source— объект, выдающий строки из лога (см. ниже);row_class— имя класса, с помощью которого создаются объекты из каждой строки логов (см. ниже);initial_value— инициализационое значение для операции схлопывания.
Методы:
reduce_n($n)— схлопнуть очередные$nстрок, вернуть промежуточный результат.reduce_all()— схлопнуть все оставшиеся строки, вернуть результат.reduced— промежуточный результат.
Минимум надо реализовать:
Local::Reducer— базовый абстрактный класс.Local::Reducer::Sum— суммирует значение поля, указанного в параметреfieldконструктора, каждой строки лога. В случае, если соответствующее поле не содержит числовое значение, строка игнорируется.Local::Reducer::MaxDiff— выясняет максимальную разницу между полями, указанными в параметрахtopиbottomконструктора, среди всех строк лога. В случае, если соответствующие поля не содержат числовые значения, строка игнорируется.
Также можно реализовать:
Local::Reducer::MinMaxAvg— считает минимум, максимум и среднее по полю, указанному в параметреfield. Результат (reduced) отдается в виде объекта с методамиget_max,get_min,get_avg. В случае, если соответствующие поля не содержат числовые значения, строка игнорируется.
Класс, объекты которого отвечают за подачу данных в Reducer. Отвечает за получение данных (через интерфейс типа "итератор"), но не за их парсинг.
Методы:
next— возвращает очередную строку илиundef, если лог исчерпан.
Минимум надо реализовать:
Local::Source::Array— отдает поэлементно массив, который передается в конструктор в параметреarray.Local::Source::Text— отдает построчно текст, который передается в конструктор в параметреtext. Разделитель —\n, но можно изменить параметром конструктораdelimiter.
Также можно реализовать:
Local::Source::FileHandler— отдает построчно содержимое файла, дескриптор которого передается в конструктор в параметреfh. Реализация должна позволять обрабатывать большие файлы (десятки гигабайт).
Класс, объекты которого отвечают за парсинг строк из источника. Формат логов может быть разным, для каждого нужен свой подкласс Row. Объекты этого класса — иммутабельны, на каждую новую строку создается новый объект. В случае, если формат строки не распознается данным классом как допустимый, конструктор не создает объект и возвращает undef.
Параметры конструктора:
str— строка из источника.
Методы:
get($name, $default)— возвращает значение поля$nameстроки лога или$default, если таковое отсутствует.
Минимум надо реализовать:
Local::Row::Simple— каждая строка — набор парключ:значение, соединенных запятой. В ключах и значениях не может быть двоеточий и запятых.Local::Row::JSON— каждая строка — JSON-object (хеш в формате JSON).
my $reducer = Local::Reducer::Sum->new(
field => 'price',
source => Local::Source::Array->new(array => [
'{"price": 1}',
'{"price": 2}',
'{"price": 3}',
]),
row_class => 'Local::Row::JSON',
initial_value => 0,
);Этот пример создает редьюсер, который посчитает сумму по полям price всех строк лога. Сам лог — это массив JSON-ов. $reducer->reduce_all() вернет 6.
my $reducer = Local::Reducer::MaxDiff->new(
top => 'received',
bottom => 'sended',
source => Local::Source::Text->new(text =>"sended:1024,received:2048\nsended:2048,received:10240"),
row_class => 'Local::Row::Simple',
initial_value => 0,
);Этот пример создает редьюсер, который считает максимальную разницу между полями received и sended, указанными в параметрах top и bottom конструктора. Сам лог — это набор строк, где каждая строка — набор пар ключ:значение соединенных запятыми. $reducer->reduce_all() вернет 8192.