diff --git a/core/database.c b/core/database.c index 3bf8839f..c67295ad 100644 --- a/core/database.c +++ b/core/database.c @@ -182,6 +182,18 @@ bool db_defrag(struct database *db) return true; } +void db_rekey(struct database *db, struct db_entry *dbe) +{ + if (dbe == NULL) + return; + + g_hash_table_remove(db->db_keys, dbe->dbe_key); + g_free(dbe->dbe_key); + + dbe->dbe_key = db->db_ops->dbe_key(dbe); + g_hash_table_insert(db->db_keys, dbe->dbe_key, dbe); +} + unsigned int db_actual_size(const struct database *db) { if (db->db_entries) diff --git a/include/core/database.h b/include/core/database.h index 6517a3fc..202c030d 100644 --- a/include/core/database.h +++ b/include/core/database.h @@ -124,6 +124,9 @@ void db_remove(struct database *, struct db_entry *); */ bool db_defrag(struct database *); +/* Called to change the key of a database entry. */ +void db_rekey(struct database *, struct db_entry *); + /* Returns the database item at the requested index. */ struct db_entry *db_at(const struct database *, unsigned int); diff --git a/tests/core/database.c b/tests/core/database.c index c4f0fafc..0d9dabd9 100644 --- a/tests/core/database.c +++ b/tests/core/database.c @@ -221,6 +221,19 @@ static void test_database(gconstpointer arg) } g_assert_false(db_defrag(&db)); + /* db_rekey() */ + i = 0; + db_for_each(dbe, next, &db) { + INT_ENTRY(dbe)->ie_val = i; + db_rekey(&db, dbe); + + key = g_strdup_printf("%u", i); + g_assert_cmpstr(dbe->dbe_key, ==, key); + g_assert_true(db_get(&db, key) == dbe); + g_free(key); + i++; + } + db_deinit(&db); g_assert_cmpuint(db.db_size, ==, 0); g_assert_cmpuint(db_actual_size(&db), ==, 0);