diff --git a/MANIFEST.in b/MANIFEST.in index f3119eb6..7bf2f03f 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -2,7 +2,6 @@ recursive-include src/clp/components/core/src/clp *.h recursive-include src/clp/components/core/src/clp *.hpp recursive-include src/clp/components/core/src/clp *.inc recursive-include src/clp_ffi_py *.hpp -recursive-include src/clp_ffi_py *.inc recursive-include clp_ffi_py *.py recursive-include clp_ffi_py *.pyi recursive-include clp_ffi_py py.typed diff --git a/clp_ffi_py/ir/query_builder.py b/clp_ffi_py/ir/query_builder.py index 413b47da..ab290c54 100644 --- a/clp_ffi_py/ir/query_builder.py +++ b/clp_ffi_py/ir/query_builder.py @@ -24,13 +24,11 @@ class QueryBuilderException(Exception): class QueryBuilder: """ - This class serves as an interface for conveniently constructing Query - objects utilized in CLP IR streaming search. It provides methods for - configuring and resetting search parameters. + This class serves as an interface for conveniently constructing Query objects utilized in CLP IR + streaming search. It provides methods for configuring and resetting search parameters. For more details about the search query CLP IR stream supports, see - :class:`~clp_ffi_py.ir.native.Query` and - :class:`~clp_ffi_py.wildcard_query.WildcardQuery`. + :class:`~clp_ffi_py.ir.native.Query` and :class:`~clp_ffi_py.wildcard_query.WildcardQuery`. """ def __init__(self) -> None: @@ -60,8 +58,8 @@ def wildcard_queries(self) -> List[WildcardQuery]: def set_search_time_lower_bound(self, ts: int) -> QueryBuilder: """ - :param ts: Start of the search time range (inclusive) as a UNIX epoch - timestamp in milliseconds. + :param ts: Start of the search time range (inclusive) as a UNIX epoch timestamp in + milliseconds. :return: self. """ self._search_time_lower_bound = ts @@ -69,8 +67,8 @@ def set_search_time_lower_bound(self, ts: int) -> QueryBuilder: def set_search_time_upper_bound(self, ts: int) -> QueryBuilder: """ - :param ts: End of the search time range (inclusive) as a UNIX epoch - timestamp in milliseconds. + :param ts: End of the search time range (inclusive) as a UNIX epoch timestamp in + milliseconds. :return: self. """ self._search_time_upper_bound = ts @@ -78,8 +76,7 @@ def set_search_time_upper_bound(self, ts: int) -> QueryBuilder: def set_search_time_termination_margin(self, ts: int) -> QueryBuilder: """ - :param ts: The search time termination margin as a UNIX epoch timestamp - in milliseconds. + :param ts: The search time termination margin as a UNIX epoch timestamp in milliseconds. :return: self. """ self._search_time_termination_margin = ts @@ -92,8 +89,8 @@ def set_search_time_termination_margin(self, ts: int) -> QueryBuilder: ) def add_wildcard_query(self, wildcard_query: str, case_sensitive: bool = False) -> QueryBuilder: """ - Constructs and adds a :class:`~clp_ffi_py.wildcard_query.WildcardQuery` - to the wildcard query list. + Constructs and adds a :class:`~clp_ffi_py.wildcard_query.WildcardQuery` to the wildcard + query list. :param wildcard_query: The wildcard query string to add. :param case_sensitive: Whether to perform case-sensitive matching. @@ -106,8 +103,8 @@ def add_wildcard_query(self, wildcard_query: WildcardQuery) -> QueryBuilder: """ Adds the given wildcard query to the wildcard query list. - :param wildcard_query: The wildcard query to add. It can be any derived - class of :class:`~clp_ffi_py.wildcard_query.WildcardQuery`. + :param wildcard_query: The wildcard query to add. It can be any derived class of + :class:`~clp_ffi_py.wildcard_query.WildcardQuery`. :return: self. """ ... @@ -189,10 +186,10 @@ def reset(self) -> QueryBuilder: def build(self) -> Query: """ - :raises QueryBuilderException: If the search time range lower bound - exceeds the search time range upper bound. - :return: A :class:`~clp_ffi_py.ir.native.Query` object initialized - with the parameters set by the builder. + :raises QueryBuilderException: If the search time range lower bound exceeds the search time + range upper bound. + :return: A :class:`~clp_ffi_py.ir.native.Query` object initialized with the parameters set + by the builder. """ if self._search_time_lower_bound > self._search_time_upper_bound: raise QueryBuilderException( diff --git a/clp_ffi_py/ir/readers.py b/clp_ffi_py/ir/readers.py index d7cc4454..e02e5ebf 100644 --- a/clp_ffi_py/ir/readers.py +++ b/clp_ffi_py/ir/readers.py @@ -12,17 +12,16 @@ class ClpIrStreamReader(Iterator[LogEvent]): """ - This class represents a stream reader used to read/decode encoded log events - from a CLP IR stream. It also provides method(s) to instantiate a log event - generator with a customized search query. + This class represents a stream reader used to read/decode encoded log events from a CLP IR + stream. It also provides method(s) to instantiate a log event generator with a customized search + query. :param istream: Input stream that contains encoded CLP IR. :param decoder_buffer_size: Initial size of the decoder buffer. - :param enable_compression: A flag indicating whether the istream is - compressed using `zstd`. - :param allow_incomplete_stream: If set to `True`, an incomplete CLP IR - stream is not treated as an error. Instead, encountering such a stream - is seen as reaching its end without raising any exceptions. + :param enable_compression: A flag indicating whether the istream is compressed using `zstd`. + :param allow_incomplete_stream: If set to `True`, an incomplete CLP IR stream is not treated as + an error. Instead, encountering such a stream is seen as reaching its end without raising + any exceptions. """ DEFAULT_DECODER_BUFFER_SIZE: int = 65536 @@ -52,8 +51,7 @@ def read_next_log_event(self) -> Optional[LogEvent]: - Next unread log event represented as an instance of LogEvent. - None if the end of IR stream is reached. :raise Exception: - If :meth:`~clp_ffi_py.ir.native.Decoder.decode_next_log_event` - fails. + If :meth:`~clp_ffi_py.ir.native.Decoder.decode_next_log_event` fails. """ return Decoder.decode_next_log_event( self._decoder_buffer, allow_incomplete_stream=self._allow_incomplete_stream @@ -61,10 +59,9 @@ def read_next_log_event(self) -> Optional[LogEvent]: def read_preamble(self) -> None: """ - Try to decode the preamble and set `metadata`. If `metadata` has been - set already, it will instantly return. It is separated from `__init__` - so that the input stream does not need to be readable on a reader's - construction, but until the user starts to iterate logs. + Try to decode the preamble and set `metadata`. If `metadata` has been set already, it will + instantly return. It is separated from `__init__` so that the input stream does not need to + be readable on a reader's construction, but until the user starts to iterate logs. :raise Exception: If :meth:`~clp_ffi_py.ir.native.Decoder.decode_preamble` fails. @@ -85,10 +82,10 @@ def search(self, query: Query) -> Generator[LogEvent, None, None]: """ Searches and yields log events that match a specific search query. - :param query: The input query object used to match log events. Check the - document of :class:`~clp_ffi_py.ir.Query` for more details. - :yield: The next unread encoded log event that matches the given search - query from the IR stream. + :param query: The input query object used to match log events. Check the document of + :class:`~clp_ffi_py.ir.Query` for more details. + :yield: The next unread encoded log event that matches the given search query from the IR + stream. """ if False is self.has_metadata(): self.read_preamble() diff --git a/clp_ffi_py/utils.py b/clp_ffi_py/utils.py index 57cb87f9..1c1711a3 100644 --- a/clp_ffi_py/utils.py +++ b/clp_ffi_py/utils.py @@ -6,12 +6,11 @@ def get_formatted_timestamp(timestamp: int, timezone: Optional[tzinfo]) -> str: """ - Gets the formatted timestamp string from the provided timestamp with the - provided timezone using isoformat. + Gets the formatted timestamp string from the provided timestamp with the provided timezone using + isoformat. :param timestamp: Timestamp to format. - :param timezone: Timezone of timestamp parameter. If None is given, UTC is - used by default. + :param timezone: Timezone of timestamp parameter. If None is given, UTC is used by default. :return: String of formatted timestamp. """ if timezone is None: diff --git a/clp_ffi_py/wildcard_query.py b/clp_ffi_py/wildcard_query.py index 64c34772..84fa69c1 100644 --- a/clp_ffi_py/wildcard_query.py +++ b/clp_ffi_py/wildcard_query.py @@ -5,17 +5,16 @@ class WildcardQuery: """ - An abstract class defining a wildcard query. Users should instantiate a - wildcard query through :class:`SubstringWildcardQuery` or - :class:`FullStringWildcardQuery`. + An abstract class defining a wildcard query. Users should instantiate a wildcard query through + :class:`SubstringWildcardQuery` or :class:`FullStringWildcardQuery`. A wildcard string may contain the following types of wildcards: 1. '*': match 0 or more characters. 2. '?': match any single character. - Each wildcard can be escaped using a preceding '\\\\' (a single backslash). - Other characters that are escaped are treated as normal characters. + Each wildcard can be escaped using a preceding '\\\\' (a single backslash). Other characters + that are escaped are treated as normal characters. """ @deprecated( @@ -61,12 +60,11 @@ def case_sensitive(self) -> bool: class SubstringWildcardQuery(WildcardQuery): """ - A wildcard query that can match a substring in a log event's message, in - contrast with :class:`FullStringWildcardQuery` where the query needs to - match the entire message. + A wildcard query that can match a substring in a log event's message, in contrast with + :class:`FullStringWildcardQuery` where the query needs to match the entire message. - This class is derived from :class:`WildcardQuery` by adding both a prefix - and a postfix wildcard ("*") to the input wildcard string. + This class is derived from :class:`WildcardQuery` by adding both a prefix and a postfix wildcard + ("*") to the input wildcard string. """ def __init__(self, substring_wildcard_query: str, case_sensitive: bool = False): @@ -84,15 +82,14 @@ def __init__(self, substring_wildcard_query: str, case_sensitive: bool = False): class FullStringWildcardQuery(WildcardQuery): """ - A wildcard query where the query must match the entirety of the log event's - message, in contrast with :class:`SubstringWildcardQuery` where the query - only needs to match a substring. + A wildcard query where the query must match the entirety of the log event's message, in contrast + with :class:`SubstringWildcardQuery` where the query only needs to match a substring. - This class is derived from :class:`WildcardQuery` as a more explicit - interface for full-string matches. + This class is derived from :class:`WildcardQuery` as a more explicit interface for full-string + matches. - Users can create a match that's anchored to only one end of the message by - adding a prefix OR postfix wildcard ("*"). + Users can create a match that's anchored to only one end of the message by adding a prefix OR + postfix wildcard ("*"). """ def __init__(self, full_string_wildcard_query: str, case_sensitive: bool = False): diff --git a/pyproject.toml b/pyproject.toml index 79ee4ce0..d38bdbdd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -75,8 +75,8 @@ archs = ["AMD64"] make-summary-multi-line = true pre-summary-newline = true recursive = true -wrap-summaries = 80 -wrap-descriptions = 80 +wrap-summaries = 100 +wrap-descriptions = 100 [tool.mypy] explicit_package_bases = true diff --git a/src/clp_ffi_py/ExceptionFFI.hpp b/src/clp_ffi_py/ExceptionFFI.hpp index 03a6a642..ab00ca5b 100644 --- a/src/clp_ffi_py/ExceptionFFI.hpp +++ b/src/clp_ffi_py/ExceptionFFI.hpp @@ -7,9 +7,8 @@ namespace clp_ffi_py { /** - * A class that represents a traceable exception during the native code - * execution. Note: for exceptions of CPython execution, please use CPython - * interface to set the exception instead. + * A class that represents a traceable exception during the native code execution. Note: for + * exceptions of CPython execution, please use CPython interface to set the exception instead. */ class ExceptionFFI : public clp::TraceableException { public: diff --git a/src/clp_ffi_py/PyObjectCast.hpp b/src/clp_ffi_py/PyObjectCast.hpp index 088d512d..731924f9 100644 --- a/src/clp_ffi_py/PyObjectCast.hpp +++ b/src/clp_ffi_py/PyObjectCast.hpp @@ -6,11 +6,10 @@ #include namespace clp_ffi_py { - /** * Casts a given function pointer to a PyCFunction. - * The main purpose of this function is to silence clang-tidy checks on using - * `reinterpret_cast`. It does not perform any further function type checking. + * The main purpose of this function is to silence clang-tidy checks on using `reinterpret_cast`. It + * does not perform any further function type checking. * @tparam Src The source function pointer type. * @param src The source function pointer. * @return PyCFunction using reinterpret_cast. @@ -23,9 +22,9 @@ auto py_c_function_cast(Src src) noexcept -> PyCFunction { } /** - * Casts a given function pointer to a `getbufferproc` CPython function. - * The main purpose of this function is to silence clang-tidy checks on using - * `reinterpret_cast`. It does not perform any further function type checking. + * Casts a given function pointer to a `getbufferproc` CPython function. The main purpose of this + * function is to silence clang-tidy checks on using `reinterpret_cast`. It does not perform any + * further function type checking. * @tparam Src The source function pointer type. * @param src The source function pointer. * @return `getbufferproc` using reinterpret_cast. @@ -38,9 +37,9 @@ auto py_getbufferproc_cast(Src src) noexcept -> getbufferproc { } /** - * Casts a given function pointer to a `releasebufferproc` CPython function. - * The main purpose of this function is to silence clang-tidy checks on using - * `reinterpret_cast`. It does not perform any further function type checking. + * Casts a given function pointer to a `releasebufferproc` CPython function. The main purpose of + * this function is to silence clang-tidy checks on using `reinterpret_cast`. It does not perform + * any further function type checking. * @tparam Src The source function pointer type. * @param src The source function pointer. * @return `releasebufferproc` using reinterpret_cast. @@ -53,8 +52,8 @@ auto py_releasebufferproc_cast(Src src) noexcept -> releasebufferproc { } /** - * This template struct is used as a compile-time flag that indicates whether - * type T is a PyObject or not. By default, `cValue` is set to false. + * This template struct is used as a compile-time flag that indicates whether type T is a PyObject + * or not. By default, `cValue` is set to false. * @tparam T */ template @@ -63,18 +62,16 @@ struct is_python_object { }; /** - * This template const expression is a wrapper of underlying `cValue` stored in - * `is_python_object`, which is used to determine whether a type T is a valid - * Python object type. + * This template const expression is a wrapper of underlying `cValue` stored in `is_python_object`, + * which is used to determine whether a type T is a valid Python object type. * @tparam T */ template // NOLINTNEXTLINE(readability-identifier-naming) constexpr bool is_python_object_v{is_python_object::cValue}; /** - * The macro to create a specialization of is_python_object for a given type T. - * Only types that are marked with this macro will be considered as a valid - * Python object type. + * The macro to create a specialization of is_python_object for a given type T. Only types that are + * marked with this macro will be considered as a valid Python object type. */ // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define CLP_FFI_PY_MARK_AS_PYOBJECT(T) \ @@ -85,12 +82,12 @@ constexpr bool is_python_object_v{is_python_object::cValue}; /** * Casts a given Src pointer to a Dst pointer. It should behave as followed: - * 1. If Src and Dst are the same type, return `src` if their type is a valid - * Python object type, or they are both PyObject. - * 2. If Dst is PyObject, the cast is valid if Src is a PyObject. A pointer, - * Python*, should be returned. - * 3. If Src is PyObject, the cast is valid if Dst is a valid Python object - * type. A pointer, Dst*, should be returned. + * 1. If Src and Dst are the same type, return `src` if their type is a valid Python object type, or + * they are both PyObject. + * 2. If Dst is PyObject, the cast is valid if Src is a PyObject. A pointer, Python*, should be + * returned. + * 3. If Src is PyObject, the cast is valid if Dst is a valid Python object type. A pointer, Dst*, + * should be returned. * 4. Any other cases are considered as invalid cast. * @tparam Dst The destination type. Must be given explicitly. * @tparam Src The source type. Can be given implicitly. @@ -129,4 +126,5 @@ CLP_FFI_PY_MARK_AS_PYOBJECT(ir::native::PyMetadata); CLP_FFI_PY_MARK_AS_PYOBJECT(ir::native::PyQuery); CLP_FFI_PY_MARK_AS_PYOBJECT(PyTypeObject); } // namespace clp_ffi_py -#endif + +#endif // CLP_FFI_PY_PY_OBJECT_CAST_HPP diff --git a/src/clp_ffi_py/PyObjectUtils.hpp b/src/clp_ffi_py/PyObjectUtils.hpp index f41f560e..914e24ad 100644 --- a/src/clp_ffi_py/PyObjectUtils.hpp +++ b/src/clp_ffi_py/PyObjectUtils.hpp @@ -7,8 +7,8 @@ namespace clp_ffi_py { /** - * A specialized deleter for PyObjectPtr which decrements the pointed PyObject - * reference count when it is destroyed. + * A specialized deleter for PyObjectPtr which decrements the pointed PyObject reference count when + * it is destroyed. * @tparam PyObjectType */ template @@ -19,8 +19,7 @@ class PyObjectDeleter { }; /** - * An empty deleter that has an empty implementation to ensure object trivial - * destruction. + * An empty deleter that has an empty implementation to ensure object trivial destruction. * @tparam PyObjectType */ template @@ -30,25 +29,24 @@ class PyObjectTrivialDeleter { }; /** - * A type of smart pointer that maintains a reference to a Python object for the - * duration of its lifetime. + * A type of smart pointer that maintains a reference to a Python object for the duration of its + * lifetime. * @tparam PyObjectType */ template using PyObjectPtr = std::unique_ptr>; /** - * A smart pointer to be used for raw Python object pointers that have static - * storage duration. It holds a reference of the underlying Python object. - * Compared to PyObjectPtr, when destructed, this smart pointer does not - * decrease the reference count of the contained Python object. Since this - * pointer has static storage duration, it's possible that the Python - * interpreter exits before this pointer's destructor is called; attempting to - * decrement the reference count (maintained by the interpreter) in this - * situation would lead to undefined behaviour. + * A smart pointer to be used for raw Python object pointers that have static storage duration. It + * holds a reference of the underlying Python object. Compared to PyObjectPtr, when destructed, this + * smart pointer does not decrease the reference count of the contained Python object. Since this + * pointer has static storage duration, it's possible that the Python interpreter exits before this + * pointer's destructor is called; attempting to decrement the reference count (maintained by the + * interpreter) in this situation would lead to undefined behaviour. * @tparam PyObjectType */ template using PyObjectStaticPtr = std::unique_ptr>; } // namespace clp_ffi_py -#endif // CLP_FFI_PY_PY_OBJECT_PTR_HPP + +#endif // CLP_FFI_PY_PY_OBJECT_UTILS_HPP diff --git a/src/clp_ffi_py/Py_utils.hpp b/src/clp_ffi_py/Py_utils.hpp index f9bb4a62..28fc3798 100644 --- a/src/clp_ffi_py/Py_utils.hpp +++ b/src/clp_ffi_py/Py_utils.hpp @@ -7,8 +7,8 @@ namespace clp_ffi_py { /** - * Initializes CPython interface to Python level utility functions implemented - * in submodule `clp_ffi_py.utils`. + * Initializes CPython interface to Python level utility functions implemented in submodule + * `clp_ffi_py.utils`. * @return true on success. * @return false on failure with the relevant Python exception and error set. */ @@ -18,20 +18,19 @@ auto py_utils_init() -> bool; * CPython wrapper of clp_ffi_py.utils.get_formatted_timestamp. * @param timestamp * @param tzinfo Python tzinfo object that specifies timezone information. - * @return a new reference of a PyObject string that stores the formatted - * timestamp. + * @return a new reference of a PyObject string that stores the formatted timestamp. * @return nullptr on failure with the relevant Python exception and error set. */ auto py_utils_get_formatted_timestamp(clp::ir::epoch_time_ms_t timestamp, PyObject* timezone) -> PyObject*; /** - * CPython wrapper of clp_ffi_py.utils.get_timezone_from_timezone_id + * CPython wrapper of clp_ffi_py.utils.get_timezone_from_timezone_id. * @param timezone_id - * @return a new reference of a Python tzinfo object that matches the input - * timezone id. + * @return a new reference of a Python tzinfo object that matches the input timezone id. * @return nullptr on failure with the relevant Python exception and error set. */ auto py_utils_get_timezone_from_timezone_id(std::string const& timezone_id) -> PyObject*; } // namespace clp_ffi_py + #endif // CLP_FFI_PY_PY_UTILS_HPP diff --git a/src/clp_ffi_py/ir/native/LogEvent.hpp b/src/clp_ffi_py/ir/native/LogEvent.hpp index 326973b8..ad82768b 100644 --- a/src/clp_ffi_py/ir/native/LogEvent.hpp +++ b/src/clp_ffi_py/ir/native/LogEvent.hpp @@ -1,5 +1,5 @@ -#ifndef CLP_FFI_PY_LOG_EVENT_HPP -#define CLP_FFI_PY_LOG_EVENT_HPP +#ifndef CLP_FFI_PY_IR_NATIVE_LOG_EVENT_HPP +#define CLP_FFI_PY_IR_NATIVE_LOG_EVENT_HPP #include @@ -7,16 +7,15 @@ namespace clp_ffi_py::ir::native { /** - * A class that represents a decoded IR log event. Contains ways to access (get - * or set) the log message, the timestamp, and the log event index. + * A class that represents a decoded IR log event. Contains ways to access (get or set) the log + * message, the timestamp, and the log event index. */ class LogEvent { public: LogEvent() = delete; /** - * Constructs a new log event and leaves the formatted timestamp empty by - * default. + * Constructs a new log event and leaves the formatted timestamp empty by default. * @param log_message * @param timestamp * @param index @@ -75,4 +74,4 @@ class LogEvent { }; } // namespace clp_ffi_py::ir::native -#endif // CLP_FFI_PY_LOG_EVENT_HPP +#endif // CLP_FFI_PY_IR_NATIVE_LOG_EVENT_HPP diff --git a/src/clp_ffi_py/ir/native/Metadata.cpp b/src/clp_ffi_py/ir/native/Metadata.cpp index f2a867ef..2346b7ee 100644 --- a/src/clp_ffi_py/ir/native/Metadata.cpp +++ b/src/clp_ffi_py/ir/native/Metadata.cpp @@ -8,8 +8,8 @@ namespace clp_ffi_py::ir::native { namespace { /** - * Validates whether the JSON object contains the given key and has a string - * data associated to this particular key. + * Validates whether the JSON object contains the given key and has a string data associated to this + * particular key. * @param json_data JSON object to be validated. * @param key The key to access the data field. * @return true if the data is valid. diff --git a/src/clp_ffi_py/ir/native/Metadata.hpp b/src/clp_ffi_py/ir/native/Metadata.hpp index 0eecadaf..33524281 100644 --- a/src/clp_ffi_py/ir/native/Metadata.hpp +++ b/src/clp_ffi_py/ir/native/Metadata.hpp @@ -1,5 +1,5 @@ -#ifndef CLP_FFI_PY_METADATA_HPP -#define CLP_FFI_PY_METADATA_HPP +#ifndef CLP_FFI_PY_IR_NATIVE_METADATA_HPP +#define CLP_FFI_PY_IR_NATIVE_METADATA_HPP #include @@ -8,15 +8,15 @@ namespace clp_ffi_py::ir::native { /** - * A class that represents a decoded IR preamble. Contains ways to access (get) - * metadata such as the timestamp format. After construction, the metadata is - * readonly. */ + * A class that represents a decoded IR preamble. Contains ways to access (get) metadata such as the + * timestamp format. After construction, the metadata is readonly. + */ class Metadata { public: /** - * Constructs a new Metadata object by reading values from a JSON object - * decoded from the preamble. This constructor will validate the JSON data - * and throw exceptions when failing to extract required values. + * Constructs a new Metadata object by reading values from a JSON object decoded from the + * preamble. This constructor will validate the JSON data and throw exceptions when failing to + * extract required values. * @param metadata JSON data that contains the metadata. * @param is_four_byte_encoding */ @@ -24,14 +24,12 @@ class Metadata { /** * Constructs a new Metadata object from the provided fields. Currently, - * `m_is_four_byte_encoding` is set to true by default since it is the only - * format supported. - * @param ref_timestamp The reference timestamp used to calculate the - * timestamp of the first log message in the IR stream. - * @param timestamp_format Timestamp format to use when generating the logs - * with a reader. - * @param timezone Timezone in TZID format to use when generating the - * timestamp from Unix epoch time. + * `m_is_four_byte_encoding` is set to true by default since it is the only format supported. + * @param ref_timestamp The reference timestamp used to calculate the timestamp of the first log + * message in the IR stream. + * @param timestamp_format Timestamp format to use when generating the logs with a reader. + * @param timezone Timezone in TZID format to use when generating the timestamp from Unix epoch + * time. */ explicit Metadata( clp::ir::epoch_time_ms_t ref_timestamp, @@ -64,4 +62,5 @@ class Metadata { std::string m_timezone_id; }; } // namespace clp_ffi_py::ir::native -#endif // CLP_FFI_PY_METADATA_HPP + +#endif // CLP_FFI_PY_IR_NATIVE_METADATA_HPP diff --git a/src/clp_ffi_py/ir/native/PyDecoder.hpp b/src/clp_ffi_py/ir/native/PyDecoder.hpp index 81a5f1cc..4080dbd7 100644 --- a/src/clp_ffi_py/ir/native/PyDecoder.hpp +++ b/src/clp_ffi_py/ir/native/PyDecoder.hpp @@ -1,5 +1,5 @@ -#ifndef CLP_FFI_PY_PYDECODER_HPP -#define CLP_FFI_PY_PYDECODER_HPP +#ifndef CLP_FFI_PY_IR_NATIVE_PYDECODER_HPP +#define CLP_FFI_PY_IR_NATIVE_PYDECODER_HPP #include // Must always be included before any other header files @@ -12,13 +12,12 @@ namespace clp_ffi_py::ir::native { class PyDecoder { public: /** - * Creates and initializes PyDecoder as a Python type, and then incorporates - * this type as a Python object into py_module. - * @param py_module This is the Python module where the initialized - * PyDecoder will be incorporated. + * Creates and initializes PyDecoder as a Python type, and then incorporates this type as a + * Python object into py_module. + * @param py_module This is the Python module where the initialized PyDecoder will be + * incorporated. * @return true on success. - * @return false on failure with the relevant Python exception and error - * set. + * @return false on failure with the relevant Python exception and error set. */ [[nodiscard]] static auto module_level_init(PyObject* py_module) -> bool; @@ -29,4 +28,4 @@ class PyDecoder { }; } // namespace clp_ffi_py::ir::native -#endif +#endif // CLP_FFI_PY_IR_NATIVE_PYDECODER_HPP diff --git a/src/clp_ffi_py/ir/native/PyDecoderBuffer.cpp b/src/clp_ffi_py/ir/native/PyDecoderBuffer.cpp index a2ca646d..b3e487be 100644 --- a/src/clp_ffi_py/ir/native/PyDecoderBuffer.cpp +++ b/src/clp_ffi_py/ir/native/PyDecoderBuffer.cpp @@ -19,8 +19,8 @@ extern "C" { * Callback of PyDecoderBuffer `__init__` method: * __init__(self, input_stream: IO[bytes], initial_buffer_capacity: int = 4096) * Keyword argument parsing is supported. - * Assumes `self` is uninitialized and will allocate the underlying memory. If - * `self` is already initialized this will result in memory leaks. + * Assumes `self` is uninitialized and will allocate the underlying memory. If `self` is already + * initialized this will result in memory leaks. * @param self * @param args * @param keywords @@ -36,9 +36,8 @@ auto PyDecoderBuffer_init(PyDecoderBuffer* self, PyObject* args, PyObject* keywo nullptr }; - // If the argument parsing fails, `self` will be deallocated. We must reset - // all pointers to nullptr in advance, otherwise the deallocator might - // trigger a segmentation fault. + // If the argument parsing fails, `self` will be deallocated. We must reset all pointers to + // nullptr in advance, otherwise the deallocator might trigger a segmentation fault. self->default_init(); PyObject* input_stream{nullptr}; @@ -101,8 +100,7 @@ auto PyDecoderBuffer_getbuffer(PyDecoderBuffer* self, Py_buffer* view, int flags /** * Callback of Python buffer protocol's `releasebuffer` operation. - * This callback doesn't do anything, but it is set intentionally to avoid - * unexpected behaviour. + * This callback doesn't do anything, but it is set intentionally to avoid unexpected behaviour. * @param self (unused). * @param view (unused). */ @@ -296,8 +294,8 @@ auto PyDecoderBuffer::metadata_init(PyMetadata* metadata) -> bool { } auto PyDecoderBuffer::py_getbuffer(Py_buffer* view, int flags) -> int { - // Don't need to set the exception message during the failure. - // The Python level caller will set the exception and thus overwrite it. + // Don't need to set the exception message during the failure. The Python level caller will set + // the exception and thus overwrite it. if (false == is_py_buffer_protocol_enabled()) { return -1; } diff --git a/src/clp_ffi_py/ir/native/PyDecoderBuffer.hpp b/src/clp_ffi_py/ir/native/PyDecoderBuffer.hpp index cb8b1e6f..2ad4a6ab 100644 --- a/src/clp_ffi_py/ir/native/PyDecoderBuffer.hpp +++ b/src/clp_ffi_py/ir/native/PyDecoderBuffer.hpp @@ -1,5 +1,5 @@ -#ifndef CLP_FFI_PY_PYDECODERBUFFER_HPP -#define CLP_FFI_PY_PYDECODERBUFFER_HPP +#ifndef CLP_FFI_PY_IR_NATIVE_PYDECODERBUFFER_HPP +#define CLP_FFI_PY_IR_NATIVE_PYDECODERBUFFER_HPP #include // Must always be included before any other header files @@ -12,31 +12,28 @@ namespace clp_ffi_py::ir::native { /** - * This Python class is designed to buffer encoded CLP IR bytes that are read - * from an input stream. This object serves a dual purpose: - * - It enables CLP IR decoding methods to access the buffered bytes for the - * purpose of decoding log events. - * - It adheres to the Python buffer protocol, allowing for direct reading from - * an `IO[bytes]`-like input stream. - * - * This class encompasses all essential attributes to hold the buffered bytes - * and monitor the state of the buffer. It's meant to be utilized across various - * CLP IR decoding method calls when decoding from the same IR stream. + * This Python class is designed to buffer encoded CLP IR bytes that are read from an input stream. + * This object serves a dual purpose: + * - It enables CLP IR decoding methods to access the buffered bytes for the purpose of decoding log + * events. + * - It adheres to the Python buffer protocol, allowing for direct reading from an `IO[bytes]`-like + * input stream. + * This class encompasses all essential attributes to hold the buffered bytes and monitor the state + * of the buffer. It's meant to be utilized across various CLP IR decoding method calls when + * decoding from the same IR stream. */ class PyDecoderBuffer { public: static constexpr Py_ssize_t cDefaultInitialCapacity{4096}; /** - * Since the memory allocation of PyDecoderBuffer is handled by CPython's - * allocator, cpp constructors will not be explicitly called. This function - * serves as the default constructor to initialize the underlying input IR - * stream and read buffer. Other data members are assumed to be - * zero-initialized by `default-init` method. It has to be manually called - * whenever creating a new PyDecoderBuffer object through CPython APIs. + * Since the memory allocation of PyDecoderBuffer is handled by CPython's allocator, cpp + * constructors will not be explicitly called. This function serves as the default constructor + * to initialize the underlying input IR stream and read buffer. Other data members are assumed + * to be zero-initialized by `default-init` method. It has to be manually called whenever + * creating a new PyDecoderBuffer object through CPython APIs. * @return true on success. - * @return false on failure with the relevant Python exception and error - * set. + * @return false on failure with the relevant Python exception and error set. */ [[nodiscard]] auto init( PyObject* input_stream, @@ -44,8 +41,8 @@ class PyDecoderBuffer { ) -> bool; /** - * Zero-initializes all the data members in PyDecoderBuffer. Should be - * called once the object is allocated. + * Zero-initializes all the data members in PyDecoderBuffer. Should be called once the object is + * allocated. */ auto default_init() -> void { m_read_buffer_mem_owner = nullptr; @@ -59,8 +56,8 @@ class PyDecoderBuffer { } /** - * Releases the memory allocated for the underlying metadata field and the - * reference held for the Python object(s). + * Releases the memory allocated for the underlying metadata field and the reference held for + * the Python object(s). */ auto clean() -> void { Py_XDECREF(m_input_ir_stream); @@ -69,20 +66,17 @@ class PyDecoderBuffer { } /** - * Commits the bytes consumed in the read buffer by incrementing the - * underlying cursor position. + * Commits the bytes consumed in the read buffer by incrementing the underlying cursor position. * @param num_bytes_consumed Total number of bytes consumed. * @return true on success. - * @return false on failure with the relevant Python exception and error - * set. + * @return false on failure with the relevant Python exception and error set. */ auto commit_read_buffer_consumption(Py_ssize_t num_bytes_consumed) -> bool; [[nodiscard]] auto get_num_decoded_message() const -> size_t { return m_num_decoded_message; } /** - * Increments the number of decoded message counter, and returns the value - * before increment. + * Increments the number of decoded message counter, and returns the value before increment. */ [[maybe_unused]] auto get_and_increment_decoded_message_count() -> size_t { auto current_num_decoded_message{m_num_decoded_message}; @@ -121,16 +115,16 @@ class PyDecoderBuffer { * Initializes the metadata and the initial reference timestamp. * @param metadata Input metadata. * @return true on success. - * @return false if the metadata has already been initialized. The relevant - * Python exception and error will be set. + * @return false if the metadata has already been initialized. The relevant Python exception and + * error will be set. */ [[nodiscard]] auto metadata_init(PyMetadata* metadata) -> bool; [[nodiscard]] auto get_metadata() const -> PyMetadata* { return m_metadata; } /** - * Handles the Python buffer protocol's `getbuffer` operation. - * This function should fail unless the buffer protocol is enabled. + * Handles the Python buffer protocol's `getbuffer` operation. This function should fail unless + * the buffer protocol is enabled. * @param view Python Buffer view. * @param flags Python Buffer flags. * @return 0 on success. @@ -146,63 +140,55 @@ class PyDecoderBuffer { } /** - * Attempts to populate the decoder buffer. When this function is called, it - * is expected to have more bytes to read from the IR stream. + * Attempts to populate the decoder buffer. When this function is called, it is expected to have + * more bytes to read from the IR stream. * @return true on success. - * @return false on failure. The Python exception and error will be properly - * set if the error + * @return false on failure. The Python exception and error will be properly set if the error. */ [[nodiscard]] auto try_read() -> bool; /** - * Tests the functionality of the DecoderBuffer by sequentially reading - * through the input stream with randomly sized reads. It will grow the read - * buffer when necessary until the the entire input stream is consumed. - * All the read bytes will be returned as a Python bytearray. + * Tests the functionality of the DecoderBuffer by sequentially reading through the input stream + * with randomly sized reads. It will grow the read buffer when necessary until the the entire + * input stream is consumed. All the read bytes will be returned as a Python bytearray. * @param seed Random seed passing from the tester. - * @return Python bytearray that contains all the read bytes read from the - * input stream in sequence. - * @return nullptr on failure with the relevant Python exception and error - * set. + * @return Python bytearray that contains all the read bytes read from the input stream in + * sequence. + * @return nullptr on failure with the relevant Python exception and error set. */ [[nodiscard]] auto test_streaming(uint32_t seed) -> PyObject*; /** - * Gets the PyTypeObject that represents PyDecoderBuffer's Python type. This - * type is dynamically created and initialized during the execution of - * `PyDecoderBuffer::module_level_init`. + * Gets the PyTypeObject that represents PyDecoderBuffer's Python type. This type is dynamically + * created and initialized during the execution of `PyDecoderBuffer::module_level_init`. * @return Python type object associated with PyDecoderBuffer. */ [[nodiscard]] static auto get_py_type() -> PyTypeObject*; /** - * Gets a PyObject that represents the incomplete stream error as a Python - * exception. + * Gets a PyObject that represents the incomplete stream error as a Python exception. */ [[nodiscard]] static auto get_py_incomplete_stream_error() -> PyObject*; /** - * Creates and initializes PyDecoderBuffer as a Python type, and then - * incorporates this type as a Python object into the py_module module. - * @param py_module This is the Python module where the initialized - * PyDecoderBuffer will be incorporated. + * Creates and initializes PyDecoderBuffer as a Python type, and then incorporates this type as + * a Python object into the py_module module. + * @param py_module This is the Python module where the initialized PyDecoderBuffer will be + * incorporated. * @return true on success. - * @return false on failure with the relevant Python exception and error - * set. + * @return false on failure with the relevant Python exception and error set. */ [[nodiscard]] static auto module_level_init(PyObject* py_module) -> bool; private: /** - * Cleans the consumed bytes by shifting the unconsumed bytes to the - * beginning of the buffer, and fills the read buffer by reading from the - * input IR stream. If more than half of the bytes are unconsumed in the - * read buffer, the buffer will be doubled before reading. - * @param num_bytes_read Number of bytes read from the input IR stream to - * populate the read buffer. + * Cleans the consumed bytes by shifting the unconsumed bytes to the beginning of the buffer, + * and fills the read buffer by reading from the input IR stream. If more than half of the bytes + * are unconsumed in the read buffer, the buffer will be doubled before reading. + * @param num_bytes_read Number of bytes read from the input IR stream to populate the read + * buffer. * @return true on success. - * @return false on failure with the relevant Python exception and error - * set. + * @return false on failure with the relevant Python exception and error set. */ [[nodiscard]] auto populate_read_buffer(Py_ssize_t& num_bytes_read) -> bool; @@ -231,4 +217,5 @@ class PyDecoderBuffer { static PyObjectStaticPtr m_py_incomplete_stream_error; }; } // namespace clp_ffi_py::ir::native -#endif + +#endif // CLP_FFI_PY_IR_NATIVE_PYDECODERBUFFER_HPP diff --git a/src/clp_ffi_py/ir/native/PyFourByteEncoder.hpp b/src/clp_ffi_py/ir/native/PyFourByteEncoder.hpp index 4b848631..d65b853d 100644 --- a/src/clp_ffi_py/ir/native/PyFourByteEncoder.hpp +++ b/src/clp_ffi_py/ir/native/PyFourByteEncoder.hpp @@ -1,5 +1,5 @@ -#ifndef CLP_FFI_PY_PYFOURBYTEENCODER_HPP -#define CLP_FFI_PY_PYFOURBYTEENCODER_HPP +#ifndef CLP_FFI_PY_IR_NATIVE_PYFOURBYTEENCODER_HPP +#define CLP_FFI_PY_IR_NATIVE_PYFOURBYTEENCODER_HPP #include // Must always be included before any other header files @@ -7,19 +7,17 @@ namespace clp_ffi_py::ir::native { /** - * This class provides a Python-level namespace for CLP 4-byte IR encoding - * methods. + * This class provides a Python-level namespace for CLP 4-byte IR encoding methods. */ class PyFourByteEncoder { public: /** - * Creates and initializes PyFourByteEncoder as a Python type, and then - * incorporates this type as a Python object into py_module. - * @param py_module This is the Python module where the initialized - * PyFourByteEncoder will be incorporated. + * Creates and initializes PyFourByteEncoder as a Python type, and then incorporates this type + * as a Python object into py_module. + * @param py_module This is the Python module where the initialized PyFourByteEncoder will be + * incorporated. * @return true on success. - * @return false on failure with the relevant Python exception and error - * set. + * @return false on failure with the relevant Python exception and error set. */ [[nodiscard]] static auto module_level_init(PyObject* py_module) -> bool; @@ -29,4 +27,5 @@ class PyFourByteEncoder { static PyObjectStaticPtr m_py_type; }; } // namespace clp_ffi_py::ir::native -#endif + +#endif // CLP_FFI_PY_IR_NATIVE_PYFOURBYTEENCODER_HPP diff --git a/src/clp_ffi_py/ir/native/PyLogEvent.cpp b/src/clp_ffi_py/ir/native/PyLogEvent.cpp index 5a22f891..b28a9c2e 100644 --- a/src/clp_ffi_py/ir/native/PyLogEvent.cpp +++ b/src/clp_ffi_py/ir/native/PyLogEvent.cpp @@ -16,8 +16,8 @@ extern "C" { * Callback of PyLogEvent `__init__` method: * __init__(log_message, timestamp, index=0, metadata=None) * Keyword argument parsing is supported. - * Assumes `self` is uninitialized and will allocate the underlying memory. If - * `self` is already initialized this will result in memory leaks. + * Assumes `self` is uninitialized and will allocate the underlying memory. If `self` is already + * initialized this will result in memory leaks. * @param self * @param args * @param keywords @@ -37,9 +37,8 @@ auto PyLogEvent_init(PyLogEvent* self, PyObject* args, PyObject* keywords) -> in nullptr }; - // If the argument parsing fails, `self` will be deallocated. We must reset - // all pointers to nullptr in advance, otherwise the deallocator might - // trigger segmentation fault + // If the argument parsing fails, `self` will be deallocated. We must reset all pointers to + // nullptr in advance, otherwise the deallocator might trigger segmentation fault. self->default_init(); char const* log_message{nullptr}; @@ -92,8 +91,8 @@ auto PyLogEvent_dealloc(PyLogEvent* self) -> void { } /** - * Constant keys used to serialize/deserialize PyLogEvent objects through - * __getstate__ and __setstate__ methods. + * Constant keys used to serialize/deserialize PyLogEvent objects through `__getstate__` and + * `__setstate__` methods. */ constexpr char const* const cStateLogMessage = "log_message"; constexpr char const* const cStateTimestamp = "timestamp"; @@ -165,8 +164,8 @@ PyDoc_STRVAR( /** * Callback of PyLogEvent `__setstate__` method. * Note: should only be used by the Python pickle module. - * Assumes `self` is uninitialized and will allocate the underlying memory. If - * `self` is already initialized this will result in memory leaks. + * Assumes `self` is uninitialized and will allocate the underlying memory. If `self` is already + * initialized this will result in memory leaks. * @param self * @param state Python dictionary that contains the serialized object info. * @return Py_None on success diff --git a/src/clp_ffi_py/ir/native/PyLogEvent.hpp b/src/clp_ffi_py/ir/native/PyLogEvent.hpp index 08cd761e..aa18c524 100644 --- a/src/clp_ffi_py/ir/native/PyLogEvent.hpp +++ b/src/clp_ffi_py/ir/native/PyLogEvent.hpp @@ -1,5 +1,5 @@ -#ifndef CLP_FFI_PY_PYLOGEVENT_HPP -#define CLP_FFI_PY_PYLOGEVENT_HPP +#ifndef CLP_FFI_PY_IR_NATIVE_PYLOGEVENT_HPP +#define CLP_FFI_PY_IR_NATIVE_PYLOGEVENT_HPP #include // Must always be included before any other header files @@ -11,31 +11,26 @@ namespace clp_ffi_py::ir::native { /** - * A PyObject structure functioning as a Python-compatible interface to retrieve - * a log event. The underlying data is pointed to by `m_log_event`. The object - * may reference a PyMetadata object pointed to by `m_py_metadata` that - * specifies the event's metadata, such as timestamp format, from the preamble. + * A PyObject structure functioning as a Python-compatible interface to retrieve a log event. The + * underlying data is pointed to by `m_log_event`. The object may reference a PyMetadata object + * pointed to by `m_py_metadata` that specifies the event's metadata, such as timestamp format, from + * the preamble. */ class PyLogEvent { public: /** - * Initializes the underlying data with the given inputs. - * Since the memory allocation of PyLogEvent is handled by CPython's - * allocator, cpp constructors will not be explicitly called. This function - * serves as the default constructor to initialize the underlying metadata. - * It has to be manually called whenever creating a new PyLogEvent object - * through CPython APIs. + * Initializes the underlying data with the given inputs. Since the memory allocation of + * PyLogEvent is handled by CPython's allocator, cpp constructors will not be explicitly called. + * This function serves as the default constructor to initialize the underlying metadata. It has + * to be manually called whenever creating a new PyLogEvent object through CPython APIs. * @param log_message * @param timestamp * @param index - * @param metadata A PyMetadata instance to bind with the log event (can be - * nullptr). - * @param formatted_timestamp Formatted timestamp. This argument is not - * given by default. It should be given when deserializing the object from - * a saved state. + * @param metadata A PyMetadata instance to bind with the log event (can be nullptr). + * @param formatted_timestamp Formatted timestamp. This argument is not given by default. It + * should be given when deserializing the object from a saved state. * @return true on success. - * @return false on failure with the relevant Python exception and error - * set. + * @return false on failure with the relevant Python exception and error set. */ [[nodiscard]] auto init( std::string_view log_message, @@ -52,8 +47,8 @@ class PyLogEvent { [[nodiscard]] auto has_metadata() -> bool { return nullptr != m_py_metadata; } /** - * Initializes the pointers to nullptr by default. Should be called once - * the object is allocated. + * Initializes the pointers to nullptr by default. Should be called once the object is + * allocated. */ auto default_init() -> void { m_log_event = nullptr; @@ -61,8 +56,8 @@ class PyLogEvent { } /** - * Releases the memory allocated for underlying metadata field and the - * reference hold for the Python object(s). + * Releases the memory allocated for underlying metadata field and the reference hold for the + * Python object(s). */ auto clean() -> void { Py_XDECREF(m_py_metadata); @@ -70,8 +65,8 @@ class PyLogEvent { } /** - * Binds the given PyMetadata and holds a reference. If `Py_metadata` has - * been set already, decrement the reference to discard the old value. + * Binds the given PyMetadata and holds a reference. If `Py_metadata` has been set already, + * decrement the reference to discard the old value. * @param metadata */ auto set_metadata(PyMetadata* metadata) -> void { @@ -83,17 +78,14 @@ class PyLogEvent { } /** - * Gets the formatted log message represented by the underlying log event. - * If a specific timezone is provided, this timezone is used to format the - * timestamp. If the timezone is not provided (Py_None), the default - * formatted timestamp from the log event is used. In the case where - * the log event does not have a cached formatted timestamp, it obtains one - * using the default timezone from the metadata (if metadata is present), - * or defaults to UTC. + * Gets the formatted log message represented by the underlying log event. If a specific + * timezone is provided, this timezone is used to format the timestamp. If the timezone is not + * provided (Py_None), the default formatted timestamp from the log event is used. In the case + * where the log event does not have a cached formatted timestamp, it obtains one using the + * default timezone from the metadata (if metadata is present), or defaults to UTC. * @param timezone Python tzinfo object that specifies a timezone. * @return Python string of the formatted log message. - * @return nullptr on failure with the relevant Python exception and error - * set. + * @return nullptr on failure with the relevant Python exception and error set. */ [[nodiscard]] auto get_formatted_message(PyObject* timezone = Py_None) -> PyObject*; @@ -102,21 +94,19 @@ class PyLogEvent { [[nodiscard]] auto get_py_metadata() -> PyMetadata* { return m_py_metadata; } /** - * Gets the PyTypeObject that represents PyLogEvent's Python type. This type - * is dynamically created and initialized during the execution of - * `PyLogEvent::module_level_init`. + * Gets the PyTypeObject that represents PyLogEvent's Python type. This type is dynamically + * created and initialized during the execution of `PyLogEvent::module_level_init`. * @return Python type object associated with PyLogEvent. */ [[nodiscard]] static auto get_py_type() -> PyTypeObject*; /** - * Creates and initializes PyLogEvent as a Python type, and then - * incorporates this type as a Python object into the py_module module. - * @param py_module This is the Python module where the initialized - * PyLogEvent will be incorporated. + * Creates and initializes PyLogEvent as a Python type, and then incorporates this type as a + * Python object into the py_module module. + * @param py_module This is the Python module where the initialized PyLogEvent will be + * incorporated. * @return true on success. - * @return false on failure with the relevant Python exception and error - * set. + * @return false on failure with the relevant Python exception and error set. */ [[nodiscard]] static auto module_level_init(PyObject* py_module) -> bool; @@ -125,12 +115,9 @@ class PyLogEvent { * @param log_message * @param timestamp * @param index - * @param metadata A PyMetadata instance to bind with the log event (can be - * nullptr). - * @return a new reference of a PyLogEvent object that is initialized with - * the given inputs. - * @return nullptr on failure with the relevant Python exception and error - * set. + * @param metadata A PyMetadata instance to bind with the log event (can be nullptr). + * @return a new reference of a PyLogEvent object that is initialized with the given inputs. + * @return nullptr on failure with the relevant Python exception and error set. */ [[nodiscard]] static auto create_new_log_event( std::string_view log_message, @@ -147,4 +134,5 @@ class PyLogEvent { static PyObjectStaticPtr m_py_type; }; } // namespace clp_ffi_py::ir::native -#endif // CLP_FFI_PY_PY_LOG_EVENT_HPP + +#endif // CLP_FFI_PY_IR_NATIVE_PYLOGEVENT_HPP diff --git a/src/clp_ffi_py/ir/native/PyMetadata.cpp b/src/clp_ffi_py/ir/native/PyMetadata.cpp index b7875662..38b67019 100644 --- a/src/clp_ffi_py/ir/native/PyMetadata.cpp +++ b/src/clp_ffi_py/ir/native/PyMetadata.cpp @@ -16,8 +16,8 @@ extern "C" { * Callback of PyMetadata `__init__` method: * __init__(self, ref_timestamp, timestamp_format, timezone_id) * Keyword argument parsing is supported. - * Assumes `self` is uninitialized and will allocate the underlying memory. If - * `self` is already initialized this will result in memory leaks. + * Assumes `self` is uninitialized and will allocate the underlying memory. If `self` is already + * initialized this will result in memory leaks. * @param self * @param args * @param keywords @@ -39,9 +39,8 @@ auto PyMetadata_init(PyMetadata* self, PyObject* args, PyObject* keywords) -> in char const* input_timestamp_format{nullptr}; char const* input_timezone{nullptr}; - // If the argument parsing fails, `self` will be deallocated. We must reset - // all pointers to nullptr in advance, otherwise the deallocator might - // trigger segmentation fault + // If the argument parsing fails, `self` will be deallocated. We must reset all pointers to + // nullptr in advance, otherwise the deallocator might trigger segmentation fault self->default_init(); if (false diff --git a/src/clp_ffi_py/ir/native/PyMetadata.hpp b/src/clp_ffi_py/ir/native/PyMetadata.hpp index ed0753ae..482f4216 100644 --- a/src/clp_ffi_py/ir/native/PyMetadata.hpp +++ b/src/clp_ffi_py/ir/native/PyMetadata.hpp @@ -1,5 +1,5 @@ -#ifndef CLP_FFI_PY_PYMETADATA_HPP -#define CLP_FFI_PY_PYMETADATA_HPP +#ifndef CLP_FFI_PY_IR_NATIVE_PYMETADATA_HPP +#define CLP_FFI_PY_IR_NATIVE_PYMETADATA_HPP #include // Must always be included before any other header files @@ -10,26 +10,22 @@ namespace clp_ffi_py::ir::native { /** - * A PyObject structure functioning as a Python-compatible interface to retrieve - * CLP IR metadata. The underlying data is pointed to by `m_metadata`. - * Additionally, it retains a tzinfo object at the Python level that signifies - * the corresponding timezone. + * A PyObject structure functioning as a Python-compatible interface to retrieve CLP IR metadata. + * The underlying data is pointed to by `m_metadata`. Additionally, it retains a tzinfo object at + * the Python level that signifies the corresponding timezone. */ class PyMetadata { public: /** - * Initializes the underlying data with the given inputs. - * Since the memory allocation of PyMetadata is handled by CPython - * allocator, cpp constructors will not be explicitly called. This function - * serves as the default constructor to initialize the underlying metadata. - * It has to be manually called whenever creating a new PyMetadata object - * through CPython APIs. + * Initializes the underlying data with the given inputs. Since the memory allocation of + * PyMetadata is handled by CPython allocator, cpp constructors will not be explicitly called. + * This function serves as the default constructor to initialize the underlying metadata. + * It has to be manually called whenever creating a new PyMetadata object through CPython APIs. * @param ref_timestamp * @param input_timestamp_format * @param input_timezone * @return true on success. - * @return false on failure with the relevant Python exception and error - * set. + * @return false on failure with the relevant Python exception and error set. */ [[nodiscard]] auto init( clp::ir::epoch_time_ms_t ref_timestamp, @@ -42,15 +38,14 @@ class PyMetadata { * @param metadata * @param is_four_byte_encoding * @return true on success. - * @return false on failure with the relevant Python exception and error - * set. + * @return false on failure with the relevant Python exception and error set. */ [[nodiscard]] auto init(nlohmann::json const& metadata, bool is_four_byte_encoding = true) -> bool; /** - * Releases the memory allocated for underlying metadata field and the - * reference hold for the Python object(s). + * Releases the memory allocated for underlying metadata field and the reference hold for the + * Python object(s). */ auto clean() -> void { delete m_metadata; @@ -58,8 +53,8 @@ class PyMetadata { } /** - * Initializes the pointers to nullptr by default. Should be called once - * the object is allocated. + * Initializes the pointers to nullptr by default. Should be called once the object is + * allocated. */ auto default_init() -> void { m_metadata = nullptr; @@ -71,45 +66,40 @@ class PyMetadata { [[nodiscard]] auto get_py_timezone() -> PyObject* { return m_py_timezone; } /** - * Gets the PyTypeObject that represents PyMetadata's Python type. This type - * is dynamically created and initialized during the execution of - * `PyMetadata::module_level_init`. + * Gets the PyTypeObject that represents PyMetadata's Python type. This type is dynamically + * created and initialized during the execution of `PyMetadata::module_level_init`. * @return Python type object associated with PyMetadata. */ [[nodiscard]] static auto get_py_type() -> PyTypeObject*; /** - * Creates and initializes PyMetadata as a Python type, and then - * incorporates this type as a Python object into the py_module module. - * @param py_module This is the Python module where the initialized - * PyMetadata will be incorporated. + * Creates and initializes PyMetadata as a Python type, and then incorporates this type as a + * Python object into the py_module module. + * @param py_module This is the Python module where the initialized PyMetadata will be + * incorporated. * @return true on success. - * @return false on failure with the relevant Python exception and error - * set. + * @return false on failure with the relevant Python exception and error set. */ [[nodiscard]] static auto module_level_init(PyObject* py_module) -> bool; /** - * Creates and initializes a new PyMetadata object with the metadata values - * specified in the JSON format. + * Creates and initializes a new PyMetadata object with the metadata values specified in the + * JSON format. * @param metadata CLP IR metadata stored in the JSON format. - * @param is_four_byte_encoding Indicates whether the CLP IR uses 4-byte - * encoding (true) or 8-byte encoding (false). - * @return a new reference of a PyMetadata object that is initialized with - * the given inputs. - * @return nullptr on failure with the relevant Python exception and error - * set. + * @param is_four_byte_encoding Indicates whether the CLP IR uses 4-byte encoding (true) or + * 8-byte encoding (false). + * @return a new reference of a PyMetadata object that is initialized with the given inputs. + * @return nullptr on failure with the relevant Python exception and error set. */ [[nodiscard]] static auto create_new_from_json(nlohmann::json const& metadata, bool is_four_byte_encoding) -> PyMetadata*; private: /** - * Initializes py_timezone by setting the corresponded tzinfo object from - * the timezone id. Should be called by `init` methods. + * Initializes py_timezone by setting the corresponded tzinfo object from the timezone id. + * Should be called by `init` methods. * @return true on success. - * @return false on failure with the relevant Python exception and error - * set. + * @return false on failure with the relevant Python exception and error set. */ [[nodiscard]] auto init_py_timezone() -> bool; @@ -120,4 +110,5 @@ class PyMetadata { static PyObjectStaticPtr m_py_type; }; } // namespace clp_ffi_py::ir::native -#endif // CLP_FFI_PY_PY_METADATA_HPP + +#endif // CLP_FFI_PY_IR_NATIVE_PYMETADATA_HPP diff --git a/src/clp_ffi_py/ir/native/PyQuery.cpp b/src/clp_ffi_py/ir/native/PyQuery.cpp index 04ebdd7f..739f2f17 100644 --- a/src/clp_ffi_py/ir/native/PyQuery.cpp +++ b/src/clp_ffi_py/ir/native/PyQuery.cpp @@ -15,16 +15,13 @@ namespace clp_ffi_py::ir::native { namespace { /** - * Deserializes the wildcard queries from a list of Python wildcard queries into - * a WildcardQuery std::vector. - * If there is no wildcard queries given, the given py_wildcard_queries will be - * set to Py_None. - * @param py_wildcard_queries A Python list that contains Python wildcard - * queries. Each element inside this list should be an instance of WildcardQuery - * defined in clp_ffi_py Python module. - * @param wildcard_queries The output std::vector that contains cleaned wildcard - * queries from the input. If py_wildcard_queries is Py_None, wildcard_queries - * will be set to empty. + * Deserializes the wildcard queries from a list of Python wildcard queries into a WildcardQuery + * std::vector. If there is no wildcard queries given, the given py_wildcard_queries will be set to + * Py_None. + * @param py_wildcard_queries A Python list that contains Python wildcard queries. Each element + * inside this list should be an instance of WildcardQuery defined in clp_ffi_py Python module. + * @param wildcard_queries The output std::vector that contains cleaned wildcard queries from the + * input. If py_wildcard_queries is Py_None, wildcard_queries will be set to empty. * @return true on success. * @return false on failure with the relevant Python exception and error set. */ @@ -75,9 +72,8 @@ auto deserialize_wildcard_queries( } /** - * Serializes the std::vector of WildcardQuery into a Python list. Serves as a - * helper function to serialize the underlying wildcard queries of the PyQuery - * object. + * Serializes the std::vector of WildcardQuery into a Python list. Serves as a helper function to + * serialize the underlying wildcard queries of the PyQuery object. * @param wildcard_queries A std::vector of WildcardQuery. * @return The Python list that consists of Python wildcard query objects. * @return Py_None if the wildcard_queries are empty. @@ -93,9 +89,8 @@ auto serialize_wildcard_queries(std::vector const& wildcard_queri return nullptr; } - // In case of failure, we only need to decrement the reference for the - // Python list. CPython will decrement the reference count of all the - // objects it contains. + // In case of failure, we only need to decrement the reference for the Python list. CPython will + // decrement the reference count of all the objects it contains. Py_ssize_t idx{0}; for (auto const& wildcard_query : wildcard_queries) { PyObjectPtr const wildcard_py_str_ptr{ @@ -137,8 +132,8 @@ extern "C" { * Query.default_search_time_termination_margin() * ) * Keyword argument parsing is supported. - * Assumes `self` is uninitialized and will allocate the underlying memory. If - * `self` is already initialized this will result in memory leaks. + * Assumes `self` is uninitialized and will allocate the underlying memory. If `self` is already + * initialized this will result in memory leaks. * @param self * @param args * @param keywords @@ -158,9 +153,8 @@ auto PyQuery_init(PyQuery* self, PyObject* args, PyObject* keywords) -> int { nullptr }; - // If the argument parsing fails, `self` will be deallocated. We must reset - // all pointers to nullptr in advance, otherwise the deallocator might - // trigger a segmentation fault. + // If the argument parsing fails, `self` will be deallocated. We must reset all pointers to + // nullptr in advance, otherwise the deallocator might trigger a segmentation fault. self->default_init(); auto search_time_lower_bound{Query::cTimestampMin}; @@ -211,8 +205,8 @@ auto PyQuery_dealloc(PyQuery* self) -> void { } /** - * Constant keys used to serialize/deserialize PyQuery objects through - * __getstate__ and __setstate__ methods. + * Constant keys used to serialize/deserialize PyQuery objects through `__getstate__` and + * `__setstate__` methods. */ constexpr char const* const cStateSearchTimeLowerBound = "search_time_lower_bound"; constexpr char const* const cStateSearchTimeUpperBound = "search_time_upper_bound"; @@ -270,8 +264,8 @@ PyDoc_STRVAR( /** * Callback of PyQuery `__setstate__` method. * Note: should only be used by the Python pickle module. - * Assumes `self` is uninitialized and will allocate the underlying memory. If - * `self` is already initialized this will result in memory leaks. + * Assumes `self` is uninitialized and will allocate the underlying memory. If `self` is already + * initialized this will result in memory leaks. * @param self * @param state Python dictionary that contains the serialized object info. * @return Py_None on success diff --git a/src/clp_ffi_py/ir/native/PyQuery.hpp b/src/clp_ffi_py/ir/native/PyQuery.hpp index 8cbde3d7..970a51b3 100644 --- a/src/clp_ffi_py/ir/native/PyQuery.hpp +++ b/src/clp_ffi_py/ir/native/PyQuery.hpp @@ -1,5 +1,5 @@ -#ifndef CLP_FFI_PY_PYQUERY_HPP -#define CLP_FFI_PY_PYQUERY_HPP +#ifndef CLP_FFI_PY_IR_NATIVE_PYQUERY_HPP +#define CLP_FFI_PY_IR_NATIVE_PYQUERY_HPP #include // Must always be included before any other header files @@ -8,29 +8,25 @@ namespace clp_ffi_py::ir::native { /** - * A PyObject structure functioning as a Python-compatible interface to retrieve - * a search query that is used to filter log events in a CLP IR stream. The - * underlying data is pointed to by `m_query`. A detailed description can be - * found in the PyQuery Python doc strings. + * A PyObject structure functioning as a Python-compatible interface to retrieve a search query that + * is used to filter log events in a CLP IR stream. The underlying data is pointed to by `m_query`. + * A detailed description can be found in the PyQuery Python doc strings. */ class PyQuery { public: /** - * Initializes the underlying data with the given input. - * Since the memory allocation of PyQuery is handled by CPython's - * allocator, any cpp constructor will not be explicitly called. This - * function serves as the default constructor to initialize the underlying - * query. It has to be manually called whenever creating a new PyQuery - * object through CPython AIPs. + * Initializes the underlying data with the given input. Since the memory allocation of PyQuery + * is handled by CPython's allocator, any cpp constructor will not be explicitly called. This + * function serves as the default constructor to initialize the underlying query. It has to be + * manually called whenever creating a new PyQuery object through CPython AIPs. * @param search_time_lower_bound Start of search time range (inclusive). * @param search_time_upper_bound End of search time range (inclusive). - * @param wildcard_queries A list of wildcard queries. Each wildcard query - * must be valid (see `wildcard_match_unsafe`). - * @param search_time_termination_margin The margin used to determine the - * search termination timestamp (see note in the Query class' docstring). + * @param wildcard_queries A list of wildcard queries. Each wildcard query must be valid (see + * `wildcard_match_unsafe`). + * @param search_time_termination_margin The margin used to determine the search termination + * timestamp (see note in the Query class' docstring). * @return true on success. - * @return false on failure with the relevant Python exception and error - * set. + * @return false on failure with the relevant Python exception and error set. */ [[nodiscard]] auto init( clp::ir::epoch_time_ms_t search_time_lower_bound, @@ -40,8 +36,8 @@ class PyQuery { ) -> bool; /** - * Initializes the pointers to nullptr by default. Should be called once - * the object is allocated. + * Initializes the pointers to nullptr by default. Should be called once the object is + * allocated. */ auto default_init() -> void { m_query = nullptr; } @@ -53,21 +49,19 @@ class PyQuery { [[nodiscard]] auto get_query() -> Query* { return m_query; } /** - * Gets the PyTypeObject that represents PyQuery's Python type. This type - * is dynamically created and initialized during the execution of - * `PyQuery::module_level_init`. + * Gets the PyTypeObject that represents PyQuery's Python type. This type is dynamically created + * and initialized during the execution of `PyQuery::module_level_init`. * @return Python type object associated with PyQuery. */ [[nodiscard]] static auto get_py_type() -> PyTypeObject*; /** - * Creates and initializes PyQuery as a Python type, and then - * incorporates this type as a Python object into the py_module module. - * @param py_module This is the Python module where the initialized - * PyQuery will be incorporated. + * Creates and initializes PyQuery as a Python type, and then incorporates this type as a Python + * object into the py_module module. + * @param py_module This is the Python module where the initialized PyQuery will be + * incorporated. * @return true on success. - * @return false on failure with the relevant Python exception and error - * set. + * @return false on failure with the relevant Python exception and error set. */ [[nodiscard]] static auto module_level_init(PyObject* py_module) -> bool; @@ -77,8 +71,7 @@ class PyQuery { [[nodiscard]] static auto get_py_wildcard_query_type() -> PyObject*; /** - * @return PyObject that represents the Python level class - * `FullStringWildcardQuery`. + * @return PyObject that represents the Python level class `FullStringWildcardQuery`. */ [[nodiscard]] static auto get_py_full_string_wildcard_query_type() -> PyObject*; @@ -91,4 +84,5 @@ class PyQuery { static PyObjectStaticPtr m_py_full_string_wildcard_query_type; }; } // namespace clp_ffi_py::ir::native -#endif + +#endif // CLP_FFI_PY_IR_NATIVE_PYQUERY_HPP diff --git a/src/clp_ffi_py/ir/native/Query.hpp b/src/clp_ffi_py/ir/native/Query.hpp index 24d62d8b..c7b9d76b 100644 --- a/src/clp_ffi_py/ir/native/Query.hpp +++ b/src/clp_ffi_py/ir/native/Query.hpp @@ -1,5 +1,5 @@ -#ifndef CLP_FFI_PY_QUERY_HPP -#define CLP_FFI_PY_QUERY_HPP +#ifndef CLP_FFI_PY_IR_NATIVE_QUERY_HPP +#define CLP_FFI_PY_IR_NATIVE_QUERY_HPP #include #include @@ -14,8 +14,8 @@ namespace clp_ffi_py::ir::native { /** - * This class defines a wildcard query, which includes a wildcard string and a - * boolean value to indicate if the match is case-sensitive. + * This class defines a wildcard query, which includes a wildcard string and a boolean value to + * indicate if the match is case-sensitive. */ class WildcardQuery { public: @@ -38,21 +38,19 @@ class WildcardQuery { }; /** - * This class represents a search query, utilized for filtering log events in a - * CLP IR stream. The query could include a list of wildcard queries aimed at - * identifying certain log messages, and a timestamp range with a lower and - * upper bound. This class provides an interface to set up a search query, as - * well as methods to validate whether the query can be matched by a log event. - * Note that an empty wildcard query list will match any log within the range. + * This class represents a search query, utilized for filtering log events in a CLP IR stream. The + * query could include a list of wildcard queries aimed at identifying certain log messages, and a + * timestamp range with a lower and upper bound. This class provides an interface to set up a search + * query, as well as methods to validate whether the query can be matched by a log event. Note that + * an empty wildcard query list will match any log within the range. *

- * NOTE: When searching an IR stream with a query, ideally, the search - * would terminate once the current log event's timestamp exceeds the upper - * bound of the query's time range. However, the timestamps in the IR stream - * might not be monotonically increasing; they can be locally disordered due to - * thread contention. So to safely stop searching, we need to ensure that the - * current timestamp in the IR stream exceeds the query's upper bound timestamp - * by a reasonable margin. This margin can be specified by the user or it - * will default to `cDefaultSearchTimeTerminationMargin`. + * NOTE: When searching an IR stream with a query, ideally, the search would terminate once the + * current log event's timestamp exceeds the upper bound of the query's time range. However, the + * timestamps in the IR stream might not be monotonically increasing; they can be locally disordered + * due to thread contention. So to safely stop searching, we need to ensure that the current + * timestamp in the IR stream exceeds the query's upper bound timestamp by a reasonable margin. + * This margin can be specified by the user or it will default to + * `cDefaultSearchTimeTerminationMargin`. */ class Query { public: @@ -65,9 +63,8 @@ class Query { }; /** - * Constructs an empty query object that will match all logs. The wildcard - * query list is empty and the timestamp range is set to include all the - * valid Unix epoch timestamps. + * Constructs an empty query object that will match all logs. The wildcard query list is empty + * and the timestamp range is set to include all the valid Unix epoch timestamps. */ explicit Query() : m_lower_bound_ts{cTimestampMin}, @@ -75,12 +72,11 @@ class Query { m_search_termination_ts{cTimestampMax} {}; /** - * Constructs a new query object with the given timestamp range with an - * empty wildcard list. + * Constructs a new query object with the given timestamp range with an empty wildcard list. * @param search_time_lower_bound Start of search time range (inclusive). * @param search_time_upper_bound End of search time range (inclusive). - * @param search_time_termination_margin The margin used to determine the - * search termination timestamp (see note in the class' docstring). + * @param search_time_termination_margin The margin used to determine the search termination + * timestamp (see note in the class' docstring). */ explicit Query( clp::ir::epoch_time_ms_t search_time_lower_bound, @@ -99,14 +95,13 @@ class Query { } /** - * Constructs a new query object with the given timestamp range and a - * wildcard query list. + * Constructs a new query object with the given timestamp range and a wildcard query list. * @param search_time_lower_bound Start of search time range (inclusive). * @param search_time_upper_bound End of search time range (inclusive). - * @param wildcard_queries A list of wildcard queries. Each wildcard query - * must be valid (see `wildcard_match_unsafe`). - * @param search_time_termination_margin The margin used to determine the - * search termination timestamp (see note in the class' docstring). + * @param wildcard_queries A list of wildcard queries. Each wildcard query must be valid (see + * `wildcard_match_unsafe`). + * @param search_time_termination_margin The margin used to determine the search termination + * timestamp (see note in the class' docstring). */ Query(clp::ir::epoch_time_ms_t search_time_lower_bound, clp::ir::epoch_time_ms_t search_time_upper_bound, @@ -137,8 +132,8 @@ class Query { } /** - * @return The search time termination margin by calculating the difference - * between m_search_termination_ts and m_upper_bound_ts. + * @return The search time termination margin by calculating the difference between + * `m_search_termination_ts` and `m_upper_bound_ts`. */ [[nodiscard]] auto get_search_time_termination_margin() const -> clp::ir::epoch_time_ms_t { return m_search_termination_ts - m_upper_bound_ts; @@ -146,8 +141,8 @@ class Query { /** * @param ts Input timestamp. - * @return true if the given timestamp is in the search time range bounded - * by the lower bound and the upper bound timestamp (inclusive). + * @return true if the given timestamp is in the search time range bounded by the lower bound + * and the upper bound timestamp (inclusive). */ [[nodiscard]] auto matches_time_range(clp::ir::epoch_time_ms_t ts) const -> bool { return m_lower_bound_ts <= ts && ts <= m_upper_bound_ts; @@ -155,19 +150,17 @@ class Query { /** * @param ts Input timestamp. - * @return Whether the given timestamp is safely outside this query's time - * range (see note in the class' docstring). + * @return Whether the given timestamp is safely outside this query's time range (see note in + * the class' docstring). */ [[nodiscard]] auto ts_safely_outside_time_range(clp::ir::epoch_time_ms_t ts) const -> bool { return m_search_termination_ts < ts; } /** - * Validates whether the input log message matches any of the wildcard - * queries in the query. + * Validates whether the input log message matches any of the wildcard queries in the query. * @param log_message Input log message. - * @return true if the wildcard query list is empty or at least one wildcard - * query matches. + * @return true if the wildcard query list is empty or at least one wildcard query matches. * @return false otherwise. */ [[nodiscard]] auto matches_wildcard_queries(std::string_view log_message) const -> bool; @@ -175,8 +168,8 @@ class Query { /** * Validates whether the input log event matches the query. * @param log_event Input log event. - * @return true if the timestamp is in range, and the wildcard list is empty - * or has at least one match. + * @return true if the timestamp is in range, and the wildcard list is empty or has at least one + * match. * @return false otherwise. */ [[nodiscard]] auto matches(LogEvent const& log_event) const -> bool { @@ -205,4 +198,5 @@ class Query { std::vector m_wildcard_queries; }; } // namespace clp_ffi_py::ir::native -#endif + +#endif // CLP_FFI_PY_IR_NATIVE_QUERY_HPP diff --git a/src/clp_ffi_py/ir/native/decoding_methods.cpp b/src/clp_ffi_py/ir/native/decoding_methods.cpp index 261fa29a..ee2756fd 100644 --- a/src/clp_ffi_py/ir/native/decoding_methods.cpp +++ b/src/clp_ffi_py/ir/native/decoding_methods.cpp @@ -28,8 +28,8 @@ using clp::ffi::ir_stream::IRProtocolErrorCode; namespace { /** - * This template defines the function signature of a termination handler - * required by `generic_decode_log_event`. Signature: ( + * This template defines the function signature of a termination handler required by + * `generic_decode_log_event`. Signature: ( * ffi::epoch_timestamp_ms timestamp, * std::string_view decoded_log_message, * size_t decoded_log_event_idx, @@ -77,14 +77,14 @@ concept TerminateHandlerSignature = requires(TerminateHandler handler) { } /** - * Decodes the next log event from the CLP IR buffer `decoder_buffer` until - * terminate handler returns true. - * @tparam TerminateHandler Method to determine if the decoding should - * terminate, and set the return value for termination. + * Decodes the next log event from the CLP IR buffer `decoder_buffer` until terminate handler + * returns true. + * @tparam TerminateHandler Method to determine if the decoding should terminate, and set the return + * value for termination. * @param decoder_buffer IR decoder buffer of the input IR stream. - * @param allow_incomplete_stream A flag to indicate whether the incomplete - * stream error should be ignored. If it is set to true, incomplete stream error - * should be treated as the IR stream is terminated. + * @param allow_incomplete_stream A flag to indicate whether the incomplete stream error should be + * ignored. If it is set to true, incomplete stream error should be treated as the IR stream is + * terminated. * @param terminate_handler * @return The return value set by `terminate_handler`. * @return PyNone if the IR stream is terminated. diff --git a/src/clp_ffi_py/ir/native/decoding_methods.hpp b/src/clp_ffi_py/ir/native/decoding_methods.hpp index 85d4c0c8..88869c1a 100644 --- a/src/clp_ffi_py/ir/native/decoding_methods.hpp +++ b/src/clp_ffi_py/ir/native/decoding_methods.hpp @@ -1,10 +1,10 @@ -#ifndef CLP_FFI_PY_DECODING_METHODS -#define CLP_FFI_PY_DECODING_METHODS +#ifndef CLP_FFI_PY_IR_NATIVE_DECODING_METHODS +#define CLP_FFI_PY_IR_NATIVE_DECODING_METHODS #include // Must always be included before any other header files -// Documentation for these methods is in clp/ir/native/PyDecoder.cpp, as it also -// serves as the documentation for Python. +// Documentation for these methods is in clp/ir/native/PyDecoder.cpp, as it also serves as the +// documentation for Python. namespace clp_ffi_py::ir::native { extern "C" { auto decode_preamble(PyObject* self, PyObject* py_decoder_buffer) -> PyObject*; @@ -12,4 +12,4 @@ auto decode_next_log_event(PyObject* self, PyObject* args, PyObject* keywords) - } } // namespace clp_ffi_py::ir::native -#endif +#endif // CLP_FFI_PY_IR_NATIVE_DECODING_METHODS diff --git a/src/clp_ffi_py/ir/native/encoding_methods.cpp b/src/clp_ffi_py/ir/native/encoding_methods.cpp index 57406fc0..f54603b1 100644 --- a/src/clp_ffi_py/ir/native/encoding_methods.cpp +++ b/src/clp_ffi_py/ir/native/encoding_methods.cpp @@ -70,8 +70,7 @@ auto encode_four_byte_message_and_timestamp_delta(PyObject* Py_UNUSED(self), PyO std::vector ir_buf; std::string_view const msg{input_buffer, static_cast(input_buffer_size)}; - // To avoid the frequent expansion of ir_buf, - // allocate sufficient space in advance + // To avoid the frequent expansion of ir_buf, allocate sufficient space in advance ir_buf.reserve(input_buffer_size * 2); if (false == clp::ffi::ir_stream::four_byte_encoding::serialize_message(msg, logtype, ir_buf)) { diff --git a/src/clp_ffi_py/ir/native/encoding_methods.hpp b/src/clp_ffi_py/ir/native/encoding_methods.hpp index 4f9367b4..8352cdf2 100644 --- a/src/clp_ffi_py/ir/native/encoding_methods.hpp +++ b/src/clp_ffi_py/ir/native/encoding_methods.hpp @@ -1,11 +1,10 @@ -#ifndef CLP_FFI_PY_ENCODING_METHODS -#define CLP_FFI_PY_ENCODING_METHODS +#ifndef CLP_FFI_PY_IR_NATIVE_PY_ENCODING_METHODS +#define CLP_FFI_PY_IR_NATIVE_PY_ENCODING_METHODS #include // Must always be included before any other header files -// Documentation for these methods is in -// clp_ffi_py/ir/native/PyFourByteEncoder.cpp, as it also serves as the -// documentation for python. +// Documentation for these methods is in clp_ffi_py/ir/native/PyFourByteEncoder.cpp, as it also +// serves as the documentation for python. namespace clp_ffi_py::ir::native { auto encode_four_byte_preamble(PyObject* self, PyObject* args) -> PyObject*; auto encode_four_byte_message_and_timestamp_delta(PyObject* self, PyObject* args) -> PyObject*; @@ -14,4 +13,4 @@ auto encode_four_byte_timestamp_delta(PyObject* self, PyObject* args) -> PyObjec auto encode_end_of_ir(PyObject* self) -> PyObject*; } // namespace clp_ffi_py::ir::native -#endif +#endif // CLP_FFI_PY_IR_NATIVE_PY_ENCODING_METHODS diff --git a/src/clp_ffi_py/ir/native/error_messages.hpp b/src/clp_ffi_py/ir/native/error_messages.hpp index ada8226d..fdf1ead9 100644 --- a/src/clp_ffi_py/ir/native/error_messages.hpp +++ b/src/clp_ffi_py/ir/native/error_messages.hpp @@ -1,5 +1,5 @@ -#ifndef CLP_FFI_PY_IR_ERROR_MESSAGES -#define CLP_FFI_PY_IR_ERROR_MESSAGES +#ifndef CLP_FFI_PY_IR_NATIVE_ERROR_MESSAGES +#define CLP_FFI_PY_IR_NATIVE_ERROR_MESSAGES namespace clp_ffi_py::ir::native { constexpr char const* cDecoderBufferOverflowError = "DecoderBuffer internal read buffer overflows."; @@ -11,4 +11,4 @@ constexpr char const* cEncodePreambleError = "Native encoder cannot encode the g constexpr char const* cEncodeMessageError = "Native encoder cannot encode the given message"; } // namespace clp_ffi_py::ir::native -#endif // CLP_FFI_PY_IR_ERROR_MESSAGES +#endif // CLP_FFI_PY_IR_NATIVE_ERROR_MESSAGES diff --git a/src/clp_ffi_py/utils.cpp b/src/clp_ffi_py/utils.cpp index 5038c40f..e5caa604 100644 --- a/src/clp_ffi_py/utils.cpp +++ b/src/clp_ffi_py/utils.cpp @@ -4,16 +4,14 @@ #include -#include #include namespace clp_ffi_py { namespace { /** * Gets the underlying py_string byte data. - * @param py_string PyObject that represents a Python level string. Only Python - * Unicode object or an instance of a Python Unicode subtype will be considered - * as valid input. + * @param py_string PyObject that represents a Python level string. Only Python Unicode object or an + * instance of a Python Unicode subtype will be considered as valid input. * @return pointer to the byte data on success. * @return nullptr on failure with the relevant Python exception and error set. */ diff --git a/src/clp_ffi_py/utils.hpp b/src/clp_ffi_py/utils.hpp index 204b347b..ad24b7b4 100644 --- a/src/clp_ffi_py/utils.hpp +++ b/src/clp_ffi_py/utils.hpp @@ -5,8 +5,11 @@ #include #include +#include #include +#include + namespace clp_ffi_py { /** * Adds the given Python type to the given Python module. @@ -20,9 +23,8 @@ auto add_python_type(PyTypeObject* new_type, char const* type_name, PyObject* mo /** * Parses a Python string into std::string. - * @param py_string PyObject that represents a Python level string. Only Python - * Unicode object or an instance of a Python Unicode subtype will be considered - * as valid input. + * @param py_string PyObject that represents a Python level string. Only Python Unicode object or an + * instance of a Python Unicode subtype will be considered as valid input. * @param out The string parsed. * @return true on success. * @return false on failure with the relevant Python exception and error set. @@ -31,9 +33,8 @@ auto parse_py_string(PyObject* py_string, std::string& out) -> bool; /** * Parses a Python string into std::string_view. - * @param py_string PyObject that represents a Python level string. Only Python - * Unicode object or an instance of a Python Unicode subtype will be considered - * as valid input. + * @param py_string PyObject that represents a Python level string. Only Python Unicode object or an + * instance of a Python Unicode subtype will be considered as valid input. * @param view The string_view of the underlying byte data of py_string. * @return true on success. * @return false on failure with the relevant Python exception and error set. @@ -50,16 +51,54 @@ auto get_py_bool(bool is_true) -> PyObject*; /** * Parses a Python integer into an int_type variable. * @tparam int_type Output integer type (size and signed/unsigned). - * @param py_int PyObject that represents a Python level integer. Only - * PyLongObject or an instance of a subtype of PyLongObject will be considered - * as valid input. + * @param py_int PyObject that represents a Python level integer. Only PyLongObject or an instance + * of a subtype of PyLongObject will be considered as valid input. * @param val The integer parsed. * @return true on success. * @return false on failure with the relevant Python exception and error set. */ template auto parse_py_int(PyObject* py_int, int_type& val) -> bool; + +/** + * A template that always evaluates as false. + */ +template +[[maybe_unused]] constexpr bool cAlwaysFalse{false}; + +template +auto parse_py_int(PyObject* py_int, int_type& val) -> bool { + if (false == static_cast(PyLong_Check(py_int))) { + PyErr_SetString(PyExc_TypeError, "parse_py_int receives none-integer argument."); + return false; + } + + if constexpr (std::is_same_v) { + val = PyLong_AsSize_t(py_int); + } else if constexpr (std::is_same_v) { + val = PyLong_AsLongLong(py_int); + } else if constexpr (std::is_same_v) { + val = PyLong_AsSsize_t(py_int); + } else if constexpr (std::is_same_v) { + uint64_t const val_as_unsigned_long{PyLong_AsUnsignedLong(py_int)}; + if (nullptr != PyErr_Occurred()) { + return false; + } + if (std::numeric_limits::max() < val_as_unsigned_long) { + PyErr_Format( + PyExc_OverflowError, + "The input integer %lu overflows the range of type `uint32_t`", + val_as_unsigned_long + ); + return false; + } + val = static_cast(val_as_unsigned_long); + } else { + static_assert(cAlwaysFalse, "Given integer type not supported."); + } + + return (nullptr == PyErr_Occurred()); +} } // namespace clp_ffi_py -#include #endif // CLP_FFI_PY_UTILS_HPP diff --git a/src/clp_ffi_py/utils.inc b/src/clp_ffi_py/utils.inc deleted file mode 100644 index 6f3012fb..00000000 --- a/src/clp_ffi_py/utils.inc +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef CLP_FFI_PY_UTILS_TPP -#define CLP_FFI_PY_UTILS_TPP - -#include // Must always be included before any other header files - -#include - -#include - -namespace clp_ffi_py { -namespace { -template -[[maybe_unused]] constexpr bool cAlwaysFalse{false}; -} // namespace - -template -auto parse_py_int(PyObject* py_int, int_type& val) -> bool { - if (false == static_cast(PyLong_Check(py_int))) { - PyErr_SetString(PyExc_TypeError, "parse_py_int receives none-integer argument."); - return false; - } - - if constexpr (std::is_same_v) { - val = PyLong_AsSize_t(py_int); - } else if constexpr (std::is_same_v) { - val = PyLong_AsLongLong(py_int); - } else if constexpr (std::is_same_v) { - val = PyLong_AsSsize_t(py_int); - } else if constexpr (std::is_same_v) { - uint64_t const val_as_unsigned_long{PyLong_AsUnsignedLong(py_int)}; - if (nullptr != PyErr_Occurred()) { - return false; - } - if (std::numeric_limits::max() < val_as_unsigned_long) { - PyErr_Format( - PyExc_OverflowError, - "The input integer %lu overflows the range of type `uint32_t`", - val_as_unsigned_long - ); - return false; - } - val = static_cast(val_as_unsigned_long); - } else { - static_assert(cAlwaysFalse, "Given integer type not supported."); - } - - return (nullptr == PyErr_Occurred()); -} -} // namespace clp_ffi_py -#endif diff --git a/tests/test_ir/__init__.py b/tests/test_ir/__init__.py index 6ea1f470..ba56d539 100644 --- a/tests/test_ir/__init__.py +++ b/tests/test_ir/__init__.py @@ -14,9 +14,9 @@ def add_tests(suite: unittest.TestSuite, loader: unittest.TestLoader, test_class: type) -> None: """ - Recursively collect tests from concrete classes. Although Test*Base classes - are functionally abstract to the user we cannot properly make them abstract - as `unittest` will still create instances of these classes. + Recursively collect tests from concrete classes. Although Test*Base classes are functionally + abstract to the user we cannot properly make them abstract as `unittest` will still create + instances of these classes. :param suite: test suite to add found tests to :param loader: load test from `unittest.TestCase` class diff --git a/tests/test_ir/test_decoder.py b/tests/test_ir/test_decoder.py index 19053b6c..6c86d8b9 100644 --- a/tests/test_ir/test_decoder.py +++ b/tests/test_ir/test_decoder.py @@ -104,8 +104,8 @@ def _generate_random_query( self, ref_log_events: List[LogEvent] ) -> Tuple[Query, List[LogEvent]]: """ - Generates a random query and return all the log events in the given - `log_events` that matches this random query. + Generates a random query and return all the log events in the given `log_events` that + matches this random query. The derived class might overwrite this method to generate a random query using customized algorithm. By default, this function returns an empty @@ -120,13 +120,13 @@ def _decode_log_stream( self, log_path: Path, query: Optional[Query] ) -> Tuple[Metadata, List[LogEvent]]: """ - Decodes the log stream specified by `log_path`, using decoding methods - provided in clp_ffi_py.ir.Decoder. + Decodes the log stream specified by `log_path`, using decoding methods provided in + clp_ffi_py.ir.Decoder. :param log_path: The path to the log stream. :param query: Optional search query. - :return: A tuple that contains the decoded metadata and log events - returned from decoding methods. + :return: A tuple that contains the decoded metadata and log events returned from decoding + methods. """ with open(str(log_path), "rb") as istream: decoder_buffer: DecoderBuffer = DecoderBuffer(istream) @@ -152,11 +152,9 @@ def _validate_decoded_logs( Validates decoded logs from the IR stream specified by `log_path`. :param ref_metadata: Reference metadata. - :param ref_log_events: A list of reference log events sequence (order - sensitive). + :param ref_log_events: A list of reference log events sequence (order sensitive). :param decoded_metadata: Metadata decoded from the IR stream. - :param decoded_log_events: A list of log events decoded from the IR - stream in sequence. + :param decoded_log_events: A list of log events decoded from the IR stream in sequence. :param log_path: Local path of the IR stream. :param seed: Random seed used to generate the log events sequence. """ @@ -249,8 +247,7 @@ def setUp(self) -> None: class TestCaseDecoderDecompressDefaultQuery(TestCaseDecoderBase): """ - Tests encoding/decoding methods against uncompressed IR stream with the - default empty query. + Tests encoding/decoding methods against uncompressed IR stream with the default empty query. """ # override @@ -263,8 +260,7 @@ def setUp(self) -> None: class TestCaseDecoderDecompressZstdDefaultQuery(TestCaseDecoderBase): """ - Tests encoding/decoding methods against zstd compressed IR stream with the - default empty query. + Tests encoding/decoding methods against zstd compressed IR stream with the default empty query. """ # override @@ -300,8 +296,8 @@ def _generate_random_query( class TestCaseDecoderTimeRangeQuery(TestCaseDecoderTimeRangeQueryBase): """ - Tests encoding/decoding methods against uncompressed IR stream with the - query that specifies a search timestamp. + Tests encoding/decoding methods against uncompressed IR stream with the query that specifies a + search timestamp. """ # override @@ -314,8 +310,8 @@ def setUp(self) -> None: class TestCaseDecoderTimeRangeQueryZstd(TestCaseDecoderTimeRangeQueryBase): """ - Tests encoding/decoding methods against zstd compressed IR stream with the - query that specifies a search timestamp. + Tests encoding/decoding methods against zstd compressed IR stream with the query that specifies + a search timestamp. """ # override @@ -345,8 +341,8 @@ def _generate_random_query( class TestCaseDecoderWildcardQuery(TestCaseDecoderWildcardQueryBase): """ - Tests encoding/decoding methods against uncompressed IR stream with the - query that specifies wildcard queries. + Tests encoding/decoding methods against uncompressed IR stream with the query that specifies + wildcard queries. """ # override @@ -359,8 +355,8 @@ def setUp(self) -> None: class TestCaseDecoderWildcardQueryZstd(TestCaseDecoderWildcardQueryBase): """ - Tests encoding/decoding methods against zstd compressed IR stream with the - query that specifies a wildcard queries. + Tests encoding/decoding methods against zstd compressed IR stream with the query that specifies + a wildcard queries. """ # override @@ -400,8 +396,8 @@ def _generate_random_query( class TestCaseDecoderTimeRangeWildcardQuery(TestCaseDecoderTimeRangeWildcardQueryBase): """ - Tests encoding/decoding methods against uncompressed IR stream with the - query that specifies both search time range and wildcard queries. + Tests encoding/decoding methods against uncompressed IR stream with the query that specifies + both search time range and wildcard queries. """ # override @@ -414,8 +410,8 @@ def setUp(self) -> None: class TestCaseDecoderTimeRangeWildcardQueryZstd(TestCaseDecoderTimeRangeWildcardQueryBase): """ - Tests encoding/decoding methods against zstd compressed IR stream with the - query that specifies both search time range and wildcard queries. + Tests encoding/decoding methods against zstd compressed IR stream with the query that specifies + both search time range and wildcard queries. """ # override diff --git a/tests/test_ir/test_decoder_buffer.py b/tests/test_ir/test_decoder_buffer.py index ff234e4a..84c82a65 100644 --- a/tests/test_ir/test_decoder_buffer.py +++ b/tests/test_ir/test_decoder_buffer.py @@ -57,8 +57,7 @@ def __launch_test(self, buffer_capacity: Optional[int]) -> None: Tests the DecoderBuffer by streaming the files inside `test_src_dir`. :param self - :param buffer_capacity: The buffer capacity used to initialize the - decoder buffer. + :param buffer_capacity: The buffer capacity used to initialize the decoder buffer. """ current_dir: Path = Path(__file__).resolve().parent test_src_dir: Path = current_dir / TestCaseDecoderBuffer.input_src_dir diff --git a/tests/test_ir/test_encoder.py b/tests/test_ir/test_encoder.py index a92d8559..d1badfaf 100644 --- a/tests/test_ir/test_encoder.py +++ b/tests/test_ir/test_encoder.py @@ -26,9 +26,8 @@ def test_init(self) -> None: def test_encoding_methods_consistency(self) -> None: """ - This test checks if the result of encode_message_and_timestamp_delta is - consistent with the combination of encode_message and - encode_timestamp_delta. + This test checks if the result of encode_message_and_timestamp_delta is consistent with the + combination of encode_message and encode_timestamp_delta. """ timestamp_delta: int = -3190 log_message: str = "This is a test message: Do NOT Reply!" diff --git a/tests/test_ir/test_log_event.py b/tests/test_ir/test_log_event.py index 87dc65b2..fc3075b6 100644 --- a/tests/test_ir/test_log_event.py +++ b/tests/test_ir/test_log_event.py @@ -59,8 +59,7 @@ def test_formatted_message(self) -> None: """ Test the reconstruction of the raw message. - In particular, it checks if the timestamp is properly formatted with the - expected tzinfo + In particular, it checks if the timestamp is properly formatted with the expected tzinfo """ log_message: str = " This is a test log message" timestamp: int = 932724000000 @@ -112,9 +111,8 @@ def test_pickle(self) -> None: """ Test the reconstruction of LogEvent object from pickling data. - For unpickled LogEvent object, even though the metadata is set to None, - it should still format the timestamp with the original tz before - pickling + For unpickled LogEvent object, even though the metadata is set to None, it should still + format the timestamp with the original tz before pickling """ log_message: str = " This is a test log message" timestamp: int = 932724000000 diff --git a/tests/test_ir/test_query.py b/tests/test_ir/test_query.py index 6be51f38..cf752deb 100644 --- a/tests/test_ir/test_query.py +++ b/tests/test_ir/test_query.py @@ -64,8 +64,7 @@ class TestCaseQuery(TestCLPBase): def test_init_search_time(self) -> None: """ - Test the construction of Query object with the different search time - range. + Test the construction of Query object with the different search time range. """ query: Query search_time_lower_bound: int diff --git a/tests/test_ir/test_query_builder.py b/tests/test_ir/test_query_builder.py index f6ddf365..f9a7beb7 100644 --- a/tests/test_ir/test_query_builder.py +++ b/tests/test_ir/test_query_builder.py @@ -226,8 +226,8 @@ def test_exception(self) -> None: def test_deprecated(self) -> None: """ - Tests deprecated methods to ensure they are still functionally correct, - and the deprecation warnings are properly captured. + Tests deprecated methods to ensure they are still functionally correct, and the deprecation + warnings are properly captured. """ query_builder: QueryBuilder = QueryBuilder() wildcard_query_strings: List[str] = ["aaa", "bbb", "ccc", "ddd"] diff --git a/tests/test_ir/test_readers.py b/tests/test_ir/test_readers.py index 9c6e556f..27a8e803 100644 --- a/tests/test_ir/test_readers.py +++ b/tests/test_ir/test_readers.py @@ -97,8 +97,8 @@ def setUp(self) -> None: class TestCaseReaderTimeRangeQuery(TestCaseReaderTimeRangeQueryBase): """ - Tests stream reader against uncompressed IR stream with the query that - specifies a search timestamp. + Tests stream reader against uncompressed IR stream with the query that specifies a search + timestamp. """ # override @@ -111,8 +111,8 @@ def setUp(self) -> None: class TestCaseReaderTimeRangeQueryZstd(TestCaseReaderTimeRangeQueryBase): """ - Tests stream reader against zstd compressed IR stream with the query that - specifies a search timestamp. + Tests stream reader against zstd compressed IR stream with the query that specifies a search + timestamp. """ # override @@ -125,8 +125,8 @@ def setUp(self) -> None: class TestCaseReaderWildcardQuery(TestCaseReaderWildcardQueryBase): """ - Tests stream reader against uncompressed IR stream with the query that - specifies wildcard queries. + Tests stream reader against uncompressed IR stream with the query that specifies wildcard + queries. """ # override @@ -139,8 +139,8 @@ def setUp(self) -> None: class TestCaseReaderWildcardQueryZstd(TestCaseReaderWildcardQueryBase): """ - Tests stream reader against zstd compressed IR stream with the query that - specifies a wildcard queries. + Tests stream reader against zstd compressed IR stream with the query that specifies a wildcard + queries. """ # override @@ -153,8 +153,8 @@ def setUp(self) -> None: class TestCaseReaderTimeRangeWildcardQuery(TestCaseReaderTimeRangeWildcardQueryBase): """ - Tests stream reader against uncompressed IR stream with the query that - specifies both search time range and wildcard queries. + Tests stream reader against uncompressed IR stream with the query that specifies both search + time range and wildcard queries. """ # override @@ -167,8 +167,8 @@ def setUp(self) -> None: class TestCaseReaderTimeRangeWildcardQueryZstd(TestCaseReaderTimeRangeWildcardQueryBase): """ - Tests stream reader against zstd compressed IR stream with the query that - specifies both search time range and wildcard queries. + Tests stream reader against zstd compressed IR stream with the query that specifies both search + time range and wildcard queries. """ # override @@ -188,8 +188,7 @@ class TestIncompleteIRStream(TestCLPBase): def test_incomplete_ir_stream_error(self) -> None: """ - Tests the reader against an incomplete IR file with - `allow_incomplete_stream` disabled. + Tests the reader against an incomplete IR file with `allow_incomplete_stream` disabled. """ incomplete_stream_error_captured: bool = False other_exception_captured: bool = False @@ -210,8 +209,7 @@ def test_incomplete_ir_stream_error(self) -> None: def test_allow_incomplete_ir_stream_error(self) -> None: """ - Tests the reader against an incomplete IR file with - `allow_incomplete_stream` enabled. + Tests the reader against an incomplete IR file with `allow_incomplete_stream` enabled. """ incomplete_stream_error_captured: bool = False other_exception_captured: bool = False diff --git a/tests/test_ir/test_utils.py b/tests/test_ir/test_utils.py index 5cf2d21f..19763361 100644 --- a/tests/test_ir/test_utils.py +++ b/tests/test_ir/test_utils.py @@ -69,8 +69,7 @@ def _check_metadata( :param expected_ref_timestamp: Expected reference timestamp. :param expected_timestamp_format: Expected timestamp format. :param expected_timezone_id: Expected timezone ID. - :param extra_test_info: Extra test information appended to the assert - message. + :param extra_test_info: Extra test information appended to the assert message. """ ref_timestamp: int = metadata.get_ref_timestamp() timestamp_format: str = metadata.get_timestamp_format() @@ -120,8 +119,7 @@ def _check_log_event( :param expected_log_message: Expected log message. :param expected_timestamp: Expected timestamp. :param expected_idx: Expected log event index. - :param extra_test_info: Extra test information appended to the assert - message. + :param extra_test_info: Extra test information appended to the assert message. """ log_message: str = log_event.get_log_message() timestamp: int = log_event.get_timestamp() @@ -144,8 +142,7 @@ def _check_wildcard_query( self, wildcard_query: WildcardQuery, ref_wildcard_string: str, ref_is_case_sensitive: bool ) -> None: """ - Given a WildcardQuery object, check if the stored data matches the input - reference. + Given a WildcardQuery object, check if the stored data matches the input reference. :param wildcard_query: Input WildcardQuery object. :param ref_wildcard_string: Reference wildcard string. @@ -173,15 +170,13 @@ def _check_query( ref_search_time_termination_margin: int, ) -> None: """ - Given a Query object, check if the stored data matches the input - references. + Given a Query object, check if the stored data matches the input references. :param query: Input Query object to validate. :param ref_search_time_lower_bound: Reference search time lower bound. :param ref_search_time_upper_bound: Reference search time upper bound. :param ref_wildcard_queries: Reference wildcard query list. - :param ref_search_time_termination_margin: Reference search time - termination margin. + :param ref_search_time_termination_margin: Reference search time termination margin. """ search_time_lower_bound: int = query.get_search_time_lower_bound() search_time_upper_bound: int = query.get_search_time_upper_bound() @@ -228,8 +223,7 @@ def _check_query( class LogGenerator: """ - Generates random logs or wildcard queries from a list of log types and - dictionary words. + Generates random logs or wildcard queries from a list of log types and dictionary words. """ log_type_list: List[str] = [ @@ -303,11 +297,10 @@ class LogGenerator: @staticmethod def generate_random_logs(num_log_events: int) -> Tuple[Metadata, List[LogEvent]]: """ - Generates logs randomly by using log types specified in `log_type_list`. - Each log type contains placeholders, and each placeholder will be - randomly replaced by randomly generated integers, randomly generated - floating point numbers, and randomly selected dictionary words according - to the type. + Generates logs randomly by using log types specified in `log_type_list`. Each log type + contains placeholders, and each placeholder will be randomly replaced by randomly generated + integers, randomly generated floating point numbers, and randomly selected dictionary words + according to the type. :param num_log_events: Number of log events to generate. :return: A tuple containing the generated log events and the metadata.