diff --git a/core/database.cpp b/core/database.cpp index 5e16eb2a..2c1ecf40 100644 --- a/core/database.cpp +++ b/core/database.cpp @@ -3,6 +3,9 @@ */ #include +#define DB_ENTRY_AT(db, index) \ + (struct db_entry *)g_ptr_array_index(db->db_entries, index) + db_entry :: db_entry() : dbe_index(0), dbe_key(NULL) @@ -17,7 +20,7 @@ static void __dbe_free(struct database *db, struct db_entry *dbe) db->db_keys.erase(dbe->dbe_key); g_free(dbe->dbe_key); - db->db_entries[dbe->dbe_index] = NULL; + g_ptr_array_index(db->db_entries, dbe->dbe_index) = NULL; db->db_ops->dbe_free(dbe); db->db_size--; @@ -26,9 +29,12 @@ static void __dbe_free(struct database *db, struct db_entry *dbe) struct db_entry *__dbe_next(const struct database *db, unsigned int index) { - for (; index < db->db_entries.size(); index++) { - if (db->db_entries[index]) - return db->db_entries[index]; + if (!db->db_entries) + return NULL; + + for (; index < db->db_entries->len; index++) { + if (DB_ENTRY_AT(db, index)) + return DB_ENTRY_AT(db, index); } return NULL; } @@ -42,13 +48,13 @@ static struct db_entry *__dbe_read(struct database *db, unsigned int index) if (valid) dbe = db->db_ops->dbe_read(&db->db_file); - db->db_entries[index] = dbe; + g_ptr_array_index(db->db_entries, index) = dbe; return dbe; } static void __dbe_setup(struct database *db, unsigned int index) { - struct db_entry *dbe = db->db_entries[index]; + struct db_entry *dbe = DB_ENTRY_AT(db, index); if (dbe) { dbe->dbe_index = index; @@ -76,14 +82,19 @@ void db_init(struct database *db, const char *filepath, bool autosave, db->db_ops = ops; db->db_size = 0; db->db_autosave = autosave; + db->db_entries = g_ptr_array_new(); file_init(&db->db_file, filepath, 0); } void db_deinit(struct database *db) { struct db_entry *dbe, *next; + db_for_each(dbe, next, db) __dbe_free(db, dbe); + + g_ptr_array_free(db->db_entries, true); + db->db_entries = NULL; } void db_save(struct database *db) @@ -93,7 +104,7 @@ void db_save(struct database *db) file_writef(&db->db_file, "%u\n", db_actual_size(db)); for (unsigned int i = 0; i < db_actual_size(db); i++) - __dbe_write(db, db->db_entries[i]); + __dbe_write(db, DB_ENTRY_AT(db, i)); file_close(&db->db_file); } @@ -112,7 +123,7 @@ void db_load(struct database *db) return; file_readf(&db->db_file, "%u", &size); - db->db_entries.resize(size); + g_ptr_array_set_size(db->db_entries, size); for (unsigned int i = 0; i < size; i++) { if (__dbe_read(db, i)) __dbe_setup(db, i); @@ -124,7 +135,7 @@ void db_load(struct database *db) struct db_entry *db_insert(struct database *db, struct db_entry *item) { if (item) { - db->db_entries.push_back(item); + g_ptr_array_add(db->db_entries, item); __dbe_setup(db, db_actual_size(db) - 1); db_autosave(db); } @@ -143,7 +154,9 @@ void db_remove(struct database *db, struct db_entry *item) unsigned int db_actual_size(const struct database *db) { - return db->db_entries.size(); + if (db->db_entries) + return db->db_entries->len; + return 0; } struct db_entry *db_first(const struct database *db) @@ -162,7 +175,7 @@ struct db_entry *db_at(struct database *db, unsigned int index) { if (index >= db_actual_size(db)) return NULL; - return db->db_entries[index]; + return DB_ENTRY_AT(db, index); } struct db_entry *db_get(struct database *db, const gchar *key) @@ -171,7 +184,7 @@ struct db_entry *db_get(struct database *db, const gchar *key) it = db->db_keys.find(key); if (it == db->db_keys.end()) return NULL; - return db->db_entries[it->second]; + return DB_ENTRY_AT(db, it->second); } struct db_entry *db_find(struct database *db, const gchar *key) diff --git a/include/core/database.h b/include/core/database.h index ba85afcb..b88a6431 100644 --- a/include/core/database.h +++ b/include/core/database.h @@ -9,7 +9,6 @@ extern "C" { } #include -#include /** * The DatabaseEntry class is the base class for storing @@ -67,9 +66,9 @@ struct database { unsigned int db_size; /* The database's count of valid entries. */ bool db_autosave; /* True if the database saves when changed. */ struct file db_file; /* The database's associated file object. */ + GPtrArray *db_entries; /* The database's backing array. */ const struct db_ops *db_ops; /* The database's operations vector. */ - std::vector db_entries; std::map db_keys; }; @@ -83,7 +82,6 @@ void db_init(struct database *, const char *, bool, const struct db_ops *); /* Called to prevent memory leaks by freeing all remaining database entries. */ void db_deinit(struct database *); - /* Called to write the database to disk. */ void db_save(struct database *); diff --git a/tests/core/database.cpp b/tests/core/database.cpp index 7816169b..39037cd9 100644 --- a/tests/core/database.cpp +++ b/tests/core/database.cpp @@ -8,7 +8,6 @@ #include - /* * Derive a db_entry for storing integerss */ @@ -108,7 +107,7 @@ static void test_init() db_init(&db, "init.db", false, &int_ops); /* Check initial sizes. */ - test_equal(db.db_entries.size(), 0); + test_equal(db.db_entries->len, 0); test_equal(db.db_keys.size(), 0); test_equal(db.db_size, 0); test_equal(db.db_autosave, false); @@ -219,7 +218,7 @@ static void test_stress(unsigned int N) db_deinit(&db); test_equal(db.db_size, 0); - test_equal(db_actual_size(&db), N + 1); + test_equal(db_actual_size(&db), 0); test_equal(db_first(&db), NULL); test_equal(test_free_count, N + 1); } @@ -256,6 +255,7 @@ static void test_save_load() db_remove(&db1, db_at(&db1, i)); db_deinit(&db2); + db2.db_entries = g_ptr_array_new(); test_setup_count = 0; db_load(&db2); test_equal(db2.db_size, N / 2); @@ -275,11 +275,13 @@ static void test_save_load() db_remove(&db1, db_at(&db1, i)); db_deinit(&db2); + db2.db_entries = g_ptr_array_new(); db_load(&db2); test_equal(db2.db_size, N / 2); db_save(&db1); db_deinit(&db2); + db2.db_entries = g_ptr_array_new(); db_load(&db2); i = 1; diff --git a/tests/core/tags/library.cpp b/tests/core/tags/library.cpp index 31453b36..5c0f3cbe 100644 --- a/tests/core/tags/library.cpp +++ b/tests/core/tags/library.cpp @@ -92,6 +92,7 @@ static void test_library_db() library_db_deinit(); db_deinit(&library_db); + library_db.db_entries = g_ptr_array_new(); db_load(&library_db); test_equal(library_db.db_size, 0); }