diff --git a/src/clp_ffi_js/ir/StreamReader.hpp b/src/clp_ffi_js/ir/StreamReader.hpp index c391ca13..0aae6748 100644 --- a/src/clp_ffi_js/ir/StreamReader.hpp +++ b/src/clp_ffi_js/ir/StreamReader.hpp @@ -15,6 +15,7 @@ #include #include +#include namespace clp_ffi_js::ir { // JS types used as inputs @@ -31,6 +32,9 @@ enum class StreamType : uint8_t { Unstructured, }; +template +using LogEvents = std::vector>; + /** * Mapping between an index in the filtered log events collection to an index in the unfiltered * log events collection. @@ -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 - static auto generic_filter_log_events( - FilteredLogEventsMap& filtered_log_event_map, - LogLevelFilterTsType const& log_level_filter, - std::vector> 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>(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 @@ -176,55 +146,111 @@ class StreamReader { size_t begin_idx, size_t end_idx, FilteredLogEventsMap const& filtered_log_event_map, - std::vector> const& log_events, + LogEvents 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 + static auto generic_filter_log_events( + FilteredLogEventsMap& filtered_log_event_map, + LogLevelFilterTsType const& log_level_filter, + LogEvents const& log_events + ) -> void; +}; + +template +requires requires(ToStringFunc func, LogEvent const& log_event) { + { + func(log_event) + } -> std::convertible_to; +} +auto StreamReader::generic_decode_range( + size_t begin_idx, + size_t end_idx, + FilteredLogEventsMap const& filtered_log_event_map, + LogEvents 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 +auto StreamReader::generic_filter_log_events( + FilteredLogEventsMap& filtered_log_event_map, + LogLevelFilterTsType const& log_level_filter, + LogEvents 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>(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 diff --git a/src/clp_ffi_js/ir/StructuredIrStreamReader.hpp b/src/clp_ffi_js/ir/StructuredIrStreamReader.hpp index fc0dcbe3..640fe9d0 100644 --- a/src/clp_ffi_js/ir/StructuredIrStreamReader.hpp +++ b/src/clp_ffi_js/ir/StructuredIrStreamReader.hpp @@ -19,7 +19,7 @@ namespace clp_ffi_js::ir { using schema_tree_node_id_t = std::optional; using StructuredIrDeserializer = clp::ffi::ir_stream::Deserializer; -using StructuredLogEvents = std::vector>; +using StructuredLogEvents = LogEvents; /** * Class to deserialize and decode Zstd-compressed CLP structured IR streams, as well as format diff --git a/src/clp_ffi_js/ir/StructuredIrUnitHandler.cpp b/src/clp_ffi_js/ir/StructuredIrUnitHandler.cpp index 68f992b5..cc7bfcd6 100644 --- a/src/clp_ffi_js/ir/StructuredIrUnitHandler.cpp +++ b/src/clp_ffi_js/ir/StructuredIrUnitHandler.cpp @@ -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()) { - auto const& log_level_node_value = log_level_pair.value().get_immutable_view(); - log_level = parse_log_level(log_level_node_value); - } else if (log_level_pair->is()) { - auto const& log_level_node_value - = (log_level_pair.value().get_immutable_view()); - 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()) { + auto const& log_level_str = log_level_value.get_immutable_view(); + log_level = parse_log_level(log_level_str); + } else if (log_level_value.is()) { + auto const& log_level_int = (log_level_value.get_immutable_view()); + if (log_level_int >= clp::enum_to_underlying_type(cValidLogLevelsBeginIdx) + && log_level_int < clp::enum_to_underlying_type(LogLevel::LENGTH)) { - log_level = static_cast(log_level_node_value); + log_level = static_cast(log_level_int); } } else { auto log_event_idx = m_deserialized_log_events->size(); @@ -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()) { + auto const timestamp_value = timestamp_optional_value.value(); + + if (timestamp_value.is()) { timestamp = static_cast( - timestamp_pair.value().get_immutable_view() + timestamp_value.get_immutable_view() ); } else { // TODO: Add support for parsing string-type timestamp values. diff --git a/src/clp_ffi_js/ir/UnstructuredIrStreamReader.cpp b/src/clp_ffi_js/ir/UnstructuredIrStreamReader.cpp index 36638b15..22085e02 100644 --- a/src/clp_ffi_js/ir/UnstructuredIrStreamReader.cpp +++ b/src/clp_ffi_js/ir/UnstructuredIrStreamReader.cpp @@ -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 { diff --git a/src/clp_ffi_js/ir/UnstructuredIrStreamReader.hpp b/src/clp_ffi_js/ir/UnstructuredIrStreamReader.hpp index e6fdf1ba..915724af 100644 --- a/src/clp_ffi_js/ir/UnstructuredIrStreamReader.hpp +++ b/src/clp_ffi_js/ir/UnstructuredIrStreamReader.hpp @@ -18,7 +18,7 @@ namespace clp_ffi_js::ir { using clp::ir::four_byte_encoded_variable_t; using UnstructuredIrDeserializer = clp::ir::LogEventDeserializer; -using UnstructuredLogEvents = std::vector>; +using UnstructuredLogEvents = LogEvents; /** * Class to deserialize and decode Zstd-compressed CLP unstructured IR streams, as well as format