hash table CHANGE new debug category for hash table changes
Fixes #963
diff --git a/src/hash_table.c b/src/hash_table.c
index f7d4378..fe0d68e 100644
--- a/src/hash_table.c
+++ b/src/hash_table.c
@@ -606,6 +606,73 @@
return 1;
}
+/* prints little-endian numbers, will also work on big-endian just the values will look weird */
+static char *
+lyht_dbgprint_val2str(void *val_p, int32_t hits, uint16_t rec_size)
+{
+ char *val;
+ int32_t i, j, val_size;
+
+ val_size = rec_size - (sizeof(struct ht_rec) - 1);
+
+ val = malloc(val_size * 2 + 1);
+ for (i = 0, j = val_size - 1; i < val_size; ++i, --j) {
+ if (hits > 0) {
+ sprintf(val + i * 2, "%02x", *(((uint8_t *)val_p) + j));
+ } else {
+ sprintf(val + i * 2, " ");
+ }
+ }
+
+ return val;
+}
+
+static void
+lyht_dbgprint_ht(struct hash_table *ht, const char *info)
+{
+ struct ht_rec *rec;
+ uint32_t i, i_len;
+ char *val;
+
+ if (LY_LLDBG > ly_log_level) {
+ return;
+ }
+
+ LOGDBG(LY_LDGHASH, "");
+ LOGDBG(LY_LDGHASH, "hash table %s (used %u, size %u):", info, ht->used, ht->size);
+
+ val = malloc(11);
+ sprintf(val, "%u", ht->size);
+ i_len = strlen(val);
+ free(val);
+
+ for (i = 0; i < ht->size; ++i) {
+ rec = lyht_get_rec(ht->recs, ht->rec_size, i);
+ val = lyht_dbgprint_val2str(&rec->val, rec->hits, ht->rec_size);
+ if (rec->hits > 0) {
+ LOGDBG(LY_LDGHASH, "[%*u] val %s hash %10u %% %*u hits %2d",
+ (int)i_len, i, val, rec->hash, (int)i_len, rec->hash & (ht->size - 1), rec->hits);
+ } else {
+ LOGDBG(LY_LDGHASH, "[%*u] val %s hash %10s %% %*s hits %2d",
+ (int)i_len, i, val, "", (int)i_len, "", rec->hits);
+ }
+ free(val);
+ }
+ LOGDBG(LY_LDGHASH, "");
+}
+
+static void
+lyht_dbgprint_value(void *val_p, uint32_t hash, uint16_t rec_size, const char *operation)
+{
+ if (LY_LLDBG > ly_log_level) {
+ return;
+ }
+
+ char *val = lyht_dbgprint_val2str(val_p, 1, rec_size);
+ LOGDBG(LY_LDGHASH, "%s value %s with hash %u", operation, val, hash);
+ free(val);
+}
+
int
lyht_insert_with_resize_cb(struct hash_table *ht, void *val_p, uint32_t hash,
values_equal_cb resize_val_equal, void **match_p)
@@ -615,6 +682,9 @@
int r, ret;
values_equal_cb old_val_equal;
+ lyht_dbgprint_ht(ht, "before");
+ lyht_dbgprint_value(val_p, hash, ht->rec_size, "inserting");
+
if (!lyht_find_first(ht, hash, &rec)) {
/* we found matching shortened hash */
if ((rec->hash == hash) && ht->val_equal(val_p, &rec->val, 1, ht->cb_data)) {
@@ -688,6 +758,8 @@
}
}
}
+
+ lyht_dbgprint_ht(ht, "after");
return ret;
}
@@ -704,8 +776,12 @@
int32_t i;
int first_matched = 0, r, ret;
+ lyht_dbgprint_ht(ht, "before");
+ lyht_dbgprint_value(val_p, hash, ht->rec_size, "removing");
+
if (lyht_find_first(ht, hash, &rec)) {
/* hash not found */
+ LOGDBG(LY_LDGHASH, "remove failed");
return 1;
}
if ((rec->hash == hash) && ht->val_equal(val_p, &rec->val, 1, ht->cb_data)) {
@@ -743,6 +819,7 @@
} else {
/* value not found even in collisions */
assert(!first_matched);
+ LOGDBG(LY_LDGHASH, "remove failed");
return 1;
}
@@ -757,5 +834,6 @@
}
}
+ lyht_dbgprint_ht(ht, "after");
return ret;
}
diff --git a/src/hash_table.h b/src/hash_table.h
index 84ea07e..b9323c0 100644
--- a/src/hash_table.h
+++ b/src/hash_table.h
@@ -60,8 +60,8 @@
*/
struct ht_rec {
uint32_t hash; /* hash of the value */
- int32_t hits; /* collision/overflow value count - 1 (a filled entry has 1 hit,
- * special value -1 means a deleted record) */
+ int32_t hits; /* (collision/overflow value count - 1) (a filled entry has 1 hit),
+ * special value (-1) means a deleted record) */
unsigned char val[1]; /* arbitrary-size value */
} _PACKED;
@@ -87,7 +87,7 @@
struct dict_rec {
char *value;
uint32_t refcount;
-};
+} _PACKED;
/**
* dictionary to store repeating strings
diff --git a/src/libyang.h.in b/src/libyang.h.in
index d0cd8d7..8f51c1d 100644
--- a/src/libyang.h.in
+++ b/src/libyang.h.in
@@ -1916,6 +1916,7 @@
#define LY_LDGXPATH 0x08 /**< XPath parsing end evaluation. */
#define LY_LDGDIFF 0x10 /**< Diff processing and creation. */
#define LY_LDGAPI 0x20 /**< API tracing. */
+#define LY_LDGHASH 0x40 /**< Hash table modifications. */
/**
* @}
diff --git a/src/log.c b/src/log.c
index 54976c9..eff2f60 100644
--- a/src/log.c
+++ b/src/log.c
@@ -266,6 +266,9 @@
case LY_LDGAPI:
str_group = "API";
break;
+ case LY_LDGHASH:
+ str_group = "HASH";
+ break;
default:
LOGINT(NULL);
return;
diff --git a/tests/internal/test_hash_table.c b/tests/internal/test_hash_table.c
index 46f4c21..9ea2fcb 100755
--- a/tests/internal/test_hash_table.c
+++ b/tests/internal/test_hash_table.c
@@ -364,5 +364,7 @@
cmocka_unit_test_setup_teardown(test_invalid_move2, setup_f, teardown_f),
};
+ /*ly_verb(LY_LLDBG);
+ ly_verb_dbg(LY_LDGHASH);*/
return cmocka_run_group_tests(tests, NULL, NULL);
}