Skip to content

Commit

Permalink
kirk review
Browse files Browse the repository at this point in the history
  • Loading branch information
davemarco committed Dec 13, 2024
1 parent feec5ef commit 61e1e83
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 97 deletions.
176 changes: 101 additions & 75 deletions src/clp_ffi_js/ir/StreamReader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <emscripten/val.h>

#include <clp_ffi_js/constants.hpp>
#include <clp_ffi_js/ir/LogEventWithFilterData.hpp>

namespace clp_ffi_js::ir {
// JS types used as inputs
Expand All @@ -31,6 +32,9 @@ enum class StreamType : uint8_t {
Unstructured,
};

template <typename LogEvent>
using LogEvents = std::vector<LogEventWithFilterData<LogEvent>>;

/**
* Mapping between an index in the filtered log events collection to an index in the unfiltered
* log events collection.
Expand Down Expand Up @@ -115,42 +119,8 @@ class StreamReader {
[[nodiscard]] virtual auto decode_range(size_t begin_idx, size_t end_idx, bool use_filter) const
-> DecodedResultsTsType = 0;

/**
* Templated implementation of `filter_log_events`.
*
* @tparam LogEvent
* @param log_level_filter
* @param log_events Derived class's log events.
* @param log_events
* @param[out] filtered_log_event_map Returns the filtered log events.
*/
template <typename LogEvent>
static auto generic_filter_log_events(
FilteredLogEventsMap& filtered_log_event_map,
LogLevelFilterTsType const& log_level_filter,
std::vector<LogEventWithFilterData<LogEvent>> const& log_events
) -> void {
if (log_level_filter.isNull()) {
filtered_log_event_map.reset();
return;
}

filtered_log_event_map.emplace();
auto filter_levels
= emscripten::vecFromJSArray<std::underlying_type_t<LogLevel>>(log_level_filter);

for (size_t log_event_idx = 0; log_event_idx < log_events.size(); ++log_event_idx) {
auto const& log_event = log_events[log_event_idx];
if (std::ranges::find(
filter_levels,
clp::enum_to_underlying_type(log_event.get_log_level())
)
!= filter_levels.end())
{
filtered_log_event_map->emplace_back(log_event_idx);
}
}
}
protected:
explicit StreamReader() = default;

/**
* Templated implementation of `decode_range` that uses `log_event_to_string` to convert
Expand All @@ -176,55 +146,111 @@ class StreamReader {
size_t begin_idx,
size_t end_idx,
FilteredLogEventsMap const& filtered_log_event_map,
std::vector<LogEventWithFilterData<LogEvent>> const& log_events,
LogEvents<LogEvent> const& log_events,
ToStringFunc log_event_to_string,
bool use_filter
) -> DecodedResultsTsType {
if (use_filter && false == filtered_log_event_map.has_value()) {
return DecodedResultsTsType{emscripten::val::null()};
}
) -> DecodedResultsTsType;

/**
* Templated implementation of `filter_log_events`.
*
* @tparam LogEvent
* @param log_level_filter
* @param log_events Derived class's log events.
* @param log_events
* @param[out] filtered_log_event_map Returns the filtered log events.
*/
template <typename LogEvent>
static auto generic_filter_log_events(
FilteredLogEventsMap& filtered_log_event_map,
LogLevelFilterTsType const& log_level_filter,
LogEvents<LogEvent> const& log_events
) -> void;
};

