gnunet-developers
[Top][All Lists]
Advanced

[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 */

reply via email to

[Prev in Thread] Current Thread [Next in Thread]