database: Implement updates to match my current design

- Force the primary key to be a string
- Throw error codes rather than 0

Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
This commit is contained in:
Anna Schumaker 2013-12-30 18:18:23 -05:00 committed by Anna Schumaker
parent ab8c15ecb7
commit acd8bd7b23
7 changed files with 162 additions and 135 deletions

View File

@ -240,9 +240,10 @@ Database: (lib/database.cpp)
- DatabaseEntry: - DatabaseEntry:
class DatabaseEntry { /* let database modify valid flag */ class DatabaseEntry { /* let database modify valid flag */
public: public:
const std::string primary_key;
bool valid; bool valid;
virtual const std::string &primary_key() = 0; DatabaseEntry(const std::string &);
virtual void write(File &) = 0; virtual void write(File &) = 0;
virtual void read(File &) = 0; virtual void read(File &) = 0;
virtual void print() = 0; virtual void print() = 0;
@ -253,13 +254,13 @@ Database: (lib/database.cpp)
- IndexEntry: - IndexEntry:
class IndexEntry : public DatabaseEntry { class IndexEntry : public DatabaseEntry {
public: public:
string key;
set<unsigned int> values; set<unsigned int> values;
const std::string &primary_key();
void write(File &); void write(File &);
void read(File &); void read(File &);
void print(); void print();
void insert(unsigned int);
void remove(unsigned int);
}; };
File << key << endl; File << key << endl;
@ -283,7 +284,7 @@ Database: (lib/database.cpp)
void print_keys(); void print_keys();
unsigned int insert(T); unsigned int insert(T);
void delete(unsigned int); void remove(unsigned int);
unsigned int size(); unsigned int size();
unsigned int num_rows(); unsigned int num_rows();
@ -332,7 +333,7 @@ Database: (lib/database.cpp)
mapping is also created into the keys map to map the primary mapping is also created into the keys map to map the primary
key back to the id of the newly added item. key back to the id of the newly added item.
void Database :: delete(unsigned int index); void Database :: remove(unsigned int index);
Mark db[index] as invalid (quick deletion). Mark db[index] as invalid (quick deletion).
unsigned int Database :: size(); unsigned int Database :: size();
@ -342,14 +343,16 @@ Database: (lib/database.cpp)
Return db.size(). Return db.size().
unsigned int Database :: first(); unsigned int Database :: first();
Return the id to the first valid row. Return the id to the first valid row. Return db.size() if
there are no valid rows.
unsigned int Database :: last(); unsigned int Database :: last();
Return the id of the last valid row. Return the id of the last valid row. Return db.size() if
there are no valid rows.
unsigned int Database :: next(unsigned int &id); unsigned int Database :: next(unsigned int &id);
Return the id of the next valid row or throw -EINVAL if there Return the id of the next valid row or return db.size() if
are no remaining valid rows. there are no valid rows.
bool Database :: has_key(const std::string &key); bool Database :: has_key(const std::string &key);
Return true if an item with primary key "key" exists in the Return true if an item with primary key "key" exists in the
@ -363,13 +366,15 @@ Database: (lib/database.cpp)
template <class T> template <class T>
T &Database :: find(const std::string &key); T &Database :: find(const std::string &key);
Search for primary key "key" in the database. The reverse Search for primary key "key" in the database. The reverse
mapping should be used to make this operation faster. Throw mapping should be used to make this operation faster.
-EEXIST if the key is not found in the mapping. Throw -EEXIST if the key is not found in the mapping.
Throw -EINVAL if the key points to an invalid entry.
template <class T> template <class T>
T &Database :: operator[](unsigned int index); T &Database :: operator[](unsigned int index);
Return a reference to db[index]. Throw -EEXIST if index is out Return a reference to db[index].
of range. Throw -EEXIST if index is out of range.
Throw -EINVAL if index is invalid.

View File

@ -32,9 +32,10 @@ Database: (lib/database.cpp)
- DatabaseEntry: - DatabaseEntry:
class DatabaseEntry { /* let database modify valid flag */ class DatabaseEntry { /* let database modify valid flag */
public: public:
const std::string primary_key;
bool valid; bool valid;
virtual const std::string &primary_key() = 0; DatabaseEntry(const std::string &);
virtual void write(File &) = 0; virtual void write(File &) = 0;
virtual void read(File &) = 0; virtual void read(File &) = 0;
virtual void print() = 0; virtual void print() = 0;
@ -45,13 +46,13 @@ Database: (lib/database.cpp)
- IndexEntry: - IndexEntry:
class IndexEntry : public DatabaseEntry { class IndexEntry : public DatabaseEntry {
public: public:
string key;
set<unsigned int> values; set<unsigned int> values;
const std::string &primary_key();
void write(File &); void write(File &);
void read(File &); void read(File &);
void print(); void print();
void insert(unsigned int);
void remove(unsigned int);
}; };
File << key << endl; File << key << endl;
@ -75,7 +76,7 @@ Database: (lib/database.cpp)
void print_keys(); void print_keys();
unsigned int insert(T); unsigned int insert(T);
void delete(unsigned int); void remove(unsigned int);
unsigned int size(); unsigned int size();
unsigned int num_rows(); unsigned int num_rows();
@ -124,7 +125,7 @@ Database: (lib/database.cpp)
mapping is also created into the keys map to map the primary mapping is also created into the keys map to map the primary
key back to the id of the newly added item. key back to the id of the newly added item.
void Database :: delete(unsigned int index); void Database :: remove(unsigned int index);
Mark db[index] as invalid (quick deletion). Mark db[index] as invalid (quick deletion).
unsigned int Database :: size(); unsigned int Database :: size();
@ -134,14 +135,16 @@ Database: (lib/database.cpp)
Return db.size(). Return db.size().
unsigned int Database :: first(); unsigned int Database :: first();
Return the id to the first valid row. Return the id to the first valid row. Return db.size() if
there are no valid rows.
unsigned int Database :: last(); unsigned int Database :: last();
Return the id of the last valid row. Return the id of the last valid row. Return db.size() if
there are no valid rows.
unsigned int Database :: next(unsigned int &id); unsigned int Database :: next(unsigned int &id);
Return the id of the next valid row or throw -EINVAL if there Return the id of the next valid row or return db.size() if
are no remaining valid rows. there are no valid rows.
bool Database :: has_key(const std::string &key); bool Database :: has_key(const std::string &key);
Return true if an item with primary key "key" exists in the Return true if an item with primary key "key" exists in the
@ -155,10 +158,12 @@ Database: (lib/database.cpp)
template <class T> template <class T>
T &Database :: find(const std::string &key); T &Database :: find(const std::string &key);
Search for primary key "key" in the database. The reverse Search for primary key "key" in the database. The reverse
mapping should be used to make this operation faster. Throw mapping should be used to make this operation faster.
-EEXIST if the key is not found in the mapping. Throw -EEXIST if the key is not found in the mapping.
Throw -EINVAL if the key points to an invalid entry.
template <class T> template <class T>
T &Database :: operator[](unsigned int index); T &Database :: operator[](unsigned int index);
Return a reference to db[index]. Throw -EEXIST if index is out Return a reference to db[index].
of range. Throw -EEXIST if index is out of range.
Throw -EINVAL if index is invalid.

View File

@ -12,43 +12,42 @@
#include <vector> #include <vector>
template <class T>
class DatabaseEntry { class DatabaseEntry {
public: public:
std::string primary_key;
bool valid; bool valid;
DatabaseEntry(); DatabaseEntry();
virtual T &primary_key() = 0;
virtual void write(File &) = 0; virtual void write(File &) = 0;
virtual void read(File &) = 0; virtual void read(File &) = 0;
#ifdef CONFIG_DEBUG #ifdef CONFIG_TEST
virtual void print() = 0; virtual void print() = 0;
#endif /* CONFIG_DEBUG */ #endif /* CONFIG_TEST */
}; };
class IndexEntry : public DatabaseEntry<const std::string> { class IndexEntry : public DatabaseEntry {
public: public:
std::string key;
std::set<unsigned int> values; std::set<unsigned int> values;
IndexEntry(); IndexEntry();
IndexEntry(const std::string &, unsigned int); IndexEntry(const std::string &, unsigned int);
~IndexEntry(); ~IndexEntry();
const std::string &primary_key();
void write(File &); void write(File &);
void read(File &); void read(File &);
#ifdef CONFIG_TEST
void print(); void print();
#endif /* CONFIG_TEST */
void insert(unsigned int); void insert(unsigned int);
void remove(unsigned int); void remove(unsigned int);
}; };
template <class T, class U> template <class T>
class Database { class Database {
private: private:
std::vector<T> db; std::vector<T> db;
std::map<U, unsigned int> keys; std::map<const std::string, unsigned int> keys;
unsigned int _size; unsigned int _size;
File file; File file;
@ -57,11 +56,11 @@ public:
~Database(); ~Database();
void save(); void save();
void load(); void load();
#ifdef CONFIG_DEBUG #ifdef CONFIG_TEST
void clear(); void clear();
void print(); void print();
void print_keys(); void print_keys();
#endif /* CONFIG_DEBUG */ #endif /* CONFIG_TEST */
unsigned int insert(T); unsigned int insert(T);
void remove(unsigned int); void remove(unsigned int);
@ -71,13 +70,13 @@ public:
unsigned int first(); unsigned int first();
unsigned int last(); unsigned int last();
unsigned int next(unsigned int); unsigned int next(unsigned int);
bool has_key(const std::string &);
unsigned int find_index(const std::string &); unsigned int find_index(const std::string &);
T &find(const std::string &); T &find(const std::string &);
T &operator[](unsigned int); T &operator[](unsigned int);
}; };
template <class T> static inline void index_insert(Database<IndexEntry> &db,
static inline void index_insert(Database<IndexEntry, T> &db,
const std::string &key, const std::string &key,
unsigned int val) unsigned int val)
{ {
@ -88,8 +87,7 @@ static inline void index_insert(Database<IndexEntry, T> &db,
} }
} }
template <class T> static inline void index_remove(Database<IndexEntry> &db,
static inline void index_remove(Database<IndexEntry, T> &db,
const std::string &key, const std::string &key,
unsigned int val) unsigned int val)
{ {

View File

@ -7,30 +7,27 @@
#ifndef OCARINA_DATABASE_HPP #ifndef OCARINA_DATABASE_HPP
#define OCARINA_DATABASE_HPP #define OCARINA_DATABASE_HPP
#include <error.h>
template <class T> template <class T>
DatabaseEntry<T> :: DatabaseEntry() Database<T> :: Database(std::string filepath)
: valid(false)
{
}
template <class T, class U>
Database<T, U> :: Database(std::string filepath)
: _size(0), file(filepath, FILE_TYPE_DATA) : _size(0), file(filepath, FILE_TYPE_DATA)
{ {
} }
template <class T, class U> template <class T>
Database<T, U> :: ~Database() Database<T> :: ~Database()
{ {
} }
template <class T, class U> template <class T>
void Database<T, U> :: save() void Database<T> :: save()
{ {
if (file.open(OPEN_WRITE) == false) try {
file.open(OPEN_WRITE);
} catch (int error) {
return; return;
}
file << db.size() << std::endl; file << db.size() << std::endl;
for (unsigned int i = 0; i < db.size(); i++) { for (unsigned int i = 0; i < db.size(); i++) {
@ -43,12 +40,16 @@ void Database<T, U> :: save()
file.close(); file.close();
} }
template <class T, class U> template <class T>
void Database<T, U> :: load() void Database<T> :: load()
{ {
unsigned int db_size; unsigned int db_size;
if (file.open(OPEN_READ) == false)
try {
file.open(OPEN_READ);
} catch (int error) {
return; return;
}
file >> db_size; file >> db_size;
db.resize(db_size); db.resize(db_size);
@ -56,7 +57,7 @@ void Database<T, U> :: load()
file >> db[i].valid; file >> db[i].valid;
if (db[i].valid == true) { if (db[i].valid == true) {
db[i].read(file); db[i].read(file);
keys.insert(std::pair<std::string, unsigned int>(db[i].primary_key(), i)); keys.insert(std::pair<std::string, unsigned int>(db[i].primary_key, i));
_size++; _size++;
} }
} }
@ -64,17 +65,17 @@ void Database<T, U> :: load()
file.close(); file.close();
} }
#ifdef CONFIG_DEBUG #ifdef CONFIG_TEST
template <class T, class U> template <class T>
void Database<T, U> :: clear() void Database<T> :: clear()
{ {
db.clear(); db.clear();
keys.clear(); keys.clear();
_size = 0; _size = 0;
} }
template <class T, class U> template <class T>
void Database<T, U> :: print() void Database<T> :: print()
{ {
:: print("Allocated rows: %u\n", db.size()); :: print("Allocated rows: %u\n", db.size());
:: print("Valid rows: %u\n", _size); :: print("Valid rows: %u\n", _size);
@ -87,8 +88,8 @@ void Database<T, U> :: print()
} }
} }
template <class T, class U> template <class T>
void Database<T, U> :: print_keys() void Database<T> :: print_keys()
{ {
std::map<const std::string, unsigned int>::iterator it; std::map<const std::string, unsigned int>::iterator it;
:: print("Found keys:"); :: print("Found keys:");
@ -96,15 +97,15 @@ void Database<T, U> :: print_keys()
:: print(" %s", it->first.c_str()); :: print(" %s", it->first.c_str());
:: print("\n"); :: print("\n");
} }
#endif /* CONFIG_DEBUG */ #endif /* CONFIG_TEST */
template <class T, class U> template <class T>
unsigned int Database<T, U> :: insert(T val) unsigned int Database<T> :: insert(T val)
{ {
unsigned int id; unsigned int id;
typename std::map<U, unsigned int>::iterator it; typename std::map<const std::string, unsigned int>::iterator it;
it = keys.find(val.primary_key()); it = keys.find(val.primary_key);
if (it != keys.end()) if (it != keys.end())
return it->second; return it->second;
@ -113,34 +114,34 @@ unsigned int Database<T, U> :: insert(T val)
*/ */
id = db.size(); id = db.size();
db.push_back(val); db.push_back(val);
keys.insert(std::pair<U, unsigned int>(val.primary_key(), id)); keys.insert(std::pair<const std::string, unsigned int>(val.primary_key, id));
db[id].valid = true; db[id].valid = true;
_size++; _size++;
return id; return id;
} }
template <class T, class U> template <class T>
void Database<T, U> :: remove(unsigned int id) void Database<T> :: remove(unsigned int id)
{ {
keys.erase(db[id].primary_key()); keys.erase(db[id].primary_key);
db[id].valid = false; db[id].valid = false;
_size--; _size--;
} }
template <class T, class U> template <class T>
unsigned int Database<T, U> :: size() unsigned int Database<T> :: size()
{ {
return _size; return _size;
} }
template <class T, class U> template <class T>
unsigned int Database<T, U> :: num_rows() unsigned int Database<T> :: num_rows()
{ {
return db.size(); return db.size();
} }
template <class T, class U> template <class T>
unsigned int Database<T, U> :: first() unsigned int Database<T> :: first()
{ {
for (unsigned int i = 0; i < db.size(); i++) { for (unsigned int i = 0; i < db.size(); i++) {
if (db[i].valid == true) if (db[i].valid == true)
@ -150,8 +151,8 @@ unsigned int Database<T, U> :: first()
return db.size(); return db.size();
} }
template <class T, class U> template <class T>
unsigned int Database<T, U> :: last() unsigned int Database<T> :: last()
{ {
if (_size == 0) if (_size == 0)
return db.size(); return db.size();
@ -164,8 +165,8 @@ unsigned int Database<T, U> :: last()
return db.size(); return db.size();
} }
template <class T, class U> template <class T>
unsigned int Database<T, U> :: next(unsigned int id) unsigned int Database<T> :: next(unsigned int id)
{ {
for (unsigned int i = id + 1; i < db.size(); i++) { for (unsigned int i = id + 1; i < db.size(); i++) {
if (db[i].valid == true) if (db[i].valid == true)
@ -175,25 +176,40 @@ unsigned int Database<T, U> :: next(unsigned int id)
return db.size(); return db.size();
} }
template <class T, class U> template <class T>
unsigned int Database<T, U> :: find_index(const std::string &key) bool Database<T> :: has_key(const std::string &key)
{ {
typename std::map<U, unsigned int>::iterator it; std::map<const std::string, unsigned int>::iterator it;
it = keys.find(key);
return it != keys.end();
}
template <class T>
unsigned int Database<T> :: find_index(const std::string &key)
{
std::map<const std::string, unsigned int>::iterator it;
it = keys.find(key); it = keys.find(key);
if (it == keys.end()) if (it == keys.end())
throw 0; throw -EEXIST;
return it->second; return it->second;
} }
template <class T, class U> template <class T>
T &Database<T, U> :: find(const std::string &key) T &Database<T> :: find(const std::string &key)
{ {
return db[find_index(key)]; unsigned int index = find_index(key);
if (db[index].valid == false)
throw -EINVAL;
return db[index];
} }
template <class T, class U> template <class T>
T &Database<T, U> :: operator[](unsigned int id) T &Database<T> :: operator[](unsigned int id)
{ {
if (id >= db.size())
throw -EEXIST;
else if (db[id].valid == false)
throw -EINVAL;
return db[id]; return db[id];
} }

View File

@ -3,13 +3,21 @@
*/ */
#include <database.h> #include <database.h>
DatabaseEntry :: DatabaseEntry()
: primary_key(""), valid(false)
{
}
IndexEntry :: IndexEntry() IndexEntry :: IndexEntry()
{ {
} }
IndexEntry :: IndexEntry(const std::string &k, unsigned int v) IndexEntry :: IndexEntry(const std::string &key, unsigned int v)
: key(k)
{ {
primary_key = key;
insert(v); insert(v);
} }
@ -17,15 +25,10 @@ IndexEntry :: ~IndexEntry()
{ {
} }
const std::string &IndexEntry :: primary_key()
{
return key;
}
void IndexEntry :: write(File &f) void IndexEntry :: write(File &f)
{ {
std::set<unsigned int>::iterator it; std::set<unsigned int>::iterator it;
f << key << std::endl << values.size() << " "; f << primary_key << std::endl << values.size() << " ";
for (it = values.begin(); it != values.end(); it++) for (it = values.begin(); it != values.end(); it++)
f << *it << " "; f << *it << " ";
} }
@ -34,13 +37,14 @@ void IndexEntry :: read(File &f)
{ {
unsigned int num, val; unsigned int num, val;
f >> key >> num; f >> primary_key >> num;
for (unsigned int i = 0; i < num; i++) { for (unsigned int i = 0; i < num; i++) {
f >> val; f >> val;
values.insert(val); values.insert(val);
} }
} }
#ifdef CONFIG_TEST
void IndexEntry :: print() void IndexEntry :: print()
{ {
std::set<unsigned int>::iterator it; std::set<unsigned int>::iterator it;
@ -52,6 +56,7 @@ void IndexEntry :: print()
} }
:: print("}"); :: print("}");
} }
#endif /* CONFIG_TEST */
void IndexEntry :: insert(unsigned int val) void IndexEntry :: insert(unsigned int val)
{ {

View File

@ -6,14 +6,12 @@
#include <sstream> #include <sstream>
class DBTest : public DatabaseEntry<const std::string> { class DBTest : public DatabaseEntry {
public: public:
unsigned int value; unsigned int value;
std::string key;
DBTest(); DBTest();
DBTest(unsigned int); DBTest(unsigned int);
const std::string &primary_key();
void write(File &); void write(File &);
void read(File &); void read(File &);
void print(); void print();
@ -29,7 +27,7 @@ DBTest :: DBTest(unsigned int val)
value = val; value = val;
ss << value; ss << value;
key = ss.str(); primary_key = ss.str();
} }
void DBTest :: write(File &file) void DBTest :: write(File &file)
@ -47,14 +45,9 @@ void DBTest :: print()
:: print("%u", value); :: print("%u", value);
} }
const std::string &DBTest :: primary_key()
{
return key;
}
void print_db(Database<DBTest> &db)
void print_db(Database<DBTest, const std::string> &db)
{ {
print("Database size: %u\n", db.size()); print("Database size: %u\n", db.size());
print("Num rows: %u\n", db.num_rows()); print("Num rows: %u\n", db.num_rows());
@ -65,14 +58,14 @@ void print_db(Database<DBTest, const std::string> &db)
print("db[%u] = %u\n", i, db[i].value); print("db[%u] = %u\n", i, db[i].value);
} }
void test_insertion(Database<DBTest, const std::string> &db) void test_insertion(Database<DBTest> &db)
{ {
for (unsigned int i = 1; i <= 100000; i++) for (unsigned int i = 1; i <= 100000; i++)
db.insert(DBTest(i)); db.insert(DBTest(i));
print_db(db); print_db(db);
} }
void test_deletion(Database<DBTest, const std::string> &db) void test_deletion(Database<DBTest> &db)
{ {
for (unsigned int i = db.first(); i < db.num_rows(); i = db.next(i)) { for (unsigned int i = db.first(); i < db.num_rows(); i = db.next(i)) {
db.remove(i); db.remove(i);
@ -87,7 +80,7 @@ void test_deletion(Database<DBTest, const std::string> &db)
void test_0() void test_0()
{ {
print("Test 0\n"); print("Test 0\n");
Database<DBTest, const std::string> db("test.db"); Database<DBTest> db("test.db");
test_insertion(db); test_insertion(db);
test_deletion(db); test_deletion(db);
@ -102,7 +95,7 @@ void test_0()
void test_1() void test_1()
{ {
print("\nTest 1\n"); print("\nTest 1\n");
Database<DBTest, const std::string> db("test.db"); Database<DBTest> db("test.db");
db.load(); db.load();
print_db(db); print_db(db);
} }
@ -113,7 +106,7 @@ void test_1()
void test_2() void test_2()
{ {
print("\nTest 2\n"); print("\nTest 2\n");
Database<DBTest, const std::string> db(""); Database<DBTest> db("");
test_insertion(db); test_insertion(db);
db.save(); db.save();
@ -125,7 +118,7 @@ void test_2()
void test_3() void test_3()
{ {
print("\nTest 3\n"); print("\nTest 3\n");
Database<DBTest, const std::string> db(""); Database<DBTest> db("");
db.load(); db.load();
} }
@ -135,7 +128,7 @@ void test_3()
void test_4() void test_4()
{ {
print("\nTest 4\n"); print("\nTest 4\n");
Database<DBTest, const std::string> db(""); Database<DBTest> db("");
for (unsigned int i = 0; i < 100; i++) for (unsigned int i = 0; i < 100; i++)
db.insert(DBTest(i % 5)); db.insert(DBTest(i % 5));
@ -149,7 +142,7 @@ void test_4()
void test_5() void test_5()
{ {
print("\nTest 5\n"); print("\nTest 5\n");
Database<DBTest, const std::string> db(""); Database<DBTest> db("");
for (unsigned int i = 0; i < 10; i++) for (unsigned int i = 0; i < 10; i++)
db.insert(DBTest(i)); db.insert(DBTest(i));
db.print(); db.print();
@ -161,7 +154,7 @@ void test_5()
void test_6() void test_6()
{ {
print("\nTest 6\n"); print("\nTest 6\n");
Database<DBTest, const std::string> db(""); Database<DBTest> db("");
for (unsigned int i = 0; i < 10; i++) for (unsigned int i = 0; i < 10; i++)
db.insert(DBTest(i)); db.insert(DBTest(i));
print_db(db); print_db(db);
@ -175,7 +168,7 @@ void test_6()
void test_7() void test_7()
{ {
print("\nTest 7\n"); print("\nTest 7\n");
Database<DBTest, const std::string> db(""); Database<DBTest> db("");
print_db(db); print_db(db);
for (unsigned int i = 0; i < 10; i++) for (unsigned int i = 0; i < 10; i++)

View File

@ -4,7 +4,7 @@
#include <database.h> #include <database.h>
#include <print.h> #include <print.h>
void print_index(Database<IndexEntry, const std::string> &index) void print_index(Database<IndexEntry> &index)
{ {
std::set<std::string>::iterator s_it; std::set<std::string>::iterator s_it;
std::set<unsigned int>::iterator u_it; std::set<unsigned int>::iterator u_it;
@ -13,7 +13,7 @@ void print_index(Database<IndexEntry, const std::string> &index)
index.print_keys(); index.print_keys();
for (unsigned int i = index.first(); i != index.num_rows(); i = index.next(i)) { for (unsigned int i = index.first(); i != index.num_rows(); i = index.next(i)) {
print("index[%s] = ", index[i].key.c_str()); print("index[%s] = ", index[i].primary_key.c_str());
index[i].print(); index[i].print();
print("\n"); print("\n");
} }
@ -21,7 +21,7 @@ void print_index(Database<IndexEntry, const std::string> &index)
print("\n"); print("\n");
} }
void populate_index(Database<IndexEntry, const std::string> &index) void populate_index(Database<IndexEntry> &index)
{ {
std::string key_str; std::string key_str;
@ -32,17 +32,19 @@ void populate_index(Database<IndexEntry, const std::string> &index)
} }
} }
void remove_keys(Database<IndexEntry, const std::string> &index) void remove_keys(Database<IndexEntry> &index)
{ {
std::string key_str; std::string key_str;
for (char key = 'a'; key <= 'z'; key+=2) { for (char key = 'a'; key <= 'z'; key+=2) {
key_str = key; key_str = key;
index.remove(index.find_index(key_str)); index.remove(index.find_index(key_str));
if (index.has_key(key_str))
print("Failed to remove key!\n");
} }
} }
void remove_values(Database<IndexEntry, const std::string> &index) void remove_values(Database<IndexEntry> &index)
{ {
std::string key_str; std::string key_str;
unsigned int limit = 0; unsigned int limit = 0;
@ -52,8 +54,11 @@ void remove_values(Database<IndexEntry, const std::string> &index)
for (unsigned int i = 0; i < limit; i++) for (unsigned int i = 0; i < limit; i++)
index_remove(index, key_str, i); index_remove(index, key_str, i);
limit++; limit++;
if (limit == 11) if (limit == 11) {
limit = 0; limit = 0;
if (index.has_key(key_str))
print("Failed to remove key!\n");
}
} }
} }
@ -63,7 +68,7 @@ void remove_values(Database<IndexEntry, const std::string> &index)
void test_0() void test_0()
{ {
print("Test 0\n"); print("Test 0\n");
Database<IndexEntry, const std::string> index(""); Database<IndexEntry> index("");
populate_index(index); populate_index(index);
print_index(index); print_index(index);
@ -75,7 +80,7 @@ void test_0()
void test_1() void test_1()
{ {
print("Test 1\n"); print("Test 1\n");
Database<IndexEntry, const std::string> index(""); Database<IndexEntry> index("");
populate_index(index); populate_index(index);
remove_keys(index); remove_keys(index);
@ -88,7 +93,7 @@ void test_1()
void test_2() void test_2()
{ {
print("Test 2\n"); print("Test 2\n");
Database<IndexEntry, const std::string> index(""); Database<IndexEntry> index("");
populate_index(index); populate_index(index);
remove_values(index); remove_values(index);
@ -101,7 +106,7 @@ void test_2()
void test_3() void test_3()
{ {
print("Test 3\n"); print("Test 3\n");
Database<IndexEntry, const std::string> index("test.idx"); Database<IndexEntry> index("test.idx");
populate_index(index); populate_index(index);
remove_values(index); remove_values(index);
@ -114,7 +119,7 @@ void test_3()
void test_4() void test_4()
{ {
print("Test 4\n"); print("Test 4\n");
Database<IndexEntry, const std::string> index("test.idx"); Database<IndexEntry> index("test.idx");
index.load(); index.load();
print_index(index); print_index(index);
@ -126,7 +131,7 @@ void test_4()
void test_5() void test_5()
{ {
print("Test 5\n"); print("Test 5\n");
Database<IndexEntry, const std::string> index(""); Database<IndexEntry> index("");
print("index[nokey].size() = "); print("index[nokey].size() = ");
try { try {
print("%u\n", index.find("nokey").values.size()); print("%u\n", index.find("nokey").values.size());