memory\!, working on logging!

v1
Brett 2023-07-20 21:44:52 -04:00
parent a1331db389
commit 7033474455
7 changed files with 140 additions and 39 deletions

View File

@ -54,7 +54,7 @@ namespace blt::profiling {
profile getProfile(const std::string& profileName); profile getProfile(const std::string& profileName);
void printProfile( void printProfile(
const std::string& profileName, logging::LOG_LEVEL loggingLevel = logging::BLT_NONE, const std::string& profileName, logging::LogLevel loggingLevel = logging::LogLevel::NONE,
bool averageHistory = false bool averageHistory = false
); );

View File

@ -13,13 +13,21 @@
namespace blt::logging { namespace blt::logging {
enum LOG_LEVEL { enum class LogLevel {
// low level
TRACE0, TRACE1, TRACE2, TRACE3,
// normal // normal
BLT_TRACE = 0, BLT_DEBUG = 1, BLT_INFO = 2, TRACE, DEBUG, INFO,
WARN,
// errors // errors
BLT_WARN = 3, BLT_ERROR = 4, BLT_FATAL = 5, ERROR, FATAL,
// default // default
BLT_NONE = 6 NONE
};
class ILogHandler {
public:
virtual void log(std::string message, LogLevel level) = 0;
}; };
struct LOG_PROPERTIES { struct LOG_PROPERTIES {
@ -31,7 +39,7 @@ namespace blt::logging {
// print the whole path or just the file name? // print the whole path or just the file name?
bool m_logFullPath = false; bool m_logFullPath = false;
const char* m_directory = "./"; const char* m_directory = "./";
LOG_LEVEL minLevel = BLT_TRACE; LogLevel minLevel = LogLevel::TRACE;
explicit constexpr LOG_PROPERTIES( explicit constexpr LOG_PROPERTIES(
bool useColor, bool logToConsole, bool logToFile, const char* directory bool useColor, bool logToConsole, bool logToFile, const char* directory
@ -43,7 +51,7 @@ namespace blt::logging {
}; };
struct logger { struct logger {
LOG_LEVEL level; LogLevel level;
void log_internal(const std::string& str) const; void log_internal(const std::string& str) const;
// evil hack, todo: better way // evil hack, todo: better way
@ -64,18 +72,18 @@ namespace blt::logging {
static void flush_all(); static void flush_all();
}; };
static logger std_out{BLT_NONE}; static logger std_out{LogLevel::NONE};
static logger trace{BLT_TRACE}; static logger trace{LogLevel::TRACE};
static logger debug{BLT_DEBUG}; static logger debug{LogLevel::DEBUG};
static logger info{BLT_INFO}; static logger info{LogLevel::INFO};
static logger warn{BLT_WARN}; static logger warn{LogLevel::WARN};
static logger error{BLT_ERROR}; static logger error{LogLevel::ERROR};
static logger fatal{BLT_FATAL}; static logger fatal{LogLevel::FATAL};
static inline logger& getLoggerFromLevel(LOG_LEVEL level) { static inline logger& getLoggerFromLevel(LogLevel level) {
static logger loggerLevelDecode[7]{trace, debug, info, warn, error, fatal, std_out}; static logger loggerLevelDecode[11]{trace, trace, trace, trace, trace, debug, info, warn, error, fatal, std_out};
return loggerLevelDecode[level]; return loggerLevelDecode[(int)level];
} }
static inline logger& operator<<(logger& out, const std::string& str) { static inline logger& operator<<(logger& out, const std::string& str) {
@ -92,7 +100,7 @@ namespace blt::logging {
void init(LOG_PROPERTIES properties); void init(LOG_PROPERTIES properties);
void log_internal( void log_internal(
const std::string& format, LOG_LEVEL level, const char* file, int currentLine, const std::string& format, LogLevel level, const char* file, int currentLine,
int auto_line, ... int auto_line, ...
); );
@ -111,7 +119,7 @@ namespace blt::logging {
*/ */
template<typename T, typename std::enable_if<std::is_arithmetic<T>::value>::type* = nullptr> template<typename T, typename std::enable_if<std::is_arithmetic<T>::value>::type* = nullptr>
inline void log_internal( inline void log_internal(
T t, LOG_LEVEL level, const char* file, int currentLine, int auto_line T t, LogLevel level, const char* file, int currentLine, int auto_line
) { ) {
log_internal(std::to_string(t), level, file, currentLine, auto_line); log_internal(std::to_string(t), level, file, currentLine, auto_line);
} }
@ -133,12 +141,12 @@ namespace blt::logging {
#define BLT_FATAL(format, ...) #define BLT_FATAL(format, ...)
#else #else
#ifndef BLT_DISABLE_LOGGING #ifndef BLT_DISABLE_LOGGING
#define BLT_TRACE(format, ...) log_internal(format, blt::logging::BLT_TRACE, __FILE__, __LINE__, true, ##__VA_ARGS__) #define BLT_TRACE(format, ...) log_internal(format, blt::logging::LogLevel::TRACE, __FILE__, __LINE__, true, ##__VA_ARGS__)
#define BLT_DEBUG(format, ...) log_internal(format, blt::logging::BLT_DEBUG, __FILE__, __LINE__, true, ##__VA_ARGS__) #define BLT_DEBUG(format, ...) log_internal(format, blt::logging::LogLevel::DEBUG, __FILE__, __LINE__, true, ##__VA_ARGS__)
#define BLT_INFO(format, ...) log_internal(format, blt::logging::BLT_INFO, __FILE__, __LINE__, true, ##__VA_ARGS__) #define BLT_INFO(format, ...) log_internal(format, blt::logging::LogLevel::INFO, __FILE__, __LINE__, true, ##__VA_ARGS__)
#define BLT_WARN(format, ...) log_internal(format, blt::logging::BLT_WARN, __FILE__, __LINE__, true, ##__VA_ARGS__) #define BLT_WARN(format, ...) log_internal(format, blt::logging::LogLevel::WARN, __FILE__, __LINE__, true, ##__VA_ARGS__)
#define BLT_ERROR(format, ...) log_internal(format, blt::logging::BLT_ERROR, __FILE__, __LINE__, true, ##__VA_ARGS__) #define BLT_ERROR(format, ...) log_internal(format, blt::logging::LogLevel::ERROR, __FILE__, __LINE__, true, ##__VA_ARGS__)
#define BLT_FATAL(format, ...) log_internal(format, blt::logging::BLT_FATAL, __FILE__, __LINE__, true, ##__VA_ARGS__) #define BLT_FATAL(format, ...) log_internal(format, blt::logging::LogLevel::FATAL, __FILE__, __LINE__, true, ##__VA_ARGS__)
#endif #endif
#endif #endif

View File

@ -7,7 +7,53 @@
#ifndef BLT_TESTS_MEMORY_H #ifndef BLT_TESTS_MEMORY_H
#define BLT_TESTS_MEMORY_H #define BLT_TESTS_MEMORY_H
#include <initializer_list>
#include <iterator>
namespace blt { namespace blt {
template<typename V>
struct ptr_iterator {
public:
using iterator_category = std::random_access_iterator_tag;
using difference_type = std::ptrdiff_t;
using value_type = V;
using pointer = value_type*;
using reference = value_type&;
explicit ptr_iterator(V* v): _v(v) {}
reference operator*() const { return *_v; }
pointer operator->() { return _v; }
ptr_iterator& operator++() {
_v++;
return *this;
}
ptr_iterator& operator--() {
_v--;
return *this;
}
ptr_iterator operator++(int){
auto tmp = *this;
++(*this);
return tmp;
}
ptr_iterator operator--(int){
auto tmp = *this;
--(*this);
return tmp;
}
friend bool operator==(const ptr_iterator& a, const ptr_iterator& b) {
return a._v == b._v;
}
friend bool operator!=(const ptr_iterator& a, const ptr_iterator& b) {
return a._v != b._v;
}
private:
V* _v;
};
/** /**
* Creates an encapsulation of a T array which will be automatically deleted when this object goes out of scope. * Creates an encapsulation of a T array which will be automatically deleted when this object goes out of scope.
* This is a simple buffer meant to be used only inside of a function and not moved around, with a few minor exceptions. * This is a simple buffer meant to be used only inside of a function and not moved around, with a few minor exceptions.
@ -77,6 +123,51 @@ namespace blt {
~nullptr_initializer() = default; ~nullptr_initializer() = default;
}; };
/**
* Creates a hash-map like association between an enum key and any arbitrary value.
* The storage is backed by a contiguous array for faster access.
* @tparam K enum value
* @tparam V associated value
*/
template<typename K, typename V>
class enum_storage {
private:
V* _values;
size_t _size = 0;
public:
enum_storage(std::initializer_list<std::pair<K, V>> init){
for (auto& i : init)
_size = std::max((size_t)i, _size);
_values = new V[_size];
}
inline V& operator[](size_t index){
return _values[index];
}
inline const V& operator[](size_t index) const {
return _values[index];
}
[[nodiscard]] inline size_t size() const {
return _size;
}
ptr_iterator<V> begin(){
return ptr_iterator{_values};
}
ptr_iterator<V> end(){
return ptr_iterator{&_values[_size]};
}
~enum_storage(){
delete[] _values;
}
};
} }
#endif //BLT_TESTS_MEMORY_H #endif //BLT_TESTS_MEMORY_H

View File

@ -30,7 +30,7 @@ namespace blt::profiling {
difference(difference), name(std::move(name)), total(total) {} difference(difference), name(std::move(name)), total(total) {}
}; };
inline void println(const std::vector<std::string>&& lines, logging::LOG_LEVEL level) { inline void println(const std::vector<std::string>&& lines, logging::LogLevel level) {
auto& logger = logging::getLoggerFromLevel(level); auto& logger = logging::getLoggerFromLevel(level);
for (const auto& line : lines) for (const auto& line : lines)
logger << line << "\n"; logger << line << "\n";
@ -104,7 +104,7 @@ namespace blt::profiling {
} }
void printProfile( void printProfile(
const std::string& profileName, logging::LOG_LEVEL loggingLevel, bool averageHistory const std::string& profileName, logging::LogLevel loggingLevel, bool averageHistory
) { ) {
auto& profile = profiles[profileName]; auto& profile = profiles[profileName];
const auto& intervals = profile.intervals; const auto& intervals = profile.intervals;

View File

@ -22,6 +22,8 @@
// https://publications.gbdirect.co.uk//c_book/chapter9/stdarg.html // https://publications.gbdirect.co.uk//c_book/chapter9/stdarg.html
// https://cplusplus.com/reference/cstdio/printf/ // https://cplusplus.com/reference/cstdio/printf/
#include <blt/std/memory.h>
namespace blt::logging { namespace blt::logging {
@ -120,7 +122,7 @@ namespace blt::logging {
return final; return final;
} }
inline void log(const std::string& str, bool hasEndingLinefeed, LOG_LEVEL level, const char* file, int currentLine, int auto_line){ inline void log(const std::string& str, bool hasEndingLinefeed, LogLevel level, const char* file, int currentLine, int auto_line){
if (level < BLT_LOGGING_PROPERTIES.minLevel) if (level < BLT_LOGGING_PROPERTIES.minLevel)
return; return;
std::string outputString = system::getTimeStringLog(); std::string outputString = system::getTimeStringLog();
@ -133,13 +135,13 @@ namespace blt::logging {
outputString += "] "; outputString += "] ";
} }
outputString += levelNames[level]; outputString += levelNames[(int)level];
outputString += str; outputString += str;
std::string fileString = outputString; std::string fileString = outputString;
if (BLT_LOGGING_PROPERTIES.m_useColor) { if (BLT_LOGGING_PROPERTIES.m_useColor) {
outputString = levelColors[level] + outputString; outputString = levelColors[(int)level] + outputString;
outputString += "\033[0m"; outputString += "\033[0m";
} }
@ -149,7 +151,7 @@ namespace blt::logging {
} }
if (BLT_LOGGING_PROPERTIES.m_logToConsole) { if (BLT_LOGGING_PROPERTIES.m_logToConsole) {
if (level > BLT_WARN) if (level > LogLevel::WARN)
std::cerr << outputString; std::cerr << outputString;
else else
std::cout << outputString; std::cout << outputString;
@ -160,7 +162,7 @@ namespace blt::logging {
} }
} }
void log_internal(const std::string& format, LOG_LEVEL level, const char* file, int currentLine, int auto_line, ...) { void log_internal(const std::string& format, LogLevel level, const char* file, int currentLine, int auto_line, ...) {
va_list args; va_list args;
va_start(args, auto_line); va_start(args, auto_line);
@ -181,7 +183,7 @@ namespace blt::logging {
} }
// stores an association between thread -> log level -> current line buffer // stores an association between thread -> log level -> current line buffer
std::unordered_map<std::thread::id, std::unordered_map<LOG_LEVEL, std::string>> thread_local_strings; std::unordered_map<std::thread::id, std::unordered_map<LogLevel, std::string>> thread_local_strings;
void logger::log_internal(const std::string& str) const { void logger::log_internal(const std::string& str) const {
auto id = std::this_thread::get_id(); auto id = std::this_thread::get_id();
@ -191,7 +193,7 @@ namespace blt::logging {
if (blt::string::contains(str, "\n")){ if (blt::string::contains(str, "\n")){
// make sure new lines are properly formatted to prevent danging lines. Ie "[trace]: .... [debug]: ...." // make sure new lines are properly formatted to prevent danging lines. Ie "[trace]: .... [debug]: ...."
bool hasEndingLinefeed = str[str.length()-1] == '\n'; bool hasEndingLinefeed = str[str.length()-1] == '\n';
if (level == BLT_NONE) { if (level == LogLevel::NONE) {
std::cout << th_str; std::cout << th_str;
} else } else
logging::log(th_str, false, level, "", -1, !hasEndingLinefeed); logging::log(th_str, false, level, "", -1, !hasEndingLinefeed);
@ -201,7 +203,7 @@ namespace blt::logging {
} }
} }
void flushLogger_internal(std::thread::id id, LOG_LEVEL level){ void flushLogger_internal(std::thread::id id, LogLevel level){
auto th_str = thread_local_strings[id][level]; auto th_str = thread_local_strings[id][level];
if (th_str.empty()) if (th_str.empty())
return; return;

View File

@ -38,7 +38,7 @@ static void runProfilingAndTableTests() {
BLT_END_INTERVAL("Help", "UnderSet" + std::to_string(i)); BLT_END_INTERVAL("Help", "UnderSet" + std::to_string(i));
} }
BLT_PRINT_PROFILE("Help", blt::logging::LOG_LEVEL::BLT_TRACE); BLT_PRINT_PROFILE("Help", blt::logging::LogLevel::TRACE);
BLT_TRACE(""); BLT_TRACE("");
blt::string::TableFormatter formatter; blt::string::TableFormatter formatter;

View File

@ -140,9 +140,9 @@ static inline void test_queues() {
fill_queues(); fill_queues();
random_access(); random_access();
BLT_PRINT_PROFILE("Insert", blt::logging::LOG_LEVEL::BLT_INFO, true); BLT_PRINT_PROFILE("Insert", blt::logging::LogLevel::INFO, true);
BLT_PRINT_PROFILE("Access", blt::logging::LOG_LEVEL::BLT_INFO, true); BLT_PRINT_PROFILE("Access", blt::logging::LogLevel::INFO, true);
BLT_PRINT_PROFILE("Random", blt::logging::LOG_LEVEL::BLT_INFO, true); BLT_PRINT_PROFILE("Random", blt::logging::LogLevel::INFO, true);
} }
#endif //BLT_TESTS_QUEUE_TESTS_H #endif //BLT_TESTS_QUEUE_TESTS_H