Verstaendnissfrage zu db(3).

D

das.chaos

Guest
Moin,

bevor ich mit Kanonen bzw. Valgrind auf Spatzen schiesse... :D

Ich habe mir testweise eine in-memory residierende db(3) per
C:
	db = dbopen(NULL, O_RDWR, 0, DB_HASH, NULL);
angelegt!
C:
static void *
c_obj_add(DB *db, DBT *key, void *arg)
{	
        struct c_obj *co;
        DBT data;

	if ((co = arg) == NULL)
	    return (NULL);

	data.data = co;
	data.size = co->co_len;
	
	if ((*db->put)(db, key, &data, 0))
		return (NULL);
	
	return (data.data);
}
Erzeugt mittels
C:
	(*db->put)(db, key, &data, 0)
eine Kopie von void *arg referenzierten Objekt
bzw. Bytestring und speichert diese in db(3).
C:
static void * 	
c_obj_del(DB *db, DBT *key, void *arg __unused)
{
	DBT data;
    	
	(void)memset(&data, 0, sizeof(data));
	
	if ((*db->get)(db, key, &data, 0))
		return (NULL);
	
	if ((*db->del)(db, key, 0))
		return (NULL);	

	return (data.data);
}
Findet und loescht zuvor erstellten Eintrag, wobei eine Referenz auf
Element, von o. g. Funktion bei Erfolg, zurueckgegeben wird. Es
ergeben sich fuer mich ein paar Fragen, da ich momentan einen
Knoten im Kopf habe.

Befindet sich dann das per data.data referenzierte Element innerhalb
eines, aus Sicht von db(3), ungueltigen Addressraumes? Sollte dann
o. g. Funktion eigendlich als
C:
static void * 	
c_obj_del(DB *db, DBT *key, void *arg __unused)
{
	DBT data;
        void *rv;
    	
	(void)memset(&data, 0, sizeof(data));

	if ((*db->get)(db, key, &data, 0))
		goto bad;
	
	if ((rv = malloc(data.size)) == NULL)
		goto bad;
	
	(void)memmove(rv, data.data, data.size);
	
	if ((*db->del)(db, key, 0)) 
		goto bad1;
out:	
	return (rv};
bad1:
	free(rv);
bad:	
	rv = NULL:
	goto out;	
}
reimplementiert werden? Damit eine Kopie des
zu loeschenden Objektes erzeugt werden wird,
welche von aufrufenden Entitaet wiederum per
void free(void *ptr) irgendwann geloescht
werden wird, falls die Kopie von dem zuvor in
db(3) entfernten Element nicht mehr
benoetigt werden weurde?

Moeglicherweise habe ich mir schon unbewusst
die Fragen selber beantwortet... da mir bekannt
ist, dass die Implementierung von db(3) ein
eigenes Memory Management auf Basis von
Paging implementiert.

Helft mir mal bitte auf die Spruenge, dass liegt
wohl am Wetter, dass ich momentan den Wald
vor lauter Baeumen nicht sehe.
 
Mmmhh... oder anders gefragt... :)

Ist
C:
static void *     
c_obj_del(DB *db, DBT *key, void *arg __unused)
{
    DBT data;
    void *rv;
        
    (void)memset(&data, 0, sizeof(data));
    
    if ((*db->get)(db, key, &data, 0) == 0) {
       
        if ((rv = malloc(data.size)) != NULL) {
            (void)memmove(rv, data.data, data.size);
    
            if ((*db->del)(db, key, 0)) {
                free(rv);
                rv = NULL;
            }
        }    
    } else 
        rv = NULL;
    
    return (rv);
}
statt
C:
static void *     
c_obj_del(DB *db, DBT *key, void *arg __unused)
{
    DBT data;
        
    (void)memset(&data, 0, sizeof(data));
    
    if ((*db->get)(db, key, &data, 0))
        return (NULL);
    
    if ((*db->del)(db, key, 0))
        return (NULL);    

    return (data.data);
}
als Methode vorzuziehen?

Wenn gefordert ist, dass das aus einer Loeschoperation resultierende
Template, siehe oben, fuer das Generieren eines Datensatzes mittels
C:
static void *
c_obj_add(DB *db, DBT *key, void *arg)
{    
    struct c_obj *co;
    DBT data;
    
    if ((co = arg) == NULL)
        return (NULL);

    data.data = co;
    data.size = co->co_len;
    
    if ((*db->put)(db, key, &data, 0))
        return (NULL);
    
    return (data.data);
}
verwendet werden sollte. Es sei angemerkt, dass
Code:
    (*db->put)(db, key, &data, 0)
eine Kopie vom Template erzeugt und diese dann
in db(3) integriert, d. h. die Menge gegebener
Templates stellt ein Erzeugenden System dar.
 
Die Beschreibung in db(3) ist tatsächlich sehr dürftig.
Ich vermute aber stark, dass nach einem db->del das entsprechende DBT nicht mehr gültig ist.
Ich wäre mir nicht einmal sicher, ob nach zwei db->get hintereinander das DBT vom ersten Aufruf noch gültig ist -- es könnte ja sein, dass immer nur das zuletzt abgefragte DBT vorgehalten wird.
Leider schweigt sich db(3) zu diesen Fragen komplett aus und man muss wohl den Quelltext durchwühlen.
 
Leider schweigt sich db(3) zu diesen Fragen komplett aus und man muss wohl den Quelltext durchwühlen.

Bin geradeeben dabei den Quelltext analytisch zu betrachten. :D

Bspw. ist in
bzw.
die auf Paging beruhende Implementierung
bzgl. dem Erzeugen und dem Loeschen von
key-value-Tupeln zu finden.

Scheint wohl zu sein, dass nach get() ein
DBT seine Gueltigkeit verliert, aber ich bin
mir noch nicht ganz sicher.
 
Zurück
Oben