gnucash master: Multiple changes pushed
John Ralls
jralls at code.gnucash.org
Sat May 9 17:43:44 EDT 2020
Updated via https://github.com/Gnucash/gnucash/commit/5da3bf79 (commit)
via https://github.com/Gnucash/gnucash/commit/3e442a0e (commit)
via https://github.com/Gnucash/gnucash/commit/0403e490 (commit)
from https://github.com/Gnucash/gnucash/commit/f1ff7896 (commit)
commit 5da3bf79434df06735e2d2e4ba2fc54d4182a9bb
Author: John Ralls <jralls at ceridwen.us>
Date: Tue Jan 22 21:29:24 2019 -0800
[QofLog] Replace hashtable with tree of vectors.
16x speedup.
diff --git a/libgnucash/backend/xml/test/CMakeLists.txt b/libgnucash/backend/xml/test/CMakeLists.txt
index 78effe61e..6612da309 100644
--- a/libgnucash/backend/xml/test/CMakeLists.txt
+++ b/libgnucash/backend/xml/test/CMakeLists.txt
@@ -18,7 +18,7 @@ set(XML_TEST_LIBS gnc-engine gnc-test-engine test-core ${LIBXML2_LDFLAGS} -lz)
function(add_xml_test _TARGET _SOURCE_FILES)
gnc_add_test(${_TARGET} "${_SOURCE_FILES}" XML_TEST_INCLUDE_DIRS XML_TEST_LIBS ${ARGN})
- target_compile_options(${_TARGET} PRIVATE -DU_SHOW_CPLUSPLUS_API=0)
+ target_compile_options(${_TARGET} PRIVATE -DU_SHOW_CPLUSPLUS_API=0 -DG_LOG_DOMAIN=\"gnc.backend.xml\")
endfunction()
diff --git a/libgnucash/engine/qoflog.cpp b/libgnucash/engine/qoflog.cpp
index f787e7602..ba3efac88 100644
--- a/libgnucash/engine/qoflog.cpp
+++ b/libgnucash/engine/qoflog.cpp
@@ -54,6 +54,9 @@ extern "C"
#include "qof.h"
#include "qoflog.h"
+#include <string>
+#include <vector>
+#include <memory>
#define QOF_LOG_MAX_CHARS 50
#define QOF_LOG_MAX_CHARS_WITH_ALLOWANCE 100
@@ -63,10 +66,45 @@ extern "C"
static FILE *fout = NULL;
static gchar* function_buffer = NULL;
static gint qof_log_num_spaces = 0;
-static GHashTable *log_table = NULL;
static GLogFunc previous_handler = NULL;
static gchar* qof_logger_format = NULL;
+using StrVec = std::vector<std::string>;
+
+struct ModuleEntry;
+using ModuleEntryPtr = std::shared_ptr<ModuleEntry>;
+
+struct ModuleEntry
+{
+ ModuleEntry(std::string name) :
+ m_name{name}, m_level{QOF_LOG_WARNING}, m_children{4} {}
+ ~ModuleEntry() = default;
+ std::string m_name;
+ QofLogLevel m_level;
+ std::vector<ModuleEntryPtr> m_children;
+};
+
+static ModuleEntryPtr modules = NULL;
+
+static StrVec
+split_domain (const std::string domain)
+{
+ static constexpr int parts = 4; //enough room for most cases
+ std::vector<std::string> domain_parts{4};
+ int start = 0;
+ auto pos = domain.find(".");
+ if (pos == std::string::npos)
+ domain_parts.emplace_back(domain);
+ else
+ while (pos != std::string::npos)
+ {
+ domain_parts.emplace_back(domain.substr(start, pos));
+ start = pos + 1;
+ pos = domain.find(".", start);
+ }
+ return domain_parts;
+}
+
void
qof_log_indent(void)
{
@@ -82,7 +120,7 @@ qof_log_dedent(void)
: qof_log_num_spaces - QOF_LOG_INDENT_WIDTH;
}
-static void
+void
qof_log_set_file(FILE *outfile)
{
if (!outfile)
@@ -148,9 +186,8 @@ void
qof_log_init_filename(const gchar* log_filename)
{
gboolean warn_about_missing_permission = FALSE;
- if (log_table == NULL)
- log_table = g_hash_table_new_full(g_str_hash, g_str_equal,
- g_free, NULL);
+ if (!modules)
+ modules = std::make_shared<ModuleEntry>("");
if (!qof_logger_format)
qof_logger_format = g_strdup ("* %s %*s <%s> %*s%s%s"); //default format
@@ -194,9 +231,8 @@ qof_log_init_filename(const gchar* log_filename)
if (!fout)
fout = stderr;
- // @@fixme really, the userdata is a struct { log_table, fout, previous_handler }
if (previous_handler == NULL)
- previous_handler = g_log_set_default_handler(log4glib_handler, log_table);
+ previous_handler = g_log_set_default_handler(log4glib_handler, &modules);
if (warn_about_missing_permission)
{
@@ -219,10 +255,9 @@ qof_log_shutdown (void)
function_buffer = NULL;
}
- if (log_table != NULL)
+ if (modules != NULL)
{
- g_hash_table_destroy(log_table);
- log_table = NULL;
+ modules = nullptr;
}
if (previous_handler != NULL)
@@ -236,14 +271,55 @@ void
qof_log_set_level(QofLogModule log_module, QofLogLevel level)
{
if (!log_module || level == 0)
- {
return;
+ if (!modules)
+ {
+ modules = std::make_shared<ModuleEntry>("");
+ modules->m_level = QOF_LOG_WARNING;
}
- if (!log_table)
+ auto module_parts = split_domain(log_module);
+ auto module = modules;
+ for (auto part : module_parts)
{
- log_table = g_hash_table_new(g_str_hash, g_str_equal);
+ auto iter = std::find_if(module->m_children.begin(),
+ module->m_children.end(),
+ [part](ModuleEntryPtr child){
+ return child && part == child->m_name;
+ });
+ if (iter == module->m_children.end())
+ {
+ auto child = std::make_shared<ModuleEntry>(part);
+ module->m_children.push_back(child);
+ module = child;
+ }
+ else
+ {
+ module = *iter;
+ }
}
- g_hash_table_insert(log_table, g_strdup((gchar*)log_module), GINT_TO_POINTER((gint)level));
+ module->m_level = level;
+}
+
+
+gboolean
+qof_log_check(QofLogModule domain, QofLogLevel level)
+{
+ g_return_val_if_fail (domain && level && modules, FALSE);
+ if (level < modules->m_level)
+ return TRUE;
+ auto domain_vec = split_domain(domain);
+ auto module = modules;
+ for (auto part : domain_vec)
+ {
+ auto iter = std::find_if(module->m_children.begin(),
+ module->m_children.end(),
+ [part](ModuleEntryPtr child) {
+ return child && part == child->m_name; });
+ if (iter == module->m_children.end()) return FALSE;
+ if (level <= (*iter)->m_level) return TRUE;
+ module = *iter;
+ }
+ return FALSE;
}
const char *
@@ -381,54 +457,6 @@ qof_log_parse_log_config(const char *filename)
g_key_file_free(conf);
}
-gboolean
-qof_log_check(QofLogModule log_domain, QofLogLevel log_level)
-{
-//#define _QLC_DBG(x) x
-#define _QLC_DBG(x)
- GHashTable *log_levels = log_table;
- gchar *domain_copy = g_strdup(log_domain == NULL ? "" : log_domain);
- gchar *dot_pointer = domain_copy;
- static const QofLogLevel default_log_thresh = QOF_LOG_WARNING;
- QofLogLevel longest_match_level = default_log_thresh;
-
- {
- gpointer match_level;
- if (log_levels && (match_level = g_hash_table_lookup(log_levels, "")) != NULL)
- longest_match_level = (QofLogLevel)GPOINTER_TO_INT(match_level);
- }
-
-_QLC_DBG( { printf("trying [%s] (%d):", log_domain, log_levels != NULL ? g_hash_table_size(log_levels) : 0); });
- if (G_LIKELY(log_levels))
- {
- // e.g., "a.b.c\0" -> "a\0b.c\0" -> "a.b\0c\0", "a.b.c\0"
- gpointer match_level;
- while ((dot_pointer = g_strstr_len(dot_pointer, strlen(dot_pointer), ".")) != NULL)
- {
- *dot_pointer = '\0';
- _QLC_DBG( { printf(" [%s]", domain_copy); });
- if (g_hash_table_lookup_extended(log_levels, domain_copy, NULL, &match_level))
- {
- longest_match_level = (QofLogLevel)GPOINTER_TO_INT(match_level);
- _QLC_DBG(printf("*"););
- }
- *dot_pointer = '.';
- dot_pointer++;
- }
-
- _QLC_DBG( { printf(" [%s]", domain_copy); });
- if (g_hash_table_lookup_extended(log_levels, domain_copy, NULL, &match_level))
- {
- longest_match_level = (QofLogLevel)GPOINTER_TO_INT(match_level);
- _QLC_DBG( { printf("*"); });
- }
- }
- _QLC_DBG( { printf(" found [%d]\n", longest_match_level); });
- g_free(domain_copy);
-
- return log_level <= longest_match_level;
-}
-
void
qof_log_set_default(QofLogLevel log_level)
{
commit 3e442a0ef9316f9bb6d2f3a9ee49a211e89dd1c6
Author: John Ralls <jralls at ceridwen.us>
Date: Tue Jan 22 14:10:39 2019 -0800
Make qof_log_set_file static.
Used only internally.
diff --git a/libgnucash/engine/qoflog.cpp b/libgnucash/engine/qoflog.cpp
index 841e85536..f787e7602 100644
--- a/libgnucash/engine/qoflog.cpp
+++ b/libgnucash/engine/qoflog.cpp
@@ -82,7 +82,7 @@ qof_log_dedent(void)
: qof_log_num_spaces - QOF_LOG_INDENT_WIDTH;
}
-void
+static void
qof_log_set_file(FILE *outfile)
{
if (!outfile)
commit 0403e4906c8c8697c7a5ed144e8834ea146ba305
Author: John Ralls <jralls at ceridwen.us>
Date: Tue Jan 22 08:47:14 2019 -0800
Move QofLogModule typedef to qoflog.h where it belongs.
diff --git a/libgnucash/engine/qofid.h b/libgnucash/engine/qofid.h
index 13314ea25..c9012b6ac 100644
--- a/libgnucash/engine/qofid.h
+++ b/libgnucash/engine/qofid.h
@@ -85,8 +85,6 @@ extern "C"
typedef const gchar * QofIdType;
/** QofIdTypeConst declaration */
typedef const gchar * QofIdTypeConst;
-/** QofLogModule declaration */
-typedef const gchar* QofLogModule;
typedef struct QofCollection_s QofCollection;
diff --git a/libgnucash/engine/qoflog.h b/libgnucash/engine/qoflog.h
index 345ad5f1a..c4ee1dfdc 100644
--- a/libgnucash/engine/qoflog.h
+++ b/libgnucash/engine/qoflog.h
@@ -94,6 +94,8 @@ extern "C"
#include <glib.h>
#include "qofutil.h"
+typedef const gchar* QofLogModule;
+
#define QOF_MOD_ENGINE "qof.engine"
typedef enum
Summary of changes:
libgnucash/backend/xml/test/CMakeLists.txt | 2 +-
libgnucash/engine/qofid.h | 2 -
libgnucash/engine/qoflog.cpp | 150 +++++++++++++++++------------
libgnucash/engine/qoflog.h | 2 +
4 files changed, 92 insertions(+), 64 deletions(-)
More information about the gnucash-changes
mailing list