template <typename LogEvent, typename ToStringFunc>
requires requires(ToStringFunc func, LogEvent const& log_event) {
{
func(log_event)
} -> std::convertible_to<std::string>;
}
auto StreamReader::generic_decode_range(
size_t begin_idx,
size_t end_idx,
FilteredLogEventsMap const& filtered_log_event_map,
LogEvents<LogEvent> const& log_events,
ToStringFunc log_event_to_string,
bool use_filter
) -> DecodedResultsTsType {
if (use_filter && false == filtered_log_event_map.has_value()) {
return DecodedResultsTsType{emscripten::val::null()};
}

size_t length{0};
if (use_filter) {
length = filtered_log_event_map->size();
} else {
length = log_events.size();
}
if (length < end_idx || begin_idx > end_idx) {
return DecodedResultsTsType{emscripten::val::null()};
}

size_t length{0};
auto const results{emscripten::val::array()};

for (size_t i = begin_idx; i < end_idx; ++i) {
size_t log_event_idx{0};
if (use_filter) {
length = filtered_log_event_map->size();
log_event_idx = filtered_log_event_map->at(i);
} else {
length = log_events.size();
}
if (length < end_idx || begin_idx > end_idx) {
return DecodedResultsTsType{emscripten::val::null()};
log_event_idx = i;
}

auto const results{emscripten::val::array()};

for (size_t i = begin_idx; i < end_idx; ++i) {
size_t log_event_idx{0};
if (use_filter) {
log_event_idx = filtered_log_event_map->at(i);
} else {
log_event_idx = i;
}

auto const& log_event_with_filter_data{log_events.at(log_event_idx)};
auto const& log_event = log_event_with_filter_data.get_log_event();
auto const& timestamp = log_event_with_filter_data.get_timestamp();
auto const& log_level = log_event_with_filter_data.get_log_level();

EM_ASM(
{ Emval.toValue($0).push([UTF8ToString($1), $2, $3, $4]); },
results.as_handle(),
log_event_to_string(log_event).c_str(),
timestamp,
log_level,
log_event_idx + 1
);
}
auto const& log_event_with_filter_data{log_events.at(log_event_idx)};
auto const& log_event = log_event_with_filter_data.get_log_event();
auto const& timestamp = log_event_with_filter_data.get_timestamp();
auto const& log_level = log_event_with_filter_data.get_log_level();

return DecodedResultsTsType(results);
EM_ASM(
{ Emval.toValue($0).push([UTF8ToString($1), $2, $3, $4]); },
results.as_handle(),
log_event_to_string(log_event).c_str(),
timestamp,
log_level,
log_event_idx + 1
);
}

protected:
explicit StreamReader() = default;
};
return DecodedResultsTsType(results);
}

template <typename LogEvent>
auto StreamReader::generic_filter_log_events(
FilteredLogEventsMap& filtered_log_event_map,
LogLevelFilterTsType const& log_level_filter,
LogEvents<LogEvent> const& log_events
) -> void {
if (log_level_filter.isNull()) {
filtered_log_event_map.reset();
return;
}

filtered_log_event_map.emplace();
auto filter_levels
= emscripten::vecFromJSArray<std::underlying_type_t<LogLevel>>(log_level_filter);

for (size_t log_event_idx = 0; log_event_idx < log_events.size(); ++log_event_idx) {
auto const& log_event = log_events[log_event_idx];
if (std::ranges::find(
filter_levels,
clp::enum_to_underlying_type(log_event.get_log_level())
)
!= filter_levels.end())
{
filtered_log_event_map->emplace_back(log_event_idx);
}
}
}
} // namespace clp_ffi_js::ir

