[Debtags-commits] [svn] r1446 - central-database/trunk/c-tdb

Erich Schubert erich at costa.debian.org
Sun Oct 30 18:33:10 UTC 2005


Author: erich
Date: Sun Oct 30 18:33:07 2005
New Revision: 1446

Added:
   central-database/trunk/c-tdb/dbid.h
   central-database/trunk/c-tdb/dbstr.h
   central-database/trunk/c-tdb/zero-copy-serialize.h
Removed:
   central-database/trunk/c-tdb/hierarchy.cc
   central-database/trunk/c-tdb/mytdb.cc
   central-database/trunk/c-tdb/mytdb.h
Modified:
   central-database/trunk/c-tdb/Makefile
   central-database/trunk/c-tdb/browse.cc
   central-database/trunk/c-tdb/etdb.h
   central-database/trunk/c-tdb/idlist.cc
   central-database/trunk/c-tdb/idlist.h
   central-database/trunk/c-tdb/load-available.cc
   central-database/trunk/c-tdb/load-tags.cc
   central-database/trunk/c-tdb/load-vocabulary.cc
   central-database/trunk/c-tdb/mappkgtag.cc
   central-database/trunk/c-tdb/mappkgtag.h
   central-database/trunk/c-tdb/pkgdb.cc
   central-database/trunk/c-tdb/pkgdb.h
   central-database/trunk/c-tdb/query.cc
   central-database/trunk/c-tdb/vocdb.cc
   central-database/trunk/c-tdb/vocdb.h
Log:
rewrote a lot of code for new C++ templates

Modified: central-database/trunk/c-tdb/Makefile
==============================================================================
--- central-database/trunk/c-tdb/Makefile	(original)
+++ central-database/trunk/c-tdb/Makefile	Sun Oct 30 18:33:07 2005
@@ -8,15 +8,19 @@
 clean:
 	-rm -f *.o *~ $(APPS)
 
-reinit: $(APPS)
+reinit: load-available load-vocabulary load-tags
 	-rm -f database/*.db
 	./load-available < testdata/available
 	./load-vocabulary < testdata/vocabulary
 	./load-tags < testdata/tags-current
 
-load-available: load-available.o mytdb.o pkgdb.o chunkreader.o
-load-vocabulary: load-vocabulary.o mytdb.o vocdb.o chunkreader.o
-load-tags: load-tags.o mytdb.o pkgdb.o vocdb.o mappkgtag.o idlist.o
-query: query.o mytdb.o pkgdb.o vocdb.o mappkgtag.o idlist.o
-browse: browse.o mytdb.o pkgdb.o vocdb.o mappkgtag.o idlist.o
-hierarchy: hierarchy.o mytdb.o pkgdb.o vocdb.o mappkgtag.o idlist.o
+idlist.o: idlist.h etdb.h dbid.h dbstr.h
+pkgdb.o: etdb.h dbid.h dbstr.h
+vocdb.o: etdb.h dbid.h dbstr.h
+mappkgtag.o: etdb.h dbid.h dbstr.h
+
+load-available: load-available.o pkgdb.o chunkreader.o
+load-vocabulary: load-vocabulary.o vocdb.o chunkreader.o
+load-tags: load-tags.o pkgdb.o vocdb.o mappkgtag.o idlist.o
+query: query.o pkgdb.o vocdb.o mappkgtag.o idlist.o
+browse: browse.o pkgdb.o vocdb.o mappkgtag.o idlist.o

Modified: central-database/trunk/c-tdb/browse.cc
==============================================================================
--- central-database/trunk/c-tdb/browse.cc	(original)
+++ central-database/trunk/c-tdb/browse.cc	Sun Oct 30 18:33:07 2005
@@ -2,22 +2,22 @@
 #include "pkgdb.h"
 #include "vocdb.h"
 #include "mappkgtag.h"
+#include "dbid.h"
 #include <iostream>
 #include <map>
 #include <set>
 #include <vector>
+#include <cmath>
 
 using namespace std;
 
-typedef pair< unsigned int, u_int32_t > cnt_pkg_t;
+typedef pair< unsigned int, dbid > cnt_pkg_t;
 struct sorter {
   bool operator()(const cnt_pkg_t p1, const cnt_pkg_t p2) const {
     return (p1.first != p2.first) ? (p1.first > p2.first) : (p1.second < p2.second);
   }
 };
 
-
-
 int main(int argc, char* argv[]) {
 	/* open databases */
 	PkgDB dbpkg(O_RDONLY);
@@ -26,84 +26,87 @@
 	MapDB maptp(MAP_ID_TAG_PKG_DB, O_RDONLY);
 
 	/* find matching packages... */
-	idlist* result = NULL;
+	IdList* result = NULL;
 	for (int i=1; i < argc; i++) {
 		try {
-			u_int32_t entry = dbvoc.name_to_id.get_char_u32(argv[i]);
+			dbid entry = dbvoc.name_to_id.get(argv[i]);
 			if (!result) {
-				result = maptp.query(entry);
+				IdList temp = maptp.get(entry);
+				result = new IdList(temp);
 			} else {
-				idlist* temp = maptp.query(entry);
+				IdList temp = maptp.get(entry);
 				result->join(temp);
-				temp->destroy();
+				temp.free_data();
 			}
-		} catch (MyTDB::KeyNotFoundError) {
+		} catch (etdb<dbstr,dbid>::KeyNotFoundError) {
 			cout << "Unknown tag specified: '" << argv[i] << "'" << endl;
 			exit(1);
 		}
 	}
