1.0.0-dev #4
| @@ -15,27 +15,27 @@ extern "C" { | ||||
|  | ||||
| // 默认日志器宏 | ||||
| #define Log_fatal(format, ...)                                                 \ | ||||
|     _log_fatal(NULL, __FILE__, __LINE__, format, ##__VA_ARGS__) | ||||
|     logMessage(NULL, LOG_FATAL, __FILE__, __LINE__, format, ##__VA_ARGS__) | ||||
| #define Log_error(format, ...)                                                 \ | ||||
|     _log_error(NULL, __FILE__, __LINE__, format, ##__VA_ARGS__) | ||||
|     logMessage(NULL, LOG_ERROR, __FILE__, __LINE__, format, ##__VA_ARGS__) | ||||
| #define Log_warning(format, ...)                                               \ | ||||
|     _log_warning(NULL, __FILE__, __LINE__, format, ##__VA_ARGS__) | ||||
|     logMessage(NULL, LOG_WARNING, __FILE__, __LINE__, format, ##__VA_ARGS__) | ||||
| #define Log_info(format, ...)                                                  \ | ||||
|     _log_info(NULL, __FILE__, __LINE__, format, ##__VA_ARGS__) | ||||
|     logMessage(NULL, LOG_INFO, __FILE__, __LINE__, format, ##__VA_ARGS__) | ||||
| #define Log_debug(format, ...)                                                 \ | ||||
|     _log_debug(NULL, __FILE__, __LINE__, format, ##__VA_ARGS__) | ||||
|     logMessage(NULL, LOG_DEBUG, __FILE__, __LINE__, format, ##__VA_ARGS__) | ||||
|  | ||||
| // 日志器宏 | ||||
| #define log_fatal(logger, format, ...)                                         \ | ||||
|     _log_fatal(logger, __FILE__, __LINE__, format, ##__VA_ARGS__) | ||||
|     logMessage(logger, LOG_FATAL, __FILE__, __LINE__, format, ##__VA_ARGS__) | ||||
| #define log_error(logger, format, ...)                                         \ | ||||
|     _log_error(logger, __FILE__, __LINE__, format, ##__VA_ARGS__) | ||||
|     logMessage(logger, LOG_ERROR, __FILE__, __LINE__, format, ##__VA_ARGS__) | ||||
| #define log_warning(logger, format, ...)                                       \ | ||||
|     _log_warning(logger, __FILE__, __LINE__, format, ##__VA_ARGS__) | ||||
|     logMessage(logger, LOG_WARNING, __FILE__, __LINE__, format, ##__VA_ARGS__) | ||||
| #define log_info(logger, format, ...)                                          \ | ||||
|     _log_info(logger, __FILE__, __LINE__, format, ##__VA_ARGS__) | ||||
|     logMessage(logger, LOG_INFO, __FILE__, __LINE__, format, ##__VA_ARGS__) | ||||
| #define log_debug(logger, format, ...)                                         \ | ||||
|     _log_debug(logger, __FILE__, __LINE__, format, ##__VA_ARGS__) | ||||
|     logMessage(logger, LOG_DEBUG, __FILE__, __LINE__, format, ##__VA_ARGS__) | ||||
|  | ||||
| typedef struct Logger { | ||||
|     log_level    level; | ||||
| @@ -47,24 +47,19 @@ typedef struct Logger { | ||||
| bool addHandler(Logger *logger, log_Handler *handler); | ||||
| bool addFilter(Logger *logger, log_filter *filter); | ||||
|  | ||||
| void _log_fatal( | ||||
|     Logger *logger, const char *file, int line, const char *format, ...); | ||||
| void _log_error( | ||||
|     Logger *logger, const char *file, int line, const char *format, ...); | ||||
| void _log_warning( | ||||
|     Logger *logger, const char *file, int line, const char *format, ...); | ||||
| void _log_info( | ||||
|     Logger *logger, const char *file, int line, const char *format, ...); | ||||
| void _log_debug( | ||||
|     Logger *logger, const char *file, int line, const char *format, ...); | ||||
| void logMessage(Logger     *logger, | ||||
|                 log_level   level, | ||||
|                 const char *file, | ||||
|                 int         line, | ||||
|                 const char *message, | ||||
|                 ...); | ||||
|  | ||||
| /** | ||||
|  * @brief 初始化默认日志对象 | ||||
|  * @param name 日志名称 | ||||
|  * @param level 日志等级 | ||||
|  * @brief 创建一个日志句柄对象 | ||||
|  * @param name 日志器名称 | ||||
|  * @return 日志句柄对象 | ||||
|  */ | ||||
| void initDefaultLogger(const char *name, log_level level); | ||||
|  | ||||
| Logger *newLogger(const char *name); | ||||
| /** | ||||
|  * @brief 获取默认日志对象 | ||||
|  * @return 默认日志对象 | ||||
|   | ||||
| @@ -13,6 +13,14 @@ typedef enum { | ||||
|     LOG_DEBUG, | ||||
| } log_level; | ||||
|  | ||||
| static const char *LOG_LEVEL_STR[] = { | ||||
|     "FATAL", | ||||
|     "ERROR", | ||||
|     "WARNING", | ||||
|     "INFO", | ||||
|     "DEBUG", | ||||
| }; | ||||
|  | ||||
| typedef enum { | ||||
|     L_ERROR, | ||||
|     L_OK, | ||||
|   | ||||
							
								
								
									
										229
									
								
								src/logging.c
									
									
									
									
									
								
							
							
						
						
									
										229
									
								
								src/logging.c
									
									
									
									
									
								
							| @@ -1,6 +1,7 @@ | ||||
| #include "logging.h" | ||||
| #include "logging/logging-core.h" | ||||
| #include "logging/logging-handler.h" | ||||
| #include "utils/logging-map.h" | ||||
| #include "utils/logging-utils.h" | ||||
| #include <stdbool.h> | ||||
| #include <stdio.h> | ||||
| @@ -18,7 +19,7 @@ | ||||
|  | ||||
| #define LOG_BUFFER_SIZE 4096 // 日志缓冲区大小,单个日志长度不能超过该值 | ||||
|  | ||||
| static Logger *G_LOGGER = NULL; // 全局日志对象,唯一实例 | ||||
| static Logger *ROOT_LOGGER = NULL; // 根日志对象,唯一实例 | ||||
|  | ||||
| /** | ||||
|  * @brief 为日志添加一个handler | ||||
| @@ -80,22 +81,15 @@ static void output_to_handler(Logger     *logger, | ||||
|                               char       *level, | ||||
|                               const char *color, | ||||
|                               const char *message) { | ||||
|     Logger *_logger = NULL; | ||||
|  | ||||
|     if (logger != NULL) { | ||||
|         _logger = logger; | ||||
|     } else { | ||||
|         _logger = G_LOGGER; | ||||
|     } | ||||
|  | ||||
|     char timeStr[20]; | ||||
|     getTimeStr(timeStr); | ||||
|     char logStr[LOG_BUFFER_SIZE * 2]; | ||||
|     if (_logger->handler->apply_color) { | ||||
|     if (logger->handler->apply_color) { | ||||
|         snprintf(logStr, | ||||
|                  LOG_BUFFER_SIZE * 2, | ||||
|                  "[%s]: %s %s%s%s %s\n", | ||||
|                  _logger->name, | ||||
|                  logger->name, | ||||
|                  timeStr, | ||||
|                  color, | ||||
|                  level, | ||||
| @@ -105,13 +99,13 @@ static void output_to_handler(Logger     *logger, | ||||
|         snprintf(logStr, | ||||
|                  LOG_BUFFER_SIZE * 2, | ||||
|                  "[%s]: %s %s %s\n", | ||||
|                  _logger->name, | ||||
|                  logger->name, | ||||
|                  timeStr, | ||||
|                  level, | ||||
|                  message); | ||||
|     } | ||||
|  | ||||
|     _logger->handler->output(_logger->handler, logStr); | ||||
|     logger->handler->output(logger->handler, logStr); | ||||
| } | ||||
|  | ||||
| /** | ||||
| @@ -124,174 +118,105 @@ static void output_to_handler(Logger     *logger, | ||||
|  */ | ||||
| static void | ||||
| log_cope(Logger *logger, char *level, const char *color, const char *message) { | ||||
|     Logger *_logger = NULL; | ||||
|  | ||||
|     if (logger != NULL) { | ||||
|         _logger = logger; | ||||
|     } else { | ||||
|         _logger = G_LOGGER; | ||||
|     } | ||||
|  | ||||
|     if (_logger == NULL) { | ||||
|     if (logger == NULL) { | ||||
|         return; | ||||
|     } | ||||
|     if (_logger->handler == NULL) { | ||||
|     if (logger->handler == NULL) { | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     log_filter  *it      = _logger->filter; | ||||
|     log_Handler *handler = _logger->handler; | ||||
|     log_filter  *it      = logger->filter; | ||||
|     log_Handler *handler = logger->handler; | ||||
|  | ||||
|     while (it != NULL) { | ||||
|         if (it->_dispose(it, _logger->level, message)) { | ||||
|             output_to_handler(_logger, level, color, message); | ||||
|         if (it->_dispose(it, logger->level, message)) { | ||||
|             output_to_handler(logger, level, color, message); | ||||
|             if (it->jump_out) { | ||||
|                 return; | ||||
|             } | ||||
|         } | ||||
|         it = it->next; | ||||
|     } | ||||
|     output_to_handler(_logger, level, color, message); | ||||
|     output_to_handler(logger, level, color, message); | ||||
| } | ||||
|  | ||||
| void _log_fatal( | ||||
|     Logger *logger, const char *file, int line, const char *message, ...) { | ||||
| void logMessage(Logger     *logger, | ||||
|                 log_level   level, | ||||
|                 const char *file, | ||||
|                 int         line, | ||||
|                 const char *message, | ||||
|                 ...) { | ||||
|     Logger *_logger = NULL; | ||||
|  | ||||
|     if (logger != NULL) { | ||||
|         _logger = logger; | ||||
|     if (logger == NULL) { | ||||
|         if (ROOT_LOGGER == NULL) { | ||||
|             ROOT_LOGGER = newLogger("ROOT"); // 创建根日志对象 | ||||
|         } | ||||
|         _logger = ROOT_LOGGER; | ||||
|     } else { | ||||
|         _logger = G_LOGGER; | ||||
|         _logger = logger; // 使用传入的日志对象 | ||||
|     } | ||||
|  | ||||
|     if (_logger->level >= LOG_ERROR) { | ||||
|         char    logStr[LOG_BUFFER_SIZE]; | ||||
|         char    finalLogStr[LOG_BUFFER_SIZE * 2]; | ||||
|     if (_logger->level >= level) { | ||||
|         char logStr | ||||
|             [LOG_BUFFER_SIZE]; // 定义一个缓冲区,用于存储格式化后的日志字符串 | ||||
|         char    finalLogStr[LOG_BUFFER_SIZE * | ||||
|                          2]; // 定义一个缓冲区,用于存储最终输出的日志字符串 | ||||
|         va_list args; | ||||
|         va_start(args, message); | ||||
|         vsprintf(logStr, message, args); | ||||
|         va_end(args); | ||||
|         snprintf( | ||||
|             finalLogStr, LOG_BUFFER_SIZE * 2, "[%s:%d] %s", file, line, logStr); | ||||
|         log_cope(_logger, "Fatal", RED_B, finalLogStr); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void _log_error( | ||||
|     Logger *logger, const char *file, int line, const char *message, ...) { | ||||
|     Logger *_logger = NULL; | ||||
|  | ||||
|     if (logger != NULL) { | ||||
|         _logger = logger; | ||||
|     } else { | ||||
|         _logger = G_LOGGER; | ||||
|     } | ||||
|  | ||||
|     if (_logger->level >= LOG_ERROR) { | ||||
|         char    logStr[LOG_BUFFER_SIZE]; | ||||
|         char    finalLogStr[LOG_BUFFER_SIZE * 2]; | ||||
|         va_list args; | ||||
|         va_start(args, message); | ||||
|         vsprintf(logStr, message, args); | ||||
|         va_end(args); | ||||
|         snprintf( | ||||
|             finalLogStr, LOG_BUFFER_SIZE * 2, "[%s:%d] %s", file, line, logStr); | ||||
|         log_cope(_logger, "Error", RED, finalLogStr); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void _log_warning( | ||||
|     Logger *logger, const char *file, int line, const char *message, ...) { | ||||
|     Logger *_logger = NULL; | ||||
|  | ||||
|     if (logger != NULL) { | ||||
|         _logger = logger; | ||||
|     } else { | ||||
|         _logger = G_LOGGER; | ||||
|     } | ||||
|  | ||||
|     if (_logger->level >= LOG_WARNING) { | ||||
|         char    logStr[LOG_BUFFER_SIZE]; | ||||
|         char    finalLogStr[LOG_BUFFER_SIZE * 2]; | ||||
|         va_list args; | ||||
|         va_start(args, message); | ||||
|         vsprintf(logStr, message, args); | ||||
|         va_end(args); | ||||
|         snprintf( | ||||
|             finalLogStr, LOG_BUFFER_SIZE * 2, "[%s:%d] %s", file, line, logStr); | ||||
|         log_cope(_logger, "Warning", YELLOW, finalLogStr); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void _log_info( | ||||
|     Logger *logger, const char *file, int line, const char *message, ...) { | ||||
|     Logger *_logger = NULL; | ||||
|  | ||||
|     if (logger != NULL) { | ||||
|         _logger = logger; | ||||
|     } else { | ||||
|         _logger = G_LOGGER; | ||||
|     } | ||||
|  | ||||
|     if (_logger->level >= LOG_INFO) { | ||||
|         char    logStr[LOG_BUFFER_SIZE]; | ||||
|         char    finalLogStr[LOG_BUFFER_SIZE * 2]; | ||||
|         va_list args; | ||||
|         va_start(args, message); | ||||
|         vsprintf(logStr, message, args); | ||||
|         va_end(args); | ||||
|         snprintf( | ||||
|             finalLogStr, LOG_BUFFER_SIZE * 2, "[%s:%d] %s", file, line, logStr); | ||||
|         switch (level) { | ||||
|         case LOG_DEBUG: | ||||
|             log_cope(_logger, "Debug", BLUE, finalLogStr); | ||||
|             break; | ||||
|         case LOG_INFO: | ||||
|             log_cope(_logger, "Info", GREEN, finalLogStr); | ||||
|             break; | ||||
|         case LOG_WARNING: | ||||
|             log_cope(_logger, "Warning", YELLOW, finalLogStr); | ||||
|             break; | ||||
|         case LOG_ERROR: | ||||
|             log_cope(_logger, "Error", RED, finalLogStr); | ||||
|             break; | ||||
|         case LOG_FATAL: | ||||
|             log_cope(_logger, "Fatal", RED_B, finalLogStr); | ||||
|             break; | ||||
|         default: | ||||
|             break; | ||||
|         } | ||||
| } | ||||
|  | ||||
| void _log_debug( | ||||
|     Logger *logger, const char *file, int line, const char *message, ...) { | ||||
|     Logger *_logger = NULL; | ||||
|  | ||||
|     if (logger != NULL) { | ||||
|         _logger = logger; | ||||
|     } else { | ||||
|         _logger = G_LOGGER; | ||||
|     } | ||||
|  | ||||
|     if (_logger->level >= LOG_DEBUG) { | ||||
|         char    logStr[LOG_BUFFER_SIZE]; | ||||
|         char    finalLogStr[LOG_BUFFER_SIZE * 2]; | ||||
|         va_list args; | ||||
|         va_start(args, message); | ||||
|         vsprintf(logStr, message, args); | ||||
|         va_end(args); | ||||
|         snprintf( | ||||
|             finalLogStr, LOG_BUFFER_SIZE * 2, "[%s:%d] %s", file, line, logStr); | ||||
|         log_cope(_logger, "Debug", CYAN, finalLogStr); | ||||
|     } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * @brief 初始化默认日志器 | ||||
|  * @brief 创建一个日志句柄 | ||||
|  * @param name 日志器名称 | ||||
|  * @param level 日志等级 | ||||
|  * @return 日志器对象 | ||||
|  */ | ||||
| void initDefaultLogger(const char *name, log_level level) { | ||||
|     if (G_LOGGER != NULL) { | ||||
|         G_LOGGER->name  = name; | ||||
|         G_LOGGER->level = level; | ||||
| Logger *newLogger(const char *name) { | ||||
|     Logger *logger = (Logger *)malloc(sizeof(Logger)); | ||||
|     if (logger == NULL) { | ||||
|         return NULL; | ||||
|     } | ||||
|  | ||||
|     Logger *logger  = (Logger *)malloc(sizeof(Logger)); | ||||
|  | ||||
|     logger->level   = level; | ||||
|     logger->level   = LOG_INFO; | ||||
|     logger->handler = loggingHandlerConsole(); | ||||
|     logger->name    = name; | ||||
|     logger->filter  = NULL; | ||||
|  | ||||
|     G_LOGGER        = logger; | ||||
|     return logger; | ||||
| } | ||||
|  | ||||
| Logger *getDefaultLogger(void) { return G_LOGGER; } | ||||
| Logger *getDefaultLogger(void) { | ||||
|     if (ROOT_LOGGER != NULL) { | ||||
|         return ROOT_LOGGER; | ||||
|     } | ||||
|  | ||||
|     ROOT_LOGGER = newLogger("ROOT"); | ||||
|     return ROOT_LOGGER; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * @brief 获取日志器对象 | ||||
| @@ -314,30 +239,6 @@ Logger *getLogger(const char *name, log_level level) { | ||||
|     return logger; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * @brief 销毁日志对象 | ||||
|  */ | ||||
| void destroyDefaultLogger(void) { | ||||
|     if (G_LOGGER != NULL) { | ||||
|         if (G_LOGGER->handler != NULL) { | ||||
|             G_LOGGER->handler->_free(G_LOGGER->handler); | ||||
|         } | ||||
|  | ||||
|         if (G_LOGGER->filter != NULL) { | ||||
|             log_filter *it   = G_LOGGER->filter; | ||||
|             log_filter *next = NULL; | ||||
|             while (it != NULL) { | ||||
|                 next = it->next; | ||||
|                 it->_free(it); | ||||
|                 it = next; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         free(G_LOGGER); | ||||
|         G_LOGGER = NULL; | ||||
|     } | ||||
| } | ||||
|  | ||||
| void destroyLogger(Logger *logger) { | ||||
|     if (logger != NULL) { | ||||
|         if (logger->handler != NULL) { | ||||
| @@ -353,7 +254,11 @@ void destroyLogger(Logger *logger) { | ||||
|                 it = next; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         free(logger); | ||||
|     } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * @brief 销毁日志对象 | ||||
|  */ | ||||
| void destroyDefaultLogger(void) { destroyLogger(ROOT_LOGGER); } | ||||
							
								
								
									
										124
									
								
								src/utils/logging-map.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								src/utils/logging-map.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,124 @@ | ||||
| #include "logging-map.h" | ||||
|  | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
|  | ||||
| /* 哈希函数:FNV-1a */ | ||||
| static uint32_t hash_bytes(const void *data, size_t len) { | ||||
|     const uint8_t *p = data; | ||||
|     uint32_t       h = 2166136261u; | ||||
|     while (len--) { | ||||
|         h ^= *p++; | ||||
|         h *= 16777619u; | ||||
|     } | ||||
|     return h; | ||||
| } | ||||
|  | ||||
| /* 创建空 map */ | ||||
| Map *map_create(size_t key_len, size_t value_len) { | ||||
|     Map *m        = calloc(1, sizeof(*m)); | ||||
|     m->key_len    = key_len; | ||||
|     m->value_len  = value_len; | ||||
|     m->bucket_cap = 8; /* 初始桶数 */ | ||||
|     m->bucket     = calloc(m->bucket_cap, sizeof(Node *)); | ||||
|     return m; | ||||
| } | ||||
|  | ||||
| /* 根据 key 找到桶下标 */ | ||||
| static size_t bucket_index(Map *m, const void *key) { | ||||
|     uint32_t h = hash_bytes(key, m->key_len); | ||||
|     return h & (m->bucket_cap - 1); /* 要求 bucket_cap 是 2 的幂 */ | ||||
| } | ||||
|  | ||||
| /* 在桶链中线性查找 */ | ||||
| static Node *find_in_chain(Node *head, const void *key, size_t key_len) { | ||||
|     for (; head; head = head->next) { | ||||
|         if (memcmp(head->kv, key, key_len) == 0) { | ||||
|             return head; | ||||
|         } | ||||
|     } | ||||
|     return NULL; | ||||
| } | ||||
|  | ||||
| /* 扩容:2× 桶数,重新哈希所有节点 */ | ||||
| static void map_resize(Map *m) { | ||||
|     size_t new_cap    = m->bucket_cap * 2; | ||||
|     Node **new_bucket = calloc(new_cap, sizeof(Node *)); | ||||
|  | ||||
|     for (size_t i = 0; i < m->bucket_cap; ++i) { | ||||
|         Node *node = m->bucket[i]; | ||||
|         while (node) { | ||||
|             Node  *next     = node->next; | ||||
|             size_t idx      = hash_bytes(node->kv, m->key_len) & (new_cap - 1); | ||||
|             node->next      = new_bucket[idx]; | ||||
|             new_bucket[idx] = node; | ||||
|             node            = next; | ||||
|         } | ||||
|     } | ||||
|     free(m->bucket); | ||||
|     m->bucket     = new_bucket; | ||||
|     m->bucket_cap = new_cap; | ||||
| } | ||||
|  | ||||
| /* 插入或覆盖 */ | ||||
| void map_put(Map *m, const void *key, const void *value) { | ||||
|     if (m->size * 4 >= m->bucket_cap * 3) { /* 装载因子 0.75 */ | ||||
|         map_resize(m); | ||||
|     } | ||||
|  | ||||
|     size_t idx  = bucket_index(m, key); | ||||
|     Node  *node = find_in_chain(m->bucket[idx], key, m->key_len); | ||||
|  | ||||
|     if (node) { /* 覆盖旧值 */ | ||||
|         memcpy(node->kv + m->key_len, value, m->value_len); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     /* 新建节点 */ | ||||
|     node       = malloc(sizeof(*node)); | ||||
|     node->kv   = malloc(m->key_len + m->value_len); | ||||
|     node->next = m->bucket[idx]; | ||||
|     memcpy(node->kv, key, m->key_len); | ||||
|     memcpy(node->kv + m->key_len, value, m->value_len); | ||||
|     m->bucket[idx] = node; | ||||
|     ++m->size; | ||||
| } | ||||
|  | ||||
| /* 查找 */ | ||||
| void *map_get(Map *m, const void *key) { | ||||
|     size_t idx  = bucket_index(m, key); | ||||
|     Node  *node = find_in_chain(m->bucket[idx], key, m->key_len); | ||||
|     return node ? (node->kv + m->key_len) : NULL; | ||||
| } | ||||
|  | ||||
| /* 删除 */ | ||||
| bool map_erase(Map *m, const void *key) { | ||||
|     size_t idx  = bucket_index(m, key); | ||||
|     Node **link = &m->bucket[idx]; | ||||
|     for (; *link; link = &(*link)->next) { | ||||
|         if (memcmp((*link)->kv, key, m->key_len) == 0) { | ||||
|             Node *to_del = *link; | ||||
|             *link        = to_del->next; | ||||
|             free(to_del->kv); | ||||
|             free(to_del); | ||||
|             --m->size; | ||||
|             return true; | ||||
|         } | ||||
|     } | ||||
|     return false; | ||||
| } | ||||
|  | ||||
| /* 销毁 */ | ||||
| void map_destroy(Map *m) { | ||||
|     for (size_t i = 0; i < m->bucket_cap; ++i) { | ||||
|         Node *node = m->bucket[i]; | ||||
|         while (node) { | ||||
|             Node *next = node->next; | ||||
|             free(node->kv); | ||||
|             free(node); | ||||
|             node = next; | ||||
|         } | ||||
|     } | ||||
|     free(m->bucket); | ||||
|     free(m); | ||||
| } | ||||
							
								
								
									
										37
									
								
								src/utils/logging-map.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								src/utils/logging-map.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| #ifndef __LOGGING_MAP_H__ | ||||
| #define __LOGGING_MAP_H__ | ||||
|  | ||||
| #include <stdbool.h> | ||||
| #include <stddef.h> | ||||
| #include <stdint.h> | ||||
|  | ||||
| typedef struct Node { | ||||
|     struct Node *next; | ||||
|     uint8_t     *kv; /* key 在前 value 在后 */ | ||||
| } Node; | ||||
|  | ||||
| struct Map { | ||||
|     size_t key_len, value_len; | ||||
|     size_t bucket_cap; | ||||
|     size_t size;   /* 当前元素个数 */ | ||||
|     Node **bucket; /* 指针数组 */ | ||||
| }; | ||||
|  | ||||
| typedef struct Map Map; | ||||
|  | ||||
| /* 创建空 map:key_len/value_len 以字节为单位 */ | ||||
| Map *map_create(size_t key_len, size_t value_len); | ||||
|  | ||||
| /* 插入或覆盖:<key> 必须指向 key_len 字节;同理 value */ | ||||
| void map_put(Map *m, const void *key, const void *value); | ||||
|  | ||||
| /* 查找:找到返回 value 指针;未找到返回 NULL */ | ||||
| void *map_get(Map *m, const void *key); | ||||
|  | ||||
| /* 删除:返回 true 表示确实删掉了 */ | ||||
| bool map_erase(Map *m, const void *key); | ||||
|  | ||||
| /* 销毁并释放所有内存 */ | ||||
| void map_destroy(Map *m); | ||||
|  | ||||
| #endif /* __LOGGING_MAP_H__ */ | ||||
| @@ -2,6 +2,8 @@ project(test) | ||||
|  | ||||
| enable_testing() | ||||
|  | ||||
| include_directories(${CMAKE_SOURCE_DIR}/src) | ||||
|  | ||||
| #测试简单基本应用 | ||||
| add_executable(${PROJECT_NAME}simple test-simple.c) | ||||
| target_link_libraries(${PROJECT_NAME}simple logging) | ||||
| @@ -17,3 +19,9 @@ add_test(test_file ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}file${CMAKE_EXECUT | ||||
| add_executable(${PROJECT_NAME}filter test-filter.c) | ||||
| target_link_libraries(${PROJECT_NAME}filter logging) | ||||
| add_test(test_filter ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}filter${CMAKE_EXECUTEABLE_SUFFIX}) | ||||
|  | ||||
|  | ||||
| #测试工具map | ||||
| add_executable(${PROJECT_NAME}map test-map.c) | ||||
| target_link_libraries(${PROJECT_NAME}map logging) | ||||
| add_test(test_map ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}map${CMAKE_EXECUTEABLE_SUFFIX}) | ||||
| @@ -6,8 +6,6 @@ | ||||
| #include <time.h> | ||||
|  | ||||
| int main() { | ||||
|     initDefaultLogger("test-filter", LOG_DEBUG); | ||||
|  | ||||
|     Log_info("This is an info message"); | ||||
|     Log_error("This is an error message%s", "123"); | ||||
|     Log_fatal("This is an fatal message"); | ||||
|   | ||||
| @@ -2,7 +2,6 @@ | ||||
| #include "logging/logging-handler.h" | ||||
|  | ||||
| int main() { | ||||
|     initDefaultLogger("testLogger", LOG_DEBUG); | ||||
|     log_Handler *hander = loggingHandlerFile("test_log", 1024 * 1024 * 10); | ||||
|     addHandler(getDefaultLogger(), hander); | ||||
|  | ||||
|   | ||||
							
								
								
									
										17
									
								
								tests/test-map.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								tests/test-map.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| #include "utils/logging-map.h" | ||||
|  | ||||
| int main(int argc, char *argv[]) { | ||||
|     (void)argc; | ||||
|     (void)argv; | ||||
|  | ||||
|     Map *map           = map_create(0, sizeof(int)); | ||||
|  | ||||
|     const char *keys[] = {"key1", "key2", "key3", "key4", "key5"}; | ||||
|  | ||||
|     for (int i = 0; i < 5; i++) { | ||||
|         map_put(map, keys[i], &i); | ||||
|     } | ||||
|  | ||||
|     map_destroy(map); | ||||
|     return 0; | ||||
| } | ||||
| @@ -1,8 +1,6 @@ | ||||
| #include "logging.h" | ||||
|  | ||||
| int main() { | ||||
|     initDefaultLogger("simple", LOG_DEBUG); | ||||
|  | ||||
|     Log_info("This is an info message"); | ||||
|     Log_error("This is an error message%s", "123"); | ||||
|     Log_fatal("This is an fatal message"); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user