#endif // CLP_FFI_JS_IR_STREAMREADER_HPP
2 changes: 1 addition & 1 deletion src/clp_ffi_js/ir/StructuredIrStreamReader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
namespace clp_ffi_js::ir {
using schema_tree_node_id_t = std::optional<clp::ffi::SchemaTree::Node::id_t>;
using StructuredIrDeserializer = clp::ffi::ir_stream::Deserializer<StructuredIrUnitHandler>;
using StructuredLogEvents = std::vector<LogEventWithFilterData<StructuredLogEvent>>;
using StructuredLogEvents = LogEvents<StructuredLogEvent>;

/**
* Class to deserialize and decode Zstd-compressed CLP structured IR streams, as well as format
Expand Down
34 changes: 19 additions & 15 deletions src/clp_ffi_js/ir/StructuredIrUnitHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,20 +101,22 @@ auto StructuredIrUnitHandler::get_log_level(
if (false == m_log_level_node_id.has_value()) {
return log_level;
}
auto const& log_level_pair{id_value_pairs.at(m_log_level_node_id.value())};
if (false == log_level_pair.has_value()) {
auto const& log_level_optional_value{id_value_pairs.at(m_log_level_node_id.value())};
if (false == log_level_optional_value.has_value()) {
return log_level;
}
if (log_level_pair->is<std::string>()) {
auto const& log_level_node_value = log_level_pair.value().get_immutable_view<std::string>();
log_level = parse_log_level(log_level_node_value);
} else if (log_level_pair->is<clp::ffi::value_int_t>()) {
auto const& log_level_node_value
= (log_level_pair.value().get_immutable_view<clp::ffi::value_int_t>());
if (log_level_node_value >= clp::enum_to_underlying_type(cValidLogLevelsBeginIdx)
&& log_level_node_value < clp::enum_to_underlying_type(LogLevel::LENGTH))

auto const log_level_value = log_level_optional_value.value();

if (log_level_value.is<std::string>()) {
auto const& log_level_str = log_level_value.get_immutable_view<std::string>();
log_level = parse_log_level(log_level_str);
} else if (log_level_value.is<clp::ffi::value_int_t>()) {
auto const& log_level_int = (log_level_value.get_immutable_view<clp::ffi::value_int_t>());
if (log_level_int >= clp::enum_to_underlying_type(cValidLogLevelsBeginIdx)
&& log_level_int < clp::enum_to_underlying_type(LogLevel::LENGTH))
{
log_level = static_cast<LogLevel>(log_level_node_value);
log_level = static_cast<LogLevel>(log_level_int);
}
} else {
auto log_event_idx = m_deserialized_log_events->size();
Expand All @@ -135,13 +137,15 @@ auto StructuredIrUnitHandler::get_timestamp(
if (false == m_timestamp_node_id.has_value()) {
return timestamp;
}
auto const& timestamp_pair{id_value_pairs.at(m_timestamp_node_id.value())};
if (false == timestamp_pair.has_value()) {
auto const& timestamp_optional_value{id_value_pairs.at(m_timestamp_node_id.value())};
if (false == timestamp_optional_value.has_value()) {
return timestamp;
}
if (timestamp_pair->is<clp::ffi::value_int_t>()) {
auto const timestamp_value = timestamp_optional_value.value();

if (timestamp_value.is<clp::ffi::value_int_t>()) {
timestamp = static_cast<clp::ir::epoch_time_ms_t>(
timestamp_pair.value().get_immutable_view<clp::ffi::value_int_t>()
timestamp_value.get_immutable_view<clp::ffi::value_int_t>()
);
} else {
// TODO: Add support for parsing string-type timestamp values.
Expand Down
6 changes: 1 addition & 5 deletions src/clp_ffi_js/ir/UnstructuredIrStreamReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,7 @@ auto UnstructuredIrStreamReader::get_filtered_log_event_map() const -> FilteredL
}

void UnstructuredIrStreamReader::filter_log_events(LogLevelFilterTsType const& log_level_filter) {
generic_filter_log_events(
m_filtered_log_event_map,
log_level_filter,
m_encoded_log_events
);
generic_filter_log_events(m_filtered_log_event_map, log_level_filter, m_encoded_log_events);
}

auto UnstructuredIrStreamReader::deserialize_stream() -> size_t {
Expand Down
2 changes: 1 addition & 1 deletion src/clp_ffi_js/ir/UnstructuredIrStreamReader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
namespace clp_ffi_js::ir {
using clp::ir::four_byte_encoded_variable_t;
using UnstructuredIrDeserializer = clp::ir::LogEventDeserializer<four_byte_encoded_variable_t>;
using UnstructuredLogEvents = std::vector<LogEventWithFilterData<UnstructuredLogEvent>>;
using UnstructuredLogEvents = LogEvents<UnstructuredLogEvent>;

/**
* Class to deserialize and decode Zstd-compressed CLP unstructured IR streams, as well as format
Expand Down

0 comments on commit 61e1e83

Please sign in to comment.