-	if (!result || (result->size == 0)) {
+	if (!result || (result->size() == 0)) {
 		/* FIXME: use a list of all packages here */
 		cout << "No matching packages found." << endl;
 		exit(1);
 	}
 
 	/* Now do the magic choice reduction */
-	vector< u_int32_t > final_tags;
+	vector< dbid > final_tags;
 
 	do {
 		/* for all packages, find tags assigned to them */
-		map<u_int32_t, unsigned int> tags;
-		for (size_t i=0; i < result->size; i++) {
-			idlist* t = mappt.query(result->data[i]);
-			for (size_t j=0; j < t->size; j++)
-				if (tags.find(t->data[j]) == tags.end()) {
-					tags[t->data[j]] = 1;
+		map<dbid, unsigned int> tags;
+		for (size_t i=0; i < result->size(); i++) {
+			IdList t = mappt.get((*result)[i]);
+			for (size_t j=0; j < t.size(); j++)
+				if (tags.find(t[j]) == tags.end()) {
+					tags[t[j]] = 1;
 				} else {
-					tags[t->data[j]] = 1 + tags[t->data[j]];
+					tags[t[j]] = 1 + tags[t[j]];
 				}
-			t->destroy();
+			t.free_data();
 		}
-		unsigned int min = 5;
-		unsigned int max = result->size * 9 / 10;
+		long destval = (long int) floor(result->size() * .5);
+		int bestval = 0;
+		dbid besttag(~0);
 		/* sorting and filtering */
-		set< cnt_pkg_t, sorter > choices;
-		for (map<u_int32_t, unsigned int>::iterator i = tags.begin(); i != tags.end(); i++) {
-			if (i->second > max) continue;
-			if (i->second < min) continue;
-			/* do we already have this tag? */
-			{	bool found = false;
-				for (vector< u_int32_t >::iterator j=final_tags.begin(); j != final_tags.end(); j++) 
-					if (i->first == *j) { found = true; break; }
+		for (map<dbid, unsigned int>::iterator i = tags.begin(); i != tags.end(); i++)
+			if ( labs(destval - i->second) < labs(destval - bestval) ) {
+				bool found = false;
+				for (vector< dbid >::iterator j=final_tags.begin(); j != final_tags.end(); j++) 
+					if (i->first.id == j->id) { found = true; break; }
 				if (found) continue;
+				bestval = i->second;
+				besttag = i->first;
 			}
-			/* add it to the list */
-			choices.insert( make_pair(i->second, i->first) );
-		}
-		if (choices.empty()) break;
-		u_int32_t win_tag = choices.begin()->second;
-		final_tags.push_back(win_tag);
-		idlist* t = maptp.query(win_tag);
+		if (besttag == dbid(~0)) break;
+		final_tags.push_back(besttag);
+		IdList t = maptp.get(besttag);
 		result->subtract(t);
-		t->destroy();
+		t.free_data();
 		
-	} while ( result->size > 5 );
+	} while ( result->size() > 5 );
 	/* output */
-	for (vector<u_int32_t>::iterator i = final_tags.begin(); i != final_tags.end(); i++) {
+	for (vector<dbid>::iterator i = final_tags.begin(); i != final_tags.end(); i++) {
 		if (i == final_tags.begin()) cout << "Subgroups:" << endl;
-		vocinfo* ti = dbvoc.get_entry(*i);
-		if (!ti) { cerr << "Unknown voc id: " << *i << endl; continue; }
-		cout << " " << ti->name() << " " << ti->desc() << endl;
-		free(ti);
+		try {
+			VocInfo ti = dbvoc.get(*i);
+			cout << " " << ti.name() << " " << ti.desc() << endl;
+			ti.free_data();
+		} catch (etdb<dbid,VocInfo>::KeyNotFoundError e) {
+			cerr << "Unknown voc id: " << i->id << endl;
+		}
 	}
 	/* output remaining packages */
-	for (size_t i = 0; i < result->size; i++) {
+	for (size_t i = 0; i < result->size(); i++) {
 		if (i == 0) cout << "Matching packages:" << endl;
-		pkginfo* pi = dbpkg.get_entry(result->data[i]);
-		if (!pi) { cerr << "Unknown pkg id: " << result->data[i] << endl; continue; }
-		cout << " " << pi->name() << " " << pi->desc() << endl;
-		free(pi);
+		try {
+			PkgInfo pi = dbpkg.get((*result)[i]);
+			cout << " " << pi.name() << " " << pi.desc() << endl;
+			pi.free_data();
+		} catch (etdb<dbid,PkgInfo>::KeyNotFoundError e) {
+			cerr << "Unknown pkg id: " << (*result)[i].id << endl;
+		}
 	}
-	result->destroy();
+	result->free_data();
 	return(0);
 }

Modified: central-database/trunk/c-tdb/etdb.h
==============================================================================
--- central-database/trunk/c-tdb/etdb.h	(original)
+++ central-database/trunk/c-tdb/etdb.h	Sun Oct 30 18:33:07 2005
@@ -8,14 +8,9 @@
 #include <string.h>
 #include <iostream>
 
-#define MAGICKEY "\01first-free-num"
-
-/*** function templates to calculate object size ***/
-template<class TYPE>
-size_t const etdb_get_size(TYPE d);
+#include "zero-copy-serialize.h"
 
-template<class TYPE>
-const char* const etdb_get_data(TYPE d);
+#define MAGICKEY "\01first-free-num"
 
 /*** TDB class template ***/
 template<class K, class V>
@@ -27,16 +22,15 @@
 	class DBOpenError {};
 	class KeyNotFoundError {};
 
-	etdb(const char* filename);
-	etdb(const char* filename, unsigned int flags);
+	etdb(const char* filename, unsigned int flags = O_RDONLY);
 	~etdb();
 
 	void close();
 
 	/* query for existence */
 	bool has_key(const K key);
-	/* set will replace existing values */
-	int set(const K k, const V v);
+	/* set with given flag */
+	int set(const K k, const V v, int flag = TDB_REPLACE);
 	/* add won't overwrite existing values */
 	int add(const K k, const V v);
 	/* get the value of a key */
@@ -52,13 +46,6 @@
 /*** implementation of etdb template ***/
 
 template<class K, class V>
-etdb<K, V>::etdb(const char* filename) {
-	db = tdb_open(filename, 0, 0, O_RDONLY, 0666);
-	if (!db) throw DBOpenError();
-	open = true;
-}
-
-template<class K, class V>
 etdb<K, V>::etdb(const char* filename, unsigned int flags) {
 	db = tdb_open(filename, 0, 0, flags, 0666);
 	if (!db) throw DBOpenError();
@@ -78,59 +65,39 @@
 
 template<class K, class V>
 bool etdb<K, V>::has_key(const K key) {
-	TDB_DATA k;
-	k.dptr  = etdb_get_data<K>(key);
-	k.dsize = etdb_get_size<K>(key);
-	return tdb_exists(db, k);
+	zcser k = key.serialize();
+	return tdb_exists(db, (TDB_DATA)k);
 }
 
 template<class K, class V>
 void etdb<K, V>::lock() {
-	// The lockkeys call has disappeared from the lib,
-	// albeit it's still in the header file...
-	//TDB_DATA k[1];
-	//k[0].dptr  = etdb_get_data<K>(key);
-	//k[0].dsize = etdb_get_size<K>(key);
-	//tdb_lockkeys(db, 1, k);
 	tdb_lockall(db);
 }
 
 template<class K, class V>
 void etdb<K, V>::unlock() {
-	// The lockkeys call has disappeared from the lib,
-	// albeit it's still in the header file...
-	//tdb_unlockkeys(db);
 	tdb_unlockall(db);
 }
 
 template<class K, class V>
-int etdb<K, V>::set(const K key, const V value) {
-	TDB_DATA k, v;
-	k.dptr  = (char*) etdb_get_data<K>(key);
-	k.dsize = etdb_get_size<K>(key);
-	v.dptr  = (char*) etdb_get_data<V>(value);
-	v.dsize = etdb_get_size<V>(value);
-	return tdb_store(db, k, v, TDB_REPLACE);
+int etdb<K, V>::set(const K key, const V value, int flag) {
+	zcser k = key.serialize();
+	zcser v = value.serialize();
+	return tdb_store(db, k, v, flag);
 }
 template<class K, class V>
 int etdb<K, V>::add(const K key, const V value) {
-	TDB_DATA k, v;
-	k.dptr  = (char*) etdb_get_data<K>(key);
-	k.dsize = etdb_get_size<K>(key);
-	v.dptr  = (char*) etdb_get_data<V>(value);
-	v.dsize = etdb_get_size<V>(value);
-	return tdb_store(db, k, v, TDB_INSERT);
+	return set(key, value, TDB_INSERT);
 }
 
 template<class K, class V>
 V etdb<K, V>::get(const K key) throw(KeyNotFoundError) {
-	TDB_DATA k, v;
-	k.dptr  = (char*) etdb_get_data<K>(key);
-	k.dsize = etdb_get_size<K>(key);
+	zcser k = key.serialize();
+	TDB_DATA v;
 	v = tdb_fetch(db, k);
 	if (!v.dptr) throw KeyNotFoundError();
 
-	return (V) v.dptr;
+	return V( (zcser) v);
 }
 
 template<class K, class V>
@@ -143,36 +110,13 @@
 		try {
 			newid = get(MAGICKEY);
 		} catch (KeyNotFoundError k) {
-			u_int32_t start = 0;
-			set(MAGICKEY, &start);
-			newid = &start;
+			set(MAGICKEY, V(1)); /* TODO: add error handling */
 		}
 		add(key, newid); /* TODO: add error handling */
-		++ *newid; /* TODO: use a different, more extensible way, of finding the next id */
-		set(MAGICKEY, newid); /* TODO: add error handling */
-		-- *newid;
+		set(MAGICKEY, newid.nextid()); /* TODO: add error handling */
 		unlock();
 		return newid;
 	}
 }
 
-/*** function templates instantiations ***/
-template<>
-size_t const etdb_get_size(const char* d) { return strlen(d)+1; }
-
-template<>
-const char* const etdb_get_data(const char* d) { return (const char*) d; }
-
-template<>
-size_t const etdb_get_size(char* d) { return strlen(d)+1; }
-
-template<>
-const char* const etdb_get_data(char* d) { return (char*) d; }
-
-template<>
-size_t const etdb_get_size(u_int32_t* d) { return sizeof(u_int32_t); }
-
-template<>
-const char* const etdb_get_data(u_int32_t* d) { return (const char*) d; }
-
 #endif

Modified: central-database/trunk/c-tdb/idlist.cc
==============================================================================
--- central-database/trunk/c-tdb/idlist.cc	(original)
+++ central-database/trunk/c-tdb/idlist.cc	Sun Oct 30 18:33:07 2005
@@ -2,73 +2,109 @@
 #include <iostream>
 using namespace std;
 
-idlist* idlist::make(size_t size) {
-	idlist* l = (idlist*) calloc(1,sizeof(idlist) + size*sizeof(int));
-	l->size = size;
-	return l;
+/* create a new list with enough memory for size elements */
+IdList::IdList(size_t size) {
+	memsize = size;
+	data = (idlist*) calloc(1, sizeof(idlist) + size*sizeof(dbid));
+	data->size = 0;
+}
+/* make a list by casting the serialization */
+IdList::IdList(zcser ser) {
+	data = (idlist*) ser.dptr;
+	assert(data);
+	memsize = (ser.dsize - sizeof(idlist)) / sizeof(dbid);
+	assert(memsize == data->size);
+}
+/* create a new list by inserting an element */
+IdList::IdList(IdList& list, size_t pos, dbid newid) {
+	assert(list.data);
+	assert(pos <= list.data->size);
+	/* initialize with new size */
+	memsize = list.data->size + 1;
+	data = (idlist*) calloc(1, sizeof(idlist) + memsize*sizeof(dbid));
+	data->size = 0;
+	/* make sure it worked */
+	assert(data);
+	memcpy(&(data->data[0]), &(list.data->data[0]), pos*sizeof(dbid));
+	data->data[pos] = newid;
+	memcpy(&(data->data[pos+1]), &(list.data->data[pos]), (list.data->size - pos)*sizeof(dbid));
+	data->size = list.data->size + 1;
+}
+/* duplicat a list ref */
+IdList::IdList(const IdList& list) {
+	data = list.data;
+	memsize = list.memsize;
+}
+/* free data */
+void IdList::free_data() {
+	free(data); data = NULL; memsize = 0;
+}
+/* serialize */
+zcser IdList::serialize() const {
+	return zcser((char*) data, sizeof(idlist) + sizeof(dbid) * data->size);
+}
+/* accessor functions */
+size_t IdList::size() const {
+	assert(data);
+	return data->size;
+}
+dbid IdList::operator[](size_t pos) {
+	assert(pos < data->size);
+	return data->data[pos];
 }
-
-idlist* idlist::make(size_t size, u_int32_t* data) {
-	idlist* l = (idlist*) malloc(sizeof(idlist) + size*sizeof(int));
-	l->size = 1;
-	memcpy(&(l->data[0]), data, size*sizeof(int));
-	l->data[size] = 0;
-	return l;
-}
-void idlist::destroy() {
-	free(this);
-}
-size_t idlist::memsize() {
-	return sizeof(idlist) + sizeof(int) * size;
-}
-
-idlist* idlist::clone() {
-	idlist* l = (idlist*) malloc(sizeof(idlist) + size * sizeof(int));
-	memcpy(l, this, sizeof(idlist) + size * sizeof(int));
-	return l;
-}
-
-int idlist::find(u_int32_t id) {
+/* find, return -insert position if not found */
+int IdList::find(dbid id) const {
 	size_t pos=0;
-	for (pos=0; pos < size; pos++) {
-		if (data[pos] == id) return +1+pos;
-		if (data[pos] > id)  return -pos;
+	assert(data);
+	for (pos=0; pos < data->size; pos++) {
+		if (data->data[pos] == id) return +1+pos;
+		if (data->data[pos] > id)  return -pos;
 	}
-	return -size;
+	return -(data->size);
 }
-
-void idlist::join(idlist* list) {
+/* join with another list */
+void IdList::join(IdList& list) {
 	size_t pos1  = 0;
 	size_t pos1w = 0;
 	size_t pos2  = 0;
-	while ((pos1 < size) && (pos2 < list->size)) {
-		if (data[pos1] == list->data[pos2]) {
-			data[pos1w] = data[pos1]; pos1w++;
+	assert(data && list.data);
+	while ((pos1 < data->size) && (pos2 < list.data->size)) {
+		if (data->data[pos1] == list.data->data[pos2]) {
+			data->data[pos1w] = data->data[pos1]; pos1w++;
 			pos1++; pos2++;
-		} else if (data[pos1] < list->data[pos2]) {
+		} else if (data->data[pos1] < list.data->data[pos2]) {
 			pos1++;
 		} else {
 			pos2++;
 		}
 	}
-	data[pos1w]=0;
-	size = pos1w;
+	data->data[pos1w]=0;
+	data->size = pos1w;
 }
-
-void idlist::subtract(idlist* list) {
+/* subtract a different list */
+void IdList::subtract(IdList& list) {
 	size_t pos1  = 0;
 	size_t pos1w = 0;
 	size_t pos2  = 0;
-	while ((pos1 < size) && (pos2 < list->size)) {
-		if (data[pos1] == list->data[pos2]) {
+	assert(data && list.data);
+	while ((pos1 < data->size) && (pos2 < list.data->size)) {
+		if (data->data[pos1] == list.data->data[pos2]) {
 			pos1++; pos2++;
-		} else if (data[pos1] < list->data[pos2]) {
-			data[pos1w] = data[pos1]; pos1w++;
+		} else if (data->data[pos1] < list.data->data[pos2]) {
+			data->data[pos1w] = data->data[pos1]; pos1w++;
 			pos1++;
 		} else {
 			pos2++;
 		}
 	}
-	data[pos1w]=0;
-	size = pos1w;
+	data->data[pos1w]=0;
+	data->size = pos1w;
+}
+/* clone a list */
+IdList clone(const IdList& c) {
+	assert(c.data);
+	IdList n(c.data->size);
+	assert(n.data);
+	memcpy(n.data, c.data, sizeof(idlist) + c.data->size * sizeof(dbid));
+	return n;
 }

Modified: central-database/trunk/c-tdb/idlist.h
==============================================================================
--- central-database/trunk/c-tdb/idlist.h	(original)
+++ central-database/trunk/c-tdb/idlist.h	Sun Oct 30 18:33:07 2005
@@ -2,19 +2,46 @@
 #define IDLIST_H
 #include <stdlib.h>
 #include <string.h>
+#include "dbid.h"
 
 class idlist {
 public:
 	size_t size;
-	u_int32_t data[1];
+	dbid data[1];
+};
+
+class IdList {
+public:
+	idlist*	data;
+	size_t	memsize;
+
+	/* create a new list, allocating mem for size entries */
+	IdList(size_t size);
+	/* create (cast) list from serialization */
+	IdList(zcser ser);
+	/* create by inserting an element at a given position */
+	IdList(IdList& list, size_t pos, dbid newid);
+	/* copy, not copying data */
+	IdList(const IdList& list);
+	
+	/* serialize */
+	zcser serialize() const;
 
-	static idlist* make(size_t size);
-	static idlist* make(size_t size, u_int32_t* data);
-	idlist* clone();
-	void destroy();
-	size_t memsize();
-	int find(u_int32_t id);
-	void join(idlist* list);
-	void subtract(idlist* list);
+	/* accessor function */
+	size_t size() const;
+	dbid operator[](size_t pos);
+
+	/* free data */
+	void free_data();
+	/* find element */
+	int find(dbid id) const;
+	/* join with other list */
+	void join(IdList& list);
+	/* subtract elements of other list */
+	void subtract(IdList& list);
 };
+
+/* clone IdList, copying memory */
+IdList clone(const IdList& c);
+
 #endif

Modified: central-database/trunk/c-tdb/load-available.cc
==============================================================================
--- central-database/trunk/c-tdb/load-available.cc	(original)
+++ central-database/trunk/c-tdb/load-available.cc	Sun Oct 30 18:33:07 2005
@@ -42,7 +42,7 @@
 		longdesc = "No detailed description available.";
 	}
 
-	db.add_entry(name, desc, longdesc);
+	db.add(name, desc, longdesc);
 	free_taglist(tl);
 }
 

Modified: central-database/trunk/c-tdb/load-tags.cc
==============================================================================
--- central-database/trunk/c-tdb/load-tags.cc	(original)
+++ central-database/trunk/c-tdb/load-tags.cc	Sun Oct 30 18:33:07 2005
@@ -36,20 +36,20 @@
 	vector<char*>* pkgs = split(buffer, ',');
 	vector<char*>* tags = split(sep, ',');
 
-	vector<int> pkgsi;
+	vector<dbid> pkgsi;
 	vector<char*>::iterator ip;
 	for (ip = pkgs->begin(); ip != pkgs->end(); ip++)
 		pkgsi.push_back( dbpkg.name_to_id.enumerate(*ip) );
 	delete pkgs;
 
-	vector<int> tagsi;
+	vector<dbid> tagsi;
 	vector<char*>::iterator it;
 	for (it = tags->begin(); it != tags->end(); it++)
 		tagsi.push_back( dbvoc.name_to_id.enumerate(*it) );
 	delete tags;
 
-	for (vector<int>::iterator i1 = pkgsi.begin(); i1 != pkgsi.end(); i1++)
-		for (vector<int>::iterator i2 = tagsi.begin(); i2 != tagsi.end(); i2++) {
+	for (vector<dbid>::iterator i1 = pkgsi.begin(); i1 != pkgsi.end(); i1++)
+		for (vector<dbid>::iterator i2 = tagsi.begin(); i2 != tagsi.end(); i2++) {
 			mappt.add_to_list(*i1, *i2);
 			maptp.add_to_list(*i2, *i1);
 		}

Modified: central-database/trunk/c-tdb/load-vocabulary.cc
==============================================================================
--- central-database/trunk/c-tdb/load-vocabulary.cc	(original)
+++ central-database/trunk/c-tdb/load-vocabulary.cc	Sun Oct 30 18:33:07 2005
@@ -13,7 +13,7 @@
 	char* desc = NULL;
 	char* longdesc = NULL;
 	int flags = 0;
-	int parent = 0;
+	dbid parent;
 	taglist* i = NULL;
 
 	if (!buffer) return;
@@ -53,9 +53,9 @@
 		*split = '\0';
 		parent = db.name_to_id.enumerate(name);
 		*split = ':';
-	} else parent = -1;
+	} else parent = dbid(~0);
 
-	db.add_entry(name, desc, desc, flags, parent);
+	db.add(name, desc, desc, flags, parent);
 	free_taglist(tl);
 }
 

Modified: central-database/trunk/c-tdb/mappkgtag.cc
==============================================================================
--- central-database/trunk/c-tdb/mappkgtag.cc	(original)
+++ central-database/trunk/c-tdb/mappkgtag.cc	Sun Oct 30 18:33:07 2005
@@ -4,60 +4,30 @@
 
 using namespace std;
 
-MapDB::MapDB(const char* filename, int flags) : MyTDB(filename, flags) {}
+MapDB::MapDB(const char* filename, int flags) : etdb<dbid,IdList>(filename, flags) {}
 
-void MapDB::add_to_list(u_int32_t key, u_int32_t value) {
-	TDB_DATA k, d;
-	k.dptr  = (char*) &key;
-	k.dsize = sizeof(u_int32_t);
+void MapDB::add_to_list(dbid key, dbid value) {
+	//zcser k = key.serialize();
 
-	d = tdb_fetch(db, k);
-	if (d.dptr) {
-		// The lockkeys call has disappeared from the lib,
-		// albeit it's still in the header file...
-		//tdb_lockkeys(db, 1, &k);
-		tdb_lockall(db);
-		idlist* il = (idlist*) d.dptr;
-		if (d.dsize != il->memsize()) {
-			cerr << "Size is " << d.dsize << " but memsize is " << il->memsize() << " ( " << il->size << ")" << endl;
-			throw "Size information does not match";
-		}
-		int pos = il->find(value);
+	try {
+		IdList il = get(key);
+		lock();
+		int pos = il.find(value);
 		if (pos <= 0) {
 			pos = abs(pos);
-			if (pos > (int)il->size) throw "Invalid position returned by idlist_find!";
-			idlist* ilneu = idlist::make(il->size + 1);
-			memcpy(&(ilneu->data[0]), &(il->data[0]), sizeof(int) * pos);
-			ilneu->data[pos] = value;
-			if (pos < (int)il->size)
-			memcpy(&(ilneu->data[pos+1]), &(il->data[pos]), sizeof(int) * (il->size - pos));
-
-			TDB_DATA newd;
-			newd.dptr  = (char*) ilneu;
-			newd.dsize = ilneu->memsize();
-			tdb_store(db, k, newd, TDB_REPLACE);
-			ilneu->destroy();
+			if (pos > (int) il.size()) throw "Invalid position returned by idlist_find!";
+			IdList ilneu(il, pos, value);
+			set(key, ilneu, TDB_REPLACE);
+			ilneu.free_data();
 		} else
-			cout << "Value " << value << " found at position " << pos << " in key " << key << endl;
-		free(d.dptr);
-		// The unlockkeys call has disappeared from the lib,
-		// albeit it's still in the header file...
-		//tdb_unlockkeys(db);
-		tdb_unlockall(db);
-	} else {
-		idlist* ilneu = idlist::make(1,&value);
-		TDB_DATA newd;
-		newd.dptr  = (char*) ilneu;
-		newd.dsize = ilneu->memsize();
-		tdb_store(db, k, newd, TDB_INSERT);
-		ilneu->destroy();
+			cout << "Value " << value.id << " found at position " << pos << " in key " << key.id << endl;
+		il.free_data();
+		unlock();
+	} catch (KeyNotFoundError e) {
+		IdList il(1);
+		il.data->data[0] = value;
+		il.data->size = 1;
+		set(key, il, TDB_INSERT);
+		il.free_data();
 	}
 }
-
-idlist* MapDB::query(u_int32_t key) {
-	TDB_DATA k, v;
-	k.dptr  = (char*) &key;
-	k.dsize = sizeof(u_int32_t);
-	v = tdb_fetch(db, k);
-	return (idlist*) v.dptr;
-}

Modified: central-database/trunk/c-tdb/mappkgtag.h
==============================================================================
--- central-database/trunk/c-tdb/mappkgtag.h	(original)
+++ central-database/trunk/c-tdb/mappkgtag.h	Sun Oct 30 18:33:07 2005
@@ -1,17 +1,17 @@
 #ifndef MAPPKGTAG_H
 #define MAPPKGTAG_H
-#include "mytdb.h"
+#include "etdb.h"
+#include "dbid.h"
 #include "idlist.h"
 
 #define MAP_ID_PKG_TAG_DB "database/map_id_pkg_tag.db"
 #define MAP_ID_TAG_PKG_DB "database/map_id_tag_pkg.db"
 
-class MapDB : public MyTDB {
+class MapDB : public etdb<dbid,IdList> {
 public:
 	MapDB(const char* filename, int flags);
 
-	void add_to_list(u_int32_t key, u_int32_t value);
-	idlist* query(u_int32_t key);
+	void add_to_list(dbid key, dbid value);
 };
 
 #endif

Modified: central-database/trunk/c-tdb/pkgdb.cc
==============================================================================
--- central-database/trunk/c-tdb/pkgdb.cc	(original)
+++ central-database/trunk/c-tdb/pkgdb.cc	Sun Oct 30 18:33:07 2005
@@ -3,9 +3,8 @@
 #include <stdlib.h>
 #include <string.h>
 
-PkgDB::PkgDB(int flags) : name_to_id(PKG_NAME_TO_ID_DB, flags), id_to_data(PKG_ID_TO_DATA_DB, flags) { }
-
-u_int32_t PkgDB::add_entry(const char* name, const char* desc, const char* longdesc) {
+/* create new (compact) package information structure */
+PkgInfo::PkgInfo(const char* name, const char* desc, const char* longdesc) {
 	size_t name_len = strlen(name) + 1;
 	size_t desc_len = strlen(desc) + 1;
 	size_t long_len = strlen(longdesc) + 1;
@@ -16,56 +15,60 @@
 	if (long_len   > USHRT_MAX) throw new SizeShortExceeded();
 	if (total_size > USHRT_MAX) throw new SizeShortExceeded();
 
-	pkginfo* pi = (pkginfo*) calloc(1, total_size);
+	/* allocate memory chunk */
+	data = (pkginfo*) malloc(total_size);
 
-	pi->name_offset = sizeof(pkginfo);
-	pi->name_size = name_len;
-	memcpy((char*)pi + pi->name_offset, name, name_len);
-	pi->desc_offset = sizeof(pkginfo) + name_len;
-	pi->desc_size = desc_len;
-	memcpy((char*)pi + pi->desc_offset, desc, desc_len);
-	pi->longdesc_offset = sizeof(pkginfo) + name_len + desc_len;
-	pi->longdesc_size = long_len;
-	memcpy((char*)pi + pi->longdesc_offset, longdesc, long_len);
-
-	int num = name_to_id.enumerate(name);
-	set_entry(num, pi, TDB_REPLACE);
-	free(pi);
-	return num;
+	/* fill the data structure */
+	data->name_offset = sizeof(pkginfo);
+	data->name_size = name_len;
+	memcpy((char*)data + data->name_offset, name, name_len);
+	data->desc_offset = sizeof(pkginfo) + name_len;
+	data->desc_size = desc_len;
+	memcpy((char*)data + data->desc_offset, desc, desc_len);
+	data->longdesc_offset = sizeof(pkginfo) + name_len + desc_len;
+	data->longdesc_size = long_len;
+	memcpy((char*)data + data->longdesc_offset, longdesc, long_len);
+}
+/* create (compact) package information structure from serialization */
+PkgInfo::PkgInfo(zcser ser) {
+	data = (pkginfo*) ser.dptr;
+}
+/* free data */
+void PkgInfo::free_data() {
+	assert(data); free(data); data = NULL;
+}
+/* serialize */
+zcser PkgInfo::serialize() const {
+	assert(data);
+	return zcser((char*) data, sizeof(pkginfo) + data->name_size + data->desc_size + data->longdesc_size);
+}
+/* accessor functions */
+const char* PkgInfo::name() {
+	return (char*)data + data->name_offset;
 }
-
-pkginfo* PkgDB::get_entry(u_int32_t id) {
-	TDB_DATA k, v;
-	k.dptr  = (char*) &id;
-	k.dsize = sizeof(u_int32_t);
-	v = tdb_fetch(id_to_data.db, k);
-	return (pkginfo*) v.dptr;
+const char* PkgInfo::desc() {
+	return (char*)data + data->desc_offset;
 }
-
-int PkgDB::set_entry(u_int32_t id, pkginfo* pi, int flag) {
-	TDB_DATA k, v;
-	k.dptr  = (char*) &id;
-	k.dsize = sizeof(u_int32_t);
-	v.dptr  = (char*) pi;
-	v.dsize = pi->memsize();
-	return tdb_store(id_to_data.db, k, v, flag);
-}
-
-int PkgDB::set_entry(u_int32_t id, pkginfo* pi) {
-	return set_entry(id, pi, TDB_REPLACE);
+const char* PkgInfo::longdesc() {
+	return (char*)data + data->longdesc_offset;
 }
 
+/* initialize/open databases */
+PkgDB::PkgDB(int flags) : name_to_id(PKG_NAME_TO_ID_DB, flags), id_to_data(PKG_ID_TO_DATA_DB, flags) { }
 
-unsigned int pkginfo::memsize() {
-	return sizeof(pkginfo) + name_size + desc_size + longdesc_size;
+/* add a new entry */
+dbid PkgDB::add(const char* name, const char* desc, const char* longdesc) {
+	dbid num = name_to_id.enumerate(name);
+	PkgInfo pi(name, desc, longdesc);
+	set(num, pi, TDB_REPLACE);
+	pi.free_data();
+	return num;
 }
 
-const char* pkginfo::name() {
-	return (char*)this + name_offset;
+PkgInfo PkgDB::get(dbid id) {
+	return id_to_data.get(id);
 }
-const char* pkginfo::desc() {
-	return (char*)this + desc_offset;
-}
-const char* pkginfo::longdesc() {
-	return (char*)this + longdesc_offset;
+
+int PkgDB::set(dbid id, PkgInfo pi, int flag) {
+	return id_to_data.set(id, pi, flag);
 }

Modified: central-database/trunk/c-tdb/pkgdb.h
==============================================================================
--- central-database/trunk/c-tdb/pkgdb.h	(original)
+++ central-database/trunk/c-tdb/pkgdb.h	Sun Oct 30 18:33:07 2005
@@ -1,11 +1,13 @@
 #ifndef PKGDB_H
 #define PKGDB_H
-#include "mytdb.h"
+#include "etdb.h"
+#include "zero-copy-serialize.h"
+#include "dbid.h"
+#include "dbstr.h"
 
 #define PKG_NAME_TO_ID_DB "database/packages_name_to_id.db"
 #define PKG_ID_TO_DATA_DB "database/packages_id_to_data.db"
 
-
 class pkginfo {
 public:
 	unsigned short	name_offset;
@@ -14,27 +16,40 @@
 	unsigned short	desc_size;
 	unsigned short	longdesc_offset;
 	unsigned short	longdesc_size;
+};
+
+class PkgInfo {
+public:
+	pkginfo* data;
+
+	/* create new */
+	PkgInfo(const char* name, const char* desc, const char* longdesc);
+	/* create (cast) from serialization */
+	PkgInfo(zcser ser);
+	/* serialize */
+	zcser serialize() const;
+	/* free data */
+	void free_data();
 
+	/* accessor functions */
 	const char* name();
 	const char* desc();
 	const char* longdesc();
-	size_t memsize();
+
+	/* exception class when unsigned short is not sufficient */
+	class SizeShortExceeded {};
 };
 
 class PkgDB {
 public:
-	enumMyTDB name_to_id;
-	MyTDB     id_to_data;
+	etdb<dbstr,dbid>	name_to_id;
+	etdb<dbid,PkgInfo>	id_to_data;
 
 	PkgDB(int flags);
 
-	u_int32_t add_entry(const char* name, const char* desc, const char* longdesc);
-	pkginfo* get_entry(u_int32_t id);
-	int set_entry(u_int32_t id, pkginfo* pi, int flag);
-	int set_entry(u_int32_t id, pkginfo* pi);
-
-	/* exception class when unsigned short is not sufficient */
-	class SizeShortExceeded {};
+	dbid	add(const char* name, const char* desc, const char* longdesc);
+	PkgInfo	get(dbid id);
+	int	set(dbid id, PkgInfo pi, int flag = TDB_REPLACE);
 };
 
 #endif

Modified: central-database/trunk/c-tdb/query.cc
==============================================================================
--- central-database/trunk/c-tdb/query.cc	(original)
+++ central-database/trunk/c-tdb/query.cc	Sun Oct 30 18:33:07 2005
@@ -10,37 +10,42 @@
 	/* open databases */
 	PkgDB dbpkg(O_RDONLY);
 	VocDB dbvoc(O_RDONLY);
-	MapDB mappt(MAP_ID_PKG_TAG_DB, O_RDONLY);
+	//MapDB mappt(MAP_ID_PKG_TAG_DB, O_RDONLY);
 	MapDB maptp(MAP_ID_TAG_PKG_DB, O_RDONLY);
 
-	idlist* result = NULL;
+	IdList* result = NULL;
 
 	for (int i=1; i < argc; i++) {
 		try {
-			u_int32_t entry = dbvoc.name_to_id.get_char_u32(argv[i]);
+			dbid entry = dbvoc.name_to_id.get(argv[i]);
 			if (!result) {
-				result = maptp.query(entry);
+				IdList temp = maptp.get(entry);
+				result = new IdList(temp);
 			} else {
-				idlist* temp = maptp.query(entry);
+				IdList temp = maptp.get(entry);
 				result->join(temp);
-				temp->destroy();
+				temp.free_data();
 			}
-		} catch (MyTDB::KeyNotFoundError) {
+		} catch (etdb<dbstr,dbid>::KeyNotFoundError e) {
 			cout << "Unknown tag specified: '" << argv[i] << "'" << endl;
 			exit(1);
 		}
 	}
-	if (!result || (result->size == 0)) {
+	if (!result || (result->size() == 0)) {
 		cout << "No matching packages found." << endl;
 		exit(1);
 	}
-	for (size_t i=0; i < result->size; i++) {
-		pkginfo* pi = dbpkg.get_entry(result->data[i]);
-		if (i > 0) cout << ", ";
-		cout << pi->name();
-		free(pi);
+	for (size_t i=0; i < result->size(); i++) {
+		try {
+			PkgInfo pi = dbpkg.get((*result)[i]);
+			if (i > 0) cout << ", ";
+			cout << pi.name();
+			pi.free_data();
+		} catch (etdb<dbid,PkgInfo>::KeyNotFoundError e) {
+			//cout << "A package was listed without package information being available!" << endl;
+		}
 	}
 	cout << endl;
-	result->destroy();
+	result->free_data();
 	return(0);
 }

Modified: central-database/trunk/c-tdb/vocdb.cc
==============================================================================
--- central-database/trunk/c-tdb/vocdb.cc	(original)
+++ central-database/trunk/c-tdb/vocdb.cc	Sun Oct 30 18:33:07 2005
@@ -3,9 +3,8 @@
 #include <stdlib.h>
 #include <string.h>
 
-VocDB::VocDB(int flags) : name_to_id(VOC_NAME_TO_ID_DB, flags), id_to_data(VOC_ID_TO_DATA_DB, flags) { }
-
-u_int32_t VocDB::add_entry(const char* name, const char* desc, const char* longdesc, u_int32_t flags, u_int32_t parent) {
+/* create new (compact) package information structure */
+VocInfo::VocInfo(const char* name, const char* desc, const char* longdesc, u_int32_t flags, dbid parent) {
 	size_t name_len = strlen(name) + 1;
 	size_t desc_len = strlen(desc) + 1;
 	size_t long_len = strlen(longdesc) + 1;
@@ -16,58 +15,68 @@
 	if (long_len   > USHRT_MAX) throw new SizeShortExceeded();
 	if (total_size > USHRT_MAX) throw new SizeShortExceeded();
 
-	vocinfo* vi = (vocinfo*) calloc(1, total_size);
+	/* allocate memory chunk */
+	data = (vocinfo*) malloc(total_size);
 
-	vi->name_offset = sizeof(vocinfo);
-	vi->name_size = name_len;
-	memcpy((char*)vi + vi->name_offset, name, name_len);
-	vi->desc_offset = sizeof(vocinfo) + name_len;
-	vi->desc_size = desc_len;
-	memcpy((char*)vi + vi->desc_offset, desc, desc_len);
-	vi->longdesc_offset = sizeof(vocinfo) + name_len + desc_len;
-	vi->longdesc_size = long_len;
-	memcpy((char*)vi + vi->longdesc_offset, longdesc, long_len);
-	vi->flags = flags;
-	vi->parent = parent;
-
-	int num = name_to_id.enumerate(name);
-	set_entry(num, vi, TDB_REPLACE);
-	free(vi);
-	return num;
+	/* fill the data structure */
+	data->name_offset = sizeof(vocinfo);
+	data->name_size = name_len;
+	memcpy((char*)data + data->name_offset, name, name_len);
+	data->desc_offset = sizeof(vocinfo) + name_len;
+	data->desc_size = desc_len;
+	memcpy((char*)data + data->desc_offset, desc, desc_len);
+	data->longdesc_offset = sizeof(vocinfo) + name_len + desc_len;
+	data->longdesc_size = long_len;
+	memcpy((char*)data + data->longdesc_offset, longdesc, long_len);
+	data->flags = flags;
+	data->parent = parent;
+}
+/* create (compact) package information structure from serialization */
+VocInfo::VocInfo(zcser ser) {
+	data = (vocinfo*) ser.dptr;
+}
+/* free data */
+void VocInfo::free_data() {
+	assert(data); free(data); data = NULL;
+}
+/* serialize */
+zcser VocInfo::serialize() const {
+	assert(data);
+	return zcser((char*) data, sizeof(vocinfo) + data->name_size + data->desc_size + data->longdesc_size);
+}
+/* accessor functions */
+const char* VocInfo::name() {
+	return (char*)data + data->name_offset;
+}
+const char* VocInfo::desc() {
+	return (char*)data + data->desc_offset;
+}
+const char* VocInfo::longdesc() {
+	return (char*)data + data->longdesc_offset;
 }
-
-vocinfo* VocDB::get_entry(u_int32_t id) {
-	TDB_DATA k, v;
-	k.dptr  = (char*) &id;
-	k.dsize = sizeof(u_int32_t);
-	v = tdb_fetch(id_to_data.db, k);
-	return (vocinfo*) v.dptr;
+u_int32_t VocInfo::flags() {
+	return data->flags;
 }
-
-int VocDB::set_entry(u_int32_t id, vocinfo* vi, int flag) {
-	TDB_DATA k, v;
-	k.dptr  = (char*) &id;
-	k.dsize = sizeof(u_int32_t);
-	v.dptr  = (char*) vi;
-	v.dsize = vi->memsize();
-	return tdb_store(id_to_data.db, k, v, flag);
-}
-
-int VocDB::set_entry(u_int32_t id, vocinfo* vi) {
-	return set_entry(id, vi, TDB_REPLACE);
+dbid VocInfo::parent() {
+	return data->parent;
 }
 
+/* initialize/open databases */
+VocDB::VocDB(int flags) : name_to_id(VOC_NAME_TO_ID_DB, flags), id_to_data(VOC_ID_TO_DATA_DB, flags) { }
 
-unsigned int vocinfo::memsize() {
-	return sizeof(vocinfo) + name_size + desc_size + longdesc_size;
+/* add a new entry */
+dbid VocDB::add(const char* name, const char* desc, const char* longdesc, u_int32_t flags, dbid parent) {
+	dbid num = name_to_id.enumerate(name);
+	VocInfo vi(name, desc, longdesc, flags, parent);
+	set(num, vi, TDB_REPLACE);
+	vi.free_data();
+	return num;
 }
 
-const char* vocinfo::name() {
-	return (char*)this + name_offset;
+VocInfo VocDB::get(dbid id) {
+	return id_to_data.get(id);
 }
-const char* vocinfo::desc() {
-	return (char*)this + desc_offset;
-}
-const char* vocinfo::longdesc() {
-	return (char*)this + longdesc_offset;
+
+int VocDB::set(dbid id, VocInfo pi, int flag) {
+	return id_to_data.set(id, pi, flag);
 }

Modified: central-database/trunk/c-tdb/vocdb.h
==============================================================================
--- central-database/trunk/c-tdb/vocdb.h	(original)
+++ central-database/trunk/c-tdb/vocdb.h	Sun Oct 30 18:33:07 2005
@@ -1,14 +1,16 @@
 #ifndef VOCDB_H
 #define VOCDB_H
 
-#include "mytdb.h"
+#include "etdb.h"
+#include "zero-copy-serialize.h"
+#include "dbid.h"
+#include "dbstr.h"
 
 #define VOC_NAME_TO_ID_DB "database/vocabulary_name_to_id.db"
 #define VOC_ID_TO_DATA_DB "database/vocabulary_id_to_data.db"
 
 #define FLAG_FACET 0x00000001
 
-
 class vocinfo {
 public:
 	unsigned short	name_offset;
@@ -18,28 +20,43 @@
 	unsigned short	longdesc_offset;
 	unsigned short	longdesc_size;
 	u_int32_t	flags;
-	u_int32_t	parent;
+	dbid		parent;
+};
+
+class VocInfo {
+public:
+	vocinfo*	data;
+
+	/* create new */
+	VocInfo(const char* name, const char* desc, const char* longdesc, u_int32_t flags, dbid parent);
+	/* create (cast) from serialization */
+	VocInfo(zcser ser);
+	/* serialize */
+	zcser serialize() const;
+	/* free data */
+	void free_data();
+
+	/* accessor functions */
+	const char*	name();
+	const char*	desc();
+	const char*	longdesc();
+	u_int32_t	flags();
+	dbid		parent();
 
-	const char* name();
-	const char* desc();
-	const char* longdesc();
-	size_t memsize();
+	/* exception class when unsigned short is not sufficient */
+	class SizeShortExceeded {};
 };
 
 class VocDB {
 public:
-	enumMyTDB name_to_id;
-	MyTDB     id_to_data;
+	etdb<dbstr, dbid>	name_to_id;
+	etdb<dbid, VocInfo>	id_to_data;
 
 	VocDB(int flags);
 
-	u_int32_t add_entry(const char* name, const char* desc, const char* longdesc, u_int32_t flags, u_int32_t facet);
-	vocinfo* get_entry(u_int32_t id);
-	int set_entry(u_int32_t id, vocinfo* pi, int flag);
-	int set_entry(u_int32_t id, vocinfo* pi);
-
-	/* exception class when unsigned short is not sufficient */
-	class SizeShortExceeded {};
+	dbid	add(const char* name, const char* desc, const char* longdesc, u_int32_t flags, dbid parent);
+	VocInfo	get(dbid id);
+	int	set(dbid id, VocInfo vi, int flag = TDB_REPLACE);
 };
 
 #endif



More information about the Debtags-commits mailing list