[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [GNUnet-developers] tdb.patch
From: |
Uli Luckas |
Subject: |
Re: [GNUnet-developers] tdb.patch |
Date: |
Mon, 06 May 2002 00:07:20 +0200 |
> After applying the patch there are two files that are not needed any
> more:
> src/include/util/contentdatabase_gdbm.h
> src/util/contentdatabase_gdbm.c
> They have been replaced by almost identical *_tdb.* files. So just
> remove them.
>
> Uli
It Looks like cvs didn't include the new files into the patch :-(
I'll attach them to this mail.
Uli
/*
This file is part of GNUnet
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 2, or (at your
option) any later version.
GNUnet is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNUnet; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
/**
* ContentDatabse - management of the 1k blocks...
* @author Christian Grothoff
* @file gnet/include/storage.h
**/
#ifndef CONTENTDATABASE_TDB_H
#define CONTENTDATABASE_TDB_H
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <openssl/ripemd.h>
#ifndef SOMEBSD
#include <wordexp.h>
#endif
#include <tdb.h>
#include "storage.h"
/**
* init the storage module.
* @param dir the name of the directory/file
* containing the content database
**/
void initContentDatabase_TDB(DirName * dir);
/**
* Free space in the database by removing one file
* @param fn the name of the file (without directory)
**/
void unlinkFromDB(HexName *fn);
/**
* Read the contents of a bucket to a buffer.
* @param fileName the name of the file, not freed!
* @param len the maximum number of bytes to read
* @param result the buffer to write the result to
* @return the number of bytes read on success, -1 on failure
**/
int readContent(HexName *fn,
int len,
void * result);
/**
* Write content to a file. Check for reduncancy and eventually
* append.
* @param fn the name of the file (without directory)
* @param block the CONTENT_SIZE bytes long block (no header!)
**/
void writeContent(HexName * fn,
CONTENT_Block * block);
/**
* Call a method for each entry in the database and
* call the callback method on it.
* @return the number of items stored in the content database
**/
int forEachEntryInDatabase(void (*callback)(HashCode160*));
#endif
/* end of contentdatabase_tdb.h */
/*
This file is part of GNUnet.
(C) 2001, 2002 Christian Grothoff (and other contributing authors)
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 2, or (at your
option) any later version.
GNUnet is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNUnet; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
/**
* ContentDatabase (tdb implementation).
* @author Christian Grothoff
* @author Uli Luckas
* @file util/contentdatabase_tdb.c
**/
#include "contentdatabase_tdb.h"
#include "xmalloc.h"
#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <pwd.h>
#include <grp.h>
#include <dirent.h>
#include <errno.h>
static TDB_CONTEXT *dbf;
/**
* Open a tdb database (for content)
* @param dir the directory where content is configured to be stored (e.g.
data/content). A file called ${dir}.dbf is used instead
**/
static TDB_CONTEXT *getDatabase(DirName *dir) {
FileName fin, ff;
TDB_CONTEXT *dbf;
char *ext = ".tdb";
int fnSize = strlen(dir->dirName) + strlen(ext);
fprintf(stderr,
"Database: %s\n",
dir->dirName);
ff = xmalloc(fnSize,
"getDatabase: filaname");
strcpy(ff, dir->dirName);
ff[strlen(ff) - 1] = 0;
strcat(ff, ext);
fin = expandFileName(ff);
xfree(ff,
"getDatabase: filaname");
dbf = tdb_open(fin, 0, 0, O_RDWR | O_CREAT, S_IRUSR|S_IWUSR);
xfree(fin,
"getDatabase: filaname (2)");
if (!dbf) {
fprintf(stderr,
"getDatabase: failed to open database file with error: %s",
tdb_errorstr(dbf));
if (errno) {
perror(", system error ");
} else {
fprintf(stderr,
"\n");
}
}
return(dbf);
}
void initContentDatabase_TDB(DirName * dir) {
dbf = getDatabase(dir);
if (dbf == NULL) {
fprintf(stderr,
"FATAL: could not open database!\n");
exit(-1);
}
}
/**
* Clean shutdown of the storage module (not used at the moment)
**/
void doneContentDatabase_TDB() {
tdb_close(dbf);
}
/**
* Call a method for each entry in the database and
* call the callback method on it.
* @return the number of items stored in the content database
**/
int forEachEntryInDatabase(void (*callback)(HashCode160*)) {
TDB_DATA prevkey, key;
HashCode160 doubleHash;
int count;
count = 0;
/* scan database data/content.dbf and add entries to database
if not already present */
key = tdb_firstkey(dbf);
while (key.dptr) {
if (strlen(key.dptr) == sizeof(HashCode160)*2) {
hex2hash((HexName*)key.dptr,
&doubleHash);
callback(&doubleHash);
count++; /* one more file */
}
prevkey = key;
key = tdb_nextkey(dbf, prevkey);
xfree(prevkey.dptr, "database dptr (allocation in DB code)");
}
return count;
}
/**
* Read the contents of a bucket to a buffer.
* @param fileName the name of the file, not freed!
* @param len the maximum number of bytes to read
* @param result the buffer to write the result to
* @return the number of bytes read on success, -1 on failure
**/
int readContent(HexName *fn,
int len,
void * result) {
TDB_DATA key, buffer;
if ((fn == NULL) || (result == NULL))
return -1;
key.dptr = fn->data;
key.dsize = strlen(key.dptr) + 1;
buffer = tdb_fetch(dbf, key);
if (!buffer.dptr)
return -1;
if (len > buffer.dsize)
len = buffer.dsize;
memcpy(result, buffer.dptr, len);
free(buffer.dptr);
return buffer.dsize;
}
/**
* Write content to a file. Check for reduncancy and eventually
* append.
* @param fn the name of the file (without directory)
* @param block the CONTENT_SIZE bytes long block (no header!)
**/
void writeContent(HexName * fn,
CONTENT_Block * block) {
CONTENT_Block preBlock[MAX_FSIZE];
TDB_DATA buffer, key;
int i;
int j;
int missmatch;
int blocks;
key.dptr = fn->data;
key.dsize = strlen(key.dptr) + 1;
buffer = tdb_fetch(dbf, key);
if (!buffer.dptr) {
j = 0;
} else {
j = buffer.dsize;
memcpy(preBlock->content, buffer.dptr, j);
xfree(buffer.dptr,"freeing dptr (allocated by tdb)");
}
if ((!j) || (j % CONTENT_SIZE != 0)) {
if (!j) {
fprintf(stderr,
"Info: New Bucket created (%d)\n",
MAX_FSIZE);
} else {
fprintf(stderr,
"WARNING: bucket in content database is corrupted!\n");
}
buffer.dptr = block->content;
buffer.dsize = CONTENT_SIZE;
tdb_store(dbf, key, buffer, TDB_REPLACE);
return;
}
blocks = j / CONTENT_SIZE;
fprintf(stderr,
"Info: Found bucket %s with %d blocks\n",
fn->data, blocks);
if (blocks >= MAX_FSIZE) {
fprintf(stderr,
"Attention: MAX_FSIZE (%d) collisions reached for a keyword!\n",
MAX_FSIZE);
return; /* full! */
}
/* collision! check if duplicate and if not, append */
for (i=0;i<blocks;i++) {
missmatch = 0;
for (j=0;j<CONTENT_SIZE;j++)
if (preBlock[i].content[j] != block->content[j]) {
missmatch++;
}
if (missmatch == 0) {
fprintf(stderr,
"Info: Data already in bucket.\n");
return; /* collision! */
}
}
fprintf(stderr,
"Info: Appended Data as block %d to bucket.\n",
blocks + 1);
memcpy(preBlock[blocks].content , block->content, CONTENT_SIZE);
buffer.dptr = preBlock->content;
buffer.dsize += CONTENT_SIZE;
tdb_store(dbf, key, buffer, TDB_REPLACE);
}
/**
* Free space in the database by removing one file
* @param fn the name of the file (without directory)
**/
void unlinkFromDB(HexName *fn) {
TDB_DATA key;
key.dptr = fn->data;
key.dsize = strlen(key.dptr) + 1;
tdb_delete(dbf, key);
}
/* end of contentdatabase_tdb.c */