/* igraph library. Copyright (C) 2009-2025 The igraph development team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef IGRAPH_PROGRESS_H #define IGRAPH_PROGRESS_H #include "igraph_decls.h" #include "igraph_error.h" #include "igraph_types.h" IGRAPH_BEGIN_C_DECLS /** * \section about_progress_handlers About progress handlers * * It is often useful to report the progress of some long * calculation, to allow the user to follow the computation and * guess the total running time. A couple of igraph functions * support this at the time of writing, hopefully more will support it * in the future. * * * * To see the progress of a computation, the user has to install a * progress handler, as there is none installed by default. * If an igraph function supports progress reporting, then it * calls the installed progress handler periodically, and passes a * percentage value to it, the percentage of computation already * performed. To install a progress handler, you need to call * \ref igraph_set_progress_handler(). Currently there is a single * pre-defined progress handler, called \ref * igraph_progress_handler_stderr(). * */ /** * \section writing_progress_handlers Writing progress handlers * * * To write a new progress handler, one needs to create a function of * type \ref igraph_progress_handler_t. The new progress handler * can then be installed with the \ref igraph_set_progress_handler() * function. * * * * One can assume that the first progress handler call from a * calculation will be call with zero as the \p percentage argument, * and the last call from a function will have 100 as the \p * percentage argument. Note, however, that if an error happens in the * middle of a computation, then the 100 percent call might be * omitted. * */ /** * \section igraph_functions_with_progress Writing igraph functions with progress reporting * * * If you want to write a function that uses igraph and supports * progress reporting, you need to include \ref igraph_progress() * calls in your function, usually via the \ref IGRAPH_PROGRESS() * macro. * * * * It is good practice to always include a call to \ref * igraph_progress() with a zero \p percentage argument, before the * computation; and another call with 100 \p percentage value * after the computation is completed. * * * * It is also good practice \em not to call \ref igraph_progress() too * often, as this would slow down the computation. It might not be * worth to support progress reporting in functions with linear or * log-linear time complexity, as these are fast, even with a large * amount of data. For functions with quadratic or higher time * complexity make sure that the time complexity of the progress * reporting is constant or at least linear. In practice this means * having at most O(n) progress checks and at most 100 * \ref igraph_progress() calls. * */ /** * \section progress_and_threads Multi-threaded programs * * * In multi-threaded programs, each thread has its own progress * handler, if thread-local storage is supported and igraph is * thread-safe. See the \ref IGRAPH_THREAD_SAFE macro for checking * whether an igraph build is thread-safe. * */ /* -------------------------------------------------- */ /* Progress handlers */ /* -------------------------------------------------- */ /** * \typedef igraph_progress_handler_t * \brief Type of progress handler functions * * This is the type of the igraph progress handler functions. * There is currently one such predefined function, * \ref igraph_progress_handler_stderr(), but the user can * write and set up more sophisticated ones. * \param message A string describing the function or algorithm * that is reporting the progress. Current igraph functions * always use the name \p message argument if reporting from the * same function. * \param percent Numeric, the percentage that was completed by the * algorithm or function. * \param data User-defined data. Current igraph functions that * report progress pass a null pointer here. Users can * write their own progress handlers and functions with progress * reporting, and then pass some meaningfull context here. * \return If the return value of the progress handler is not * \c IGRAPH_SUCCESS, then \ref igraph_progress() returns the * error code from the progress handler intact. The \ref IGRAPH_PROGRESS() * macro also frees all allocated memory. */ typedef igraph_error_t igraph_progress_handler_t(const char *message, igraph_real_t percent, void *data); IGRAPH_EXPORT extern igraph_progress_handler_t igraph_progress_handler_stderr; IGRAPH_EXPORT igraph_progress_handler_t * igraph_set_progress_handler(igraph_progress_handler_t new_handler); IGRAPH_EXPORT igraph_error_t igraph_progress(const char *message, igraph_real_t percent, void *data); IGRAPH_EXPORT igraph_error_t igraph_progressf(const char *message, igraph_real_t percent, void *data, ...); /** * \define IGRAPH_PROGRESS * \brief Report the progress of a calculation from an igraph function (macro variant). * * The standard way to report progress from an igraph function * \param message A string, a textual message that references the * calculation under progress. * \param percent Numeric scalar, the percentage that is complete. * \param data User-defined data, this can be used in user-defined * progress handler functions, from user-written igraph functions. * \return If the return value of the progress handler is not * \c IGRAPH_SUCCESS, then \ref igraph_progress() returns the * error code from the progress handler intact. The \ref IGRAPH_PROGRESS() * macro also frees all allocated memory. */ #define IGRAPH_PROGRESS(message, percent, data) \ do { \ IGRAPH_CHECK(igraph_progress((message), (percent), (data))); \ } while (0) /** * \define IGRAPH_PROGRESSF * \brief Report the progress of a calculation from an igraph function, printf-like (macro variant). * * This is the more flexible version of \ref IGRAPH_PROGRESS(), * having a printf-like syntax. As this macro takes variable * number of arguments, they must be all supplied as a single * argument, enclosed in parentheses. \ref igraph_progressf() is then * called with the given arguments. * * \param args The arguments to pass to \ref igraph_progressf(). * \return If the progress handler returns with a value other than * \c IGRAPH_SUCCESS, then the function that called this * macro returns as well, with the same error code, after * cleaning up all allocated memory as needed. */ #define IGRAPH_PROGRESSF(args) \ do { \ IGRAPH_CHECK(igraph_progressf args); \ } while (0) IGRAPH_END_C_DECLS #endif