core/database: Convert class to a struct

In addition, we lowercase variable names and add a db_ prefix to all
struct members.

Signed-off-by: Anna Schumaker <Anna@OcarinaProject.net>
This commit is contained in:
Anna Schumaker 2015-10-17 10:07:58 -04:00
parent 385515edbc
commit 8a4e9fc2bc
15 changed files with 90 additions and 98 deletions

View File

@ -70,14 +70,14 @@ void IndexEntry :: read(file &file)
Index :: Index(const std::string &filepath, bool autosave) Index :: Index(const std::string &filepath, bool autosave)
: Database(filepath, autosave) : database(filepath, autosave)
{} {}
void Index :: insert(const std::string &key, unsigned int value) void Index :: insert(const std::string &key, unsigned int value)
{ {
IndexEntry *it = find(key); IndexEntry *it = find(key);
if (it == NULL) if (it == NULL)
it = Database :: insert(IndexEntry(key)); it = database :: insert(IndexEntry(key));
it->insert(value); it->insert(value);
autosave(); autosave();

View File

@ -6,7 +6,7 @@
#include <glib.h> #include <glib.h>
static Database<Album> album_db("album.db", true); static database<Album> album_db("album.db", true);
static const std::string make_key(const std::string &name, unsigned int year) static const std::string make_key(const std::string &name, unsigned int year)
{ {

View File

@ -4,7 +4,7 @@
#include <core/tags/artist.h> #include <core/tags/artist.h>
static Database<Artist> artist_db("artist.db", true); static database<Artist> artist_db("artist.db", true);
Artist :: Artist() : GenericTag() {} Artist :: Artist() : GenericTag() {}

View File

@ -4,7 +4,7 @@
#include <core/tags/genre.h> #include <core/tags/genre.h>
static Database<Genre> genre_db("genre.db", true); static database<Genre> genre_db("genre.db", true);
Genre :: Genre() : GenericTag() {} Genre :: Genre() : GenericTag() {}

View File

@ -4,7 +4,7 @@
#include <core/tags/library.h> #include <core/tags/library.h>
static Database<Library> library_db("library.db", true); static database<Library> library_db("library.db", true);
Library :: Library() Library :: Library()

View File

@ -8,7 +8,7 @@
#include <glib.h> #include <glib.h>
static Database<Track> track_db("track.db", false); static database<Track> track_db("track.db", false);
Track :: Track() Track :: Track()
@ -165,7 +165,7 @@ void tags :: remove_track(Track *track)
void tags :: remove_library_tracks(Library *library) void tags :: remove_library_tracks(Library *library)
{ {
Database<Track>::iterator it; database<Track>::iterator it;
for (it = track_db.begin(); it != track_db.end(); it = track_db.next(it)) { for (it = track_db.begin(); it != track_db.end(); it = track_db.next(it)) {
if ((*it)->library() == library) if ((*it)->library() == library)

View File

@ -12,7 +12,7 @@ extern "C" {
#include <string> #include <string>
#include <vector> #include <vector>
template<class T> class Database; template<class T> struct database;
/** /**
* The DatabaseEntry class is the base class for storing * The DatabaseEntry class is the base class for storing
@ -20,7 +20,7 @@ template<class T> class Database;
*/ */
class DatabaseEntry { class DatabaseEntry {
private: private:
template <class T> friend class Database; template <class T> friend struct database;
unsigned int _index; /**< The location of an item in the Database. */ unsigned int _index; /**< The location of an item in the Database. */
public: public:
@ -81,24 +81,14 @@ public:
* The Database class will add a newline after each DatabaseEntry. * The Database class will add a newline after each DatabaseEntry.
*/ */
template <class T> template <class T>
class Database { struct database {
private: unsigned int db_size; /* The database's count of valid entries. */
/** Databases are backed by a std::vector. */ bool db_autosave; /* True if the database saves when changed. */
std::vector<T *> _db; struct file db_file; /* The database's associated file object. */
/** Used for keeping track of primary keys. */ std::vector<T *> db_entries;
std::map<const std::string, unsigned int> _keys; std::map<const std::string, unsigned int> db_keys;
/** The number of valid DatabaseEntries in the Database. */
unsigned int _size;
/** Set to True if the Database should be saved when changed. */
bool _autosave;
/** File object for reading and writing a Database. */
file _file;
public:
/** Iterator access for our backing std::vector */ /** Iterator access for our backing std::vector */
typedef typename std::vector<T *>::iterator iterator; typedef typename std::vector<T *>::iterator iterator;
/** Const iterator access for our backing std::vector */ /** Const iterator access for our backing std::vector */
@ -114,12 +104,12 @@ public:
* to False then the Database will have to be saved * to False then the Database will have to be saved
* manually. * manually.
*/ */
Database(std::string, bool); database(std::string, bool);
/** /**
* Deletes all remaining entries in a Database to prevent memory leaks. * Deletes all remaining entries in a Database to prevent memory leaks.
*/ */
~Database(); ~database();
/** /**
* Called to save the Database to disk. * Called to save the Database to disk.

View File

@ -8,14 +8,14 @@
#define OCARINA_DATABASE_HPP #define OCARINA_DATABASE_HPP
template <class T> template <class T>
Database<T> :: Database(std::string filepath, bool autosave) database<T> :: database(std::string filepath, bool autosave)
: _size(0), _autosave(autosave) : db_size(0), db_autosave(autosave)
{ {
file_init(&_file, filepath.c_str(), 0); file_init(&db_file, filepath.c_str(), 0);
} }
template <class T> template <class T>
Database<T> :: ~Database() database<T> :: ~database()
{ {
iterator it; iterator it;
for (it = begin(); it != end(); it = next(it)) for (it = begin(); it != end(); it = next(it))
@ -23,63 +23,65 @@ Database<T> :: ~Database()
} }
template <class T> template <class T>
void Database<T> :: save() void database<T> :: save()
{ {
if (file_open(&_file, OPEN_WRITE) == false) if (file_open(&db_file, OPEN_WRITE) == false)
return; return;
file_writef(&_file, "%u\n", actual_size()); file_writef(&db_file, "%u\n", actual_size());
for (unsigned int i = 0; i < _db.size(); i++) { for (unsigned int i = 0; i < db_entries.size(); i++) {
if (_db[i] == NULL) if (db_entries[i] == NULL)
file_writef(&_file, "%d\n", false); file_writef(&db_file, "%d\n", false);
else { else {
file_writef(&_file, "%d ", true); file_writef(&db_file, "%d ", true);
_db[i]->write(_file); db_entries[i]->write(db_file);
file_writef(&_file, "\n"); file_writef(&db_file, "\n");
} }
} }
file_close(&_file); file_close(&db_file);
} }
template <class T> template <class T>
void Database<T> :: autosave() void database<T> :: autosave()
{ {
if (_autosave == true) if (db_autosave == true)
save(); save();
} }
template <class T> template <class T>
void Database<T> :: load() void database<T> :: load()
{ {
unsigned int db_size; unsigned int size;
std::string str;
int valid; int valid;
if (file_exists(&_file) == false) if (file_exists(&db_file) == false)
return; return;
else if (file_open(&_file, OPEN_READ) == false) else if (file_open(&db_file, OPEN_READ) == false)
return; return;
file_readf(&_file, "%u", &db_size); file_readf(&db_file, "%u", &size);
_db.resize(db_size); db_entries.resize(size);
for (unsigned int i = 0; i < db_size; i++) { for (unsigned int i = 0; i < size; i++) {
file_readf(&_file, "%d", &valid); file_readf(&db_file, "%d", &valid);
if (valid == false) { if (valid == false) {
_db[i] = NULL; db_entries[i] = NULL;
} else { } else {
_db[i] = new T; db_entries[i] = new T;
_db[i]->_index = i; db_entries[i]->_index = i;
_db[i]->read(_file); db_entries[i]->read(db_file);
_keys[_db[i]->primary_key()] = i; str = db_entries[i]->primary_key();
_size++; db_keys[str] = i;
db_size++;
} }
} }
file_close(&_file); file_close(&db_file);
} }
template <class T> template <class T>
T *Database<T> :: insert(const T &item) T *database<T> :: insert(const T &item)
{ {
T *t = find(item.primary_key()); T *t = find(item.primary_key());
@ -88,60 +90,60 @@ T *Database<T> :: insert(const T &item)
t = new T(item); t = new T(item);
t->_index = actual_size(); t->_index = actual_size();
_db.push_back(t); db_entries.push_back(t);
_keys[t->primary_key()] = t->index(); db_keys[t->primary_key()] = t->index();
_size++; db_size++;
autosave(); autosave();
return t; return t;
} }
template <class T> template <class T>
void Database<T> :: remove(unsigned int index) void database<T> :: remove(unsigned int index)
{ {
if (index >= actual_size()) if (index >= actual_size())
return; return;
if (_db[index] == NULL) if (db_entries[index] == NULL)
return; return;
_keys.erase(_db[index]->primary_key()); db_keys.erase(db_entries[index]->primary_key());
delete _db[index]; delete db_entries[index];
_db[index] = NULL; db_entries[index] = NULL;
_size--; db_size--;
autosave(); autosave();
} }
template <class T> template <class T>
unsigned int Database<T> :: size() unsigned int database<T> :: size()
{ {
return _size; return db_size;
} }
template <class T> template <class T>
unsigned int Database<T> :: actual_size() unsigned int database<T> :: actual_size()
{ {
return _db.size(); return db_entries.size();
} }
template <class T> template <class T>
typename Database<T>::iterator Database<T> :: begin() typename database<T>::iterator database<T> :: begin()
{ {
if (size() == 0) if (size() == 0)
return end(); return end();
iterator it = _db.begin(); iterator it = db_entries.begin();
if ( (*it) != NULL ) if ( (*it) != NULL )
return it; return it;
return next(it); return next(it);
} }
template <class T> template <class T>
typename Database<T>::iterator Database<T> :: end() typename database<T>::iterator database<T> :: end()
{ {
return _db.end(); return db_entries.end();
} }
template <class T> template <class T>
typename Database<T>::iterator Database<T> :: next(iterator &it) typename database<T>::iterator database<T> :: next(iterator &it)
{ {
do { do {
it++; it++;
@ -150,20 +152,20 @@ typename Database<T>::iterator Database<T> :: next(iterator &it)
} }
template <class T> template <class T>
T *Database<T> :: at(unsigned int index) T *database<T> :: at(unsigned int index)
{ {
if (index >= actual_size()) if (index >= actual_size())
return NULL; return NULL;
return _db[index]; return db_entries[index];
} }
template <class T> template <class T>
T *Database<T> :: find(const std::string &key) T *database<T> :: find(const std::string &key)
{ {
std::map<const std::string, unsigned int>::iterator it; std::map<const std::string, unsigned int>::iterator it;
it = _keys.find(key); it = db_keys.find(key);
if (it == _keys.end()) if (it == db_keys.end())
return NULL; return NULL;
return _db[it->second]; return db_entries[it->second];
} }
#endif /* OCARINA_DATABASE_HPP */ #endif /* OCARINA_DATABASE_HPP */

View File

@ -103,7 +103,7 @@ public:
* An Index is a special Database for mapping std::strings to a std::set of * An Index is a special Database for mapping std::strings to a std::set of
* integer identifiers. * integer identifiers.
*/ */
class Index : public Database<IndexEntry> { class Index : public database<IndexEntry> {
public: public:
/** /**
* Index constructor. This simply passes the filepath and autosave * Index constructor. This simply passes the filepath and autosave

View File

@ -61,7 +61,7 @@ static void test_db_entry()
static void test_init() static void test_init()
{ {
Database<struct int_entry> db("database.db", false); database<struct int_entry> db("database.db", false);
/* Check initial sizes. */ /* Check initial sizes. */
test_equal(db.actual_size(), 0); test_equal(db.actual_size(), 0);
@ -70,8 +70,8 @@ static void test_init()
static void test_stress(unsigned int N) static void test_stress(unsigned int N)
{ {
Database<struct int_entry> db("stress.db", false); database<struct int_entry> db("stress.db", false);
Database<struct int_entry>::iterator it; database<struct int_entry>::iterator it;
std::vector<struct int_entry *> ptrs; std::vector<struct int_entry *> ptrs;
struct int_entry *dbe; struct int_entry *dbe;
unsigned int i; unsigned int i;
@ -143,8 +143,8 @@ static void test_stress_100K() { test_stress(100000); }
static void test_save_load() static void test_save_load()
{ {
Database<struct int_entry> db1("save_load.db", true); database<struct int_entry> db1("save_load.db", true);
Database<struct int_entry> db2("save_load.db", false); database<struct int_entry> db2("save_load.db", false);
struct int_entry *dbe; struct int_entry *dbe;
const unsigned int N = 10; const unsigned int N = 10;
unsigned int i; unsigned int i;
@ -166,7 +166,7 @@ static void test_save_load()
for (i = 0; i < N; i += 2) for (i = 0; i < N; i += 2)
db1.remove(i); db1.remove(i);
db2 = Database<struct int_entry>("save_load.db", false); db2 = database<struct int_entry>("save_load.db", false);
db2.load(); db2.load();
test_equal(db2.size(), N / 2); test_equal(db2.size(), N / 2);
for (i = 1; i < N; i++) { for (i = 1; i < N; i++) {
@ -185,12 +185,12 @@ static void test_save_load()
for (i = N; i < (2 * N); i += 2) for (i = N; i < (2 * N); i += 2)
db2.remove(i); db2.remove(i);
db1 = Database<struct int_entry>("save_load.db", false); db1 = database<struct int_entry>("save_load.db", false);
db1.load(); db1.load();
test_equal(db1.size(), N / 2); test_equal(db1.size(), N / 2);
db2.save(); db2.save();
db1 = Database<struct int_entry>("save_load.db", false); db1 = database<struct int_entry>("save_load.db", false);
db1.load(); db1.load();
test_equal(db1.size(), N); test_equal(db1.size(), N);

View File

@ -37,7 +37,7 @@ static void test_album_tag()
static void test_album_tag_lookup() static void test_album_tag_lookup()
{ {
Database<Album> album_db("album.db", false); database<Album> album_db("album.db", false);
Album *album = tags :: get_album("Hyrule Symphony", 1998); Album *album = tags :: get_album("Hyrule Symphony", 1998);
test_equal(album->name(), (std::string)"Hyrule Symphony"); test_equal(album->name(), (std::string)"Hyrule Symphony");

View File

@ -19,7 +19,7 @@ static void test_artist_tag()
static void test_artist_tag_lookup() static void test_artist_tag_lookup()
{ {
Database<Artist> artist_db("artist.db", false); database<Artist> artist_db("artist.db", false);
Artist *artist = tags :: get_artist("Koji Kondo"); Artist *artist = tags :: get_artist("Koji Kondo");
test_equal(artist->name(), (std::string)"Koji Kondo"); test_equal(artist->name(), (std::string)"Koji Kondo");

View File

@ -19,7 +19,7 @@ static void test_artist_tag()
static void test_genere_tag_lookup() static void test_genere_tag_lookup()
{ {
Database<Genre> genre_db("genre.db", false); database<Genre> genre_db("genre.db", false);
Genre *genre = tags :: get_genre("Video Game Music"); Genre *genre = tags :: get_genre("Video Game Music");
test_equal(genre->name(), (std::string)"Video Game Music"); test_equal(genre->name(), (std::string)"Video Game Music");

View File

@ -44,7 +44,7 @@ static void test_library_tag()
static void test_library_tag_lookup() static void test_library_tag_lookup()
{ {
Database<Library> library_db("library.db", false); database<Library> library_db("library.db", false);
Library *library; Library *library;
test_equal(tags :: library_size(), (unsigned)0); test_equal(tags :: library_size(), (unsigned)0);

View File

@ -107,7 +107,7 @@ static void test_track_tag_destructor()
static void test_track_tag_load_db(unsigned int size) static void test_track_tag_load_db(unsigned int size)
{ {
Database<Track> track_db("track.db", false); database<Track> track_db("track.db", false);
track_db.load(); track_db.load();
test_equal(track_db.size(), size); test_equal(track_db.size(), size);
} }