gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r3858 - in GNUnet: . src/applications src/applications/dht/


From: grothoff
Subject: [GNUnet-SVN] r3858 - in GNUnet: . src/applications src/applications/dht/module src/applications/dstore src/include
Date: Sat, 2 Dec 2006 22:35:27 -0800 (PST)

Author: grothoff
Date: 2006-12-02 22:35:19 -0800 (Sat, 02 Dec 2006)
New Revision: 3858

Added:
   GNUnet/src/applications/dstore/
   GNUnet/src/applications/dstore/Makefile.am
   GNUnet/src/applications/dstore/check.conf
   GNUnet/src/applications/dstore/dstore.c
   GNUnet/src/applications/dstore/dstore_test.c
   GNUnet/src/include/gnunet_dstore_service.h
Modified:
   GNUnet/INSTALL
   GNUnet/configure.ac
   GNUnet/ltmain.sh
   GNUnet/src/applications/Makefile.am
   GNUnet/src/applications/dht/module/dstore.c
   GNUnet/src/applications/dht/module/dstore.h
   GNUnet/src/include/Makefile.am
   GNUnet/src/include/gnunet_kvstore_service.h
Log:
dstore started

Modified: GNUnet/INSTALL
===================================================================
--- GNUnet/INSTALL      2006-12-03 05:21:11 UTC (rev 3857)
+++ GNUnet/INSTALL      2006-12-03 06:35:19 UTC (rev 3858)
@@ -1,13 +1,16 @@
-Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
-Foundation, Inc.
+Installation Instructions
+*************************
 
-   This file is free documentation; the Free Software Foundation gives
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free
+Software Foundation, Inc.
+
+This file is free documentation; the Free Software Foundation gives
 unlimited permission to copy, distribute and modify it.
 
 Basic Installation
 ==================
 
-   These are generic installation instructions.
+These are generic installation instructions.
 
    The `configure' shell script attempts to guess correct values for
 various system-dependent variables used during compilation.  It uses
@@ -67,9 +70,9 @@
 Compilers and Options
 =====================
 
-   Some systems require unusual options for compilation or linking that
-the `configure' script does not know about.  Run `./configure --help'
-for details on some of the pertinent environment variables.
+Some systems require unusual options for compilation or linking that the
+`configure' script does not know about.  Run `./configure --help' for
+details on some of the pertinent environment variables.
 
    You can give `configure' initial values for configuration parameters
 by setting variables in the command line or in the environment.  Here
@@ -82,7 +85,7 @@
 Compiling For Multiple Architectures
 ====================================
 
-   You can compile the package for more than one kind of computer at the
+You can compile the package for more than one kind of computer at the
 same time, by placing the object files for each architecture in their
 own directory.  To do this, you must use a version of `make' that
 supports the `VPATH' variable, such as GNU `make'.  `cd' to the
@@ -99,19 +102,19 @@
 Installation Names
 ==================
 
-   By default, `make install' will install the package's files in
-`/usr/local/bin', `/usr/local/man', etc.  You can specify an
-installation prefix other than `/usr/local' by giving `configure' the
-option `--prefix=PATH'.
+By default, `make install' installs the package's commands under
+`/usr/local/bin', include files under `/usr/local/include', etc.  You
+can specify an installation prefix other than `/usr/local' by giving
+`configure' the option `--prefix=PREFIX'.
 
    You can specify separate installation prefixes for
 architecture-specific files and architecture-independent files.  If you
-give `configure' the option `--exec-prefix=PATH', the package will use
-PATH as the prefix for installing programs and libraries.
-Documentation and other data files will still use the regular prefix.
+pass the option `--exec-prefix=PREFIX' to `configure', the package uses
+PREFIX as the prefix for installing programs and libraries.
+Documentation and other data files still use the regular prefix.
 
    In addition, if you use an unusual directory layout you can give
-options like `--bindir=PATH' to specify different values for particular
+options like `--bindir=DIR' to specify different values for particular
 kinds of files.  Run `configure --help' for a list of the directories
 you can set and what kinds of files go in them.
 
@@ -122,7 +125,7 @@
 Optional Features
 =================
 
-   Some packages pay attention to `--enable-FEATURE' options to
+Some packages pay attention to `--enable-FEATURE' options to
 `configure', where FEATURE indicates an optional part of the package.
 They may also pay attention to `--with-PACKAGE' options, where PACKAGE
 is something like `gnu-as' or `x' (for the X Window System).  The
@@ -137,11 +140,11 @@
 Specifying the System Type
 ==========================
 
-   There may be some features `configure' cannot figure out
-automatically, but needs to determine by the type of machine the package
-will run on.  Usually, assuming the package is built to be run on the
-_same_ architectures, `configure' can figure that out, but if it prints
-a message saying it cannot guess the machine type, give it the
+There may be some features `configure' cannot figure out automatically,
+but needs to determine by the type of machine the package will run on.
+Usually, assuming the package is built to be run on the _same_
+architectures, `configure' can figure that out, but if it prints a
+message saying it cannot guess the machine type, give it the
 `--build=TYPE' option.  TYPE can either be a short name for the system
 type, such as `sun4', or a canonical name which has the form:
 
@@ -156,7 +159,7 @@
 need to know the machine type.
 
    If you are _building_ compiler tools for cross-compiling, you should
-use the `--target=TYPE' option to select the type of system they will
+use the option `--target=TYPE' to select the type of system they will
 produce code for.
 
    If you want to _use_ a cross compiler, that generates code for a
@@ -167,9 +170,9 @@
 Sharing Defaults
 ================
 
-   If you want to set default values for `configure' scripts to share,
-you can create a site shell script called `config.site' that gives
-default values for variables like `CC', `cache_file', and `prefix'.
+If you want to set default values for `configure' scripts to share, you
+can create a site shell script called `config.site' that gives default
+values for variables like `CC', `cache_file', and `prefix'.
 `configure' looks for `PREFIX/share/config.site' if it exists, then
 `PREFIX/etc/config.site' if it exists.  Or, you can set the
 `CONFIG_SITE' environment variable to the location of the site script.
@@ -178,7 +181,7 @@
 Defining Variables
 ==================
 
-   Variables not defined in a site shell script can be set in the
+Variables not defined in a site shell script can be set in the
 environment passed to `configure'.  However, some packages may run
 configure again during the build, and the customized values of these
 variables may be lost.  In order to avoid this problem, you should set
@@ -186,14 +189,18 @@
 
      ./configure CC=/usr/local2/bin/gcc
 
-will cause the specified gcc to be used as the C compiler (unless it is
-overridden in the site shell script).
+causes the specified `gcc' to be used as the C compiler (unless it is
+overridden in the site shell script).  Here is a another example:
 
+     /bin/bash ./configure CONFIG_SHELL=/bin/bash
+
+Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent
+configuration-related scripts to be executed by `/bin/bash'.
+
 `configure' Invocation
 ======================
 
-   `configure' recognizes the following options to control how it
-operates.
+`configure' recognizes the following options to control how it operates.
 
 `--help'
 `-h'

Modified: GNUnet/configure.ac
===================================================================
--- GNUnet/configure.ac 2006-12-03 05:21:11 UTC (rev 3857)
+++ GNUnet/configure.ac 2006-12-03 06:35:19 UTC (rev 3858)
@@ -539,6 +539,7 @@
 src/applications/dht/Makefile
 src/applications/dht/tools/Makefile
 src/applications/dht/module/Makefile
+src/applications/dstore/Makefile
 src/applications/fragmentation/Makefile
 src/applications/fs/Makefile
 src/applications/fs/collection/Makefile

Modified: GNUnet/ltmain.sh
===================================================================
--- GNUnet/ltmain.sh    2006-12-03 05:21:11 UTC (rev 3857)
+++ GNUnet/ltmain.sh    2006-12-03 06:35:19 UTC (rev 3858)
@@ -43,7 +43,7 @@
 
 PROGRAM=ltmain.sh
 PACKAGE=libtool
-VERSION="1.5.22 Debian 1.5.22-4"
+VERSION=1.5.22
 TIMESTAMP=" (1.1220.2.365 2005/12/18 22:14:06)"
 
 # See if we are running on zsh, and set the options which allow our
@@ -2082,10 +2082,7 @@
        case $pass in
        dlopen) libs="$dlfiles" ;;
        dlpreopen) libs="$dlprefiles" ;;
-       link)
-         libs="$deplibs %DEPLIBS%"
-         test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs"
-         ;;
+       link) libs="$deplibs %DEPLIBS% $dependency_libs" ;;
        esac
       fi
       if test "$pass" = dlopen; then
@@ -3204,11 +3201,6 @@
            age="$number_minor"
            revision="$number_minor"
            ;;
-         *)
-           $echo "$modename: unknown library version type \`$version_type'" 
1>&2
-           $echo "Fatal configuration error.  See the $PACKAGE docs for more 
information." 1>&2
-           exit $EXIT_FAILURE
-           ;;
          esac
          ;;
        no)

Modified: GNUnet/src/applications/Makefile.am
===================================================================
--- GNUnet/src/applications/Makefile.am 2006-12-03 05:21:11 UTC (rev 3857)
+++ GNUnet/src/applications/Makefile.am 2006-12-03 06:35:19 UTC (rev 3858)
@@ -4,7 +4,7 @@
 endif
 
 if HAVE_SQLITE
- SQLITE_DIR = sqstore_sqlite kvstore_sqlite
+ SQLITE_DIR = sqstore_sqlite kvstore_sqlite dstore dht
 endif
 
 if !MINGW
@@ -38,7 +38,6 @@
  tracekit \
  traffic \
  transport \
- dht \
  $(VPN_DIR)
 # $(TESTBED_DIR) 
 # chat

Modified: GNUnet/src/applications/dht/module/dstore.c
===================================================================
--- GNUnet/src/applications/dht/module/dstore.c 2006-12-03 05:21:11 UTC (rev 
3857)
+++ GNUnet/src/applications/dht/module/dstore.c 2006-12-03 06:35:19 UTC (rev 
3858)
@@ -22,270 +22,17 @@
  * @file module/dstore.c
  * @brief entries in local DHT
  * @author Simo Viitanen, Christian Grothoff
- *
- * TODO:
- * - store should automatically delete
- *   oldest content when full
- * - use SQL-based database instead of
- *   in-memory database
  */
 
 #include "platform.h"
 #include "dstore.h"
 #include "gnunet_blockstore.h"
 
+static Dstore_ServiceAPI * dstore;
 
-/**
- * @brief datastructure for one entry in the table.
- */
-typedef struct HT_Entry_t {
-  struct HT_Entry_t * next;
-  HashCode512 key;
-  unsigned int count;
-  DataContainer ** values;
-} HT_Entry;
+static CoreAPIForApplication * coreAPI;
 
 /**
- * @brief the per-table data
- */
-typedef struct {
-  struct MUTEX * lock;
-  size_t max_memory;
-  HT_Entry * first;
-} MemoryDatastore;
-
-
-/**
- * Lookup an item in the datastore.
- *
- * @param key the value to lookup
- * @param maxResults maximum number of results
- * @param results where to store the result; must point to
- *        an array of maxResuls containers; if the containers
- *        point to allocated memory, it will be used by lookup;
- *        otherwise lookup will allocate the data pointer;
- *        in either case dataLength is adjusted to the actual
- *        size of the data.  If not enough space is present to
- *        accomodate the data the data will be truncated.
- * @return number of results, SYSERR on error
- */
-static int ds_lookup(void * closure,
-                    unsigned int type,
-                    unsigned int prio,
-                    unsigned int keyCount,
-                    const HashCode512 * keys,
-                    DataProcessor resultCallback,
-                    void * resCallbackClosure) {
-  MemoryDatastore * ds = (MemoryDatastore*) closure;
-  HT_Entry * pos;
-  int i;
-
-  if ( (ds == NULL) || (keyCount != 1) )
-    return SYSERR;
-  MUTEX_LOCK(ds->lock);
-  pos = ds->first;
-  while (pos != NULL) {
-    if (0 == memcmp(&keys[0],
-                   &pos->key,
-                   sizeof(HashCode512))) {
-      for (i=0;i<pos->count;i++)
-       if (OK != resultCallback(&pos->key,
-                                pos->values[i],
-                                resCallbackClosure)) {
-         MUTEX_UNLOCK(ds->lock);
-         return SYSERR;
-       }
-      MUTEX_UNLOCK(ds->lock);
-      return pos->count;
-    }
-    pos = pos->next;
-  }
-  MUTEX_UNLOCK(ds->lock);
-  return 0;
-}
-
-/**
- * Store an item in the datastore.
- *
- * @param key the key of the item
- * @param value the value to store
- *  for other entries under the same key (if key already exists)
- * @return OK if the value could be stored, DHT_ERRORCODE or SYSERR if not 
(i.e. out of space)
- */
-static int ds_store(void * closure,
-                   const HashCode512 * key,
-                   const DataContainer * value,
-                   unsigned int prio) {
-  MemoryDatastore * ds = closure;
-  HT_Entry * pos;
-  unsigned int size;
-
-  if (ds == NULL)
-    return SYSERR;
-
-  size = ntohl(value->size);
-  MUTEX_LOCK(ds->lock);
-  pos = ds->first;
-  while (pos != NULL) {
-    if (0 == memcmp(key,
-                   &pos->key,
-                   sizeof(HashCode512))) {
-      if (ds->max_memory < size) {
-       MUTEX_UNLOCK(ds->lock);
-       return NO;
-      }
-      ds->max_memory -= size;
-      GROW(pos->values,
-          pos->count,
-          pos->count+1);
-      pos->values[pos->count-1]
-       = MALLOC(size);
-      memcpy(pos->values[pos->count-1],
-            value,
-            size);
-      MUTEX_UNLOCK(ds->lock);
-      return OK;
-    } /* end key match */
-    pos = pos->next;
-  }
-  /* no key matched, create fresh entry */
-  if (ds->max_memory < sizeof(HT_Entry) + size) {
-    MUTEX_UNLOCK(ds->lock);
-    return NO;
-  }
-  ds->max_memory -= sizeof(HT_Entry) + size;
-  pos = MALLOC(sizeof(HT_Entry));
-  pos->key = *key;
-  pos->count = 1;
-  pos->values = MALLOC(sizeof(DataContainer*));
-  pos->values[0] = MALLOC(size);
-  memcpy(pos->values[0],
-        value,
-        size);
-  pos->next = ds->first;
-  ds->first = pos;
-  MUTEX_UNLOCK(ds->lock);
-  return OK;
-}
-
-
-
-/**
- * Remove an item from the datastore.
- *
- * @param key the key of the item
- * @param value the value to remove, NULL for all values of the key
- * @return OK if the value could be removed, SYSERR if not (i.e. not present)
- */
-static int ds_remove(void * closure,
-                    const HashCode512 * key,
-                    const DataContainer * value) {
-  MemoryDatastore * ds = closure;
-  HT_Entry * pos;
-  HT_Entry * prev;
-  int i;
-  unsigned int size;
-
-  if (ds == NULL)
-    return SYSERR;
-  size = ntohl(value->size);
-  MUTEX_LOCK(ds->lock);
-  prev = NULL;
-  pos = ds->first;
-  while (pos != NULL) {
-    if (0 == memcmp(key,
-                   &pos->key,
-                   sizeof(HashCode512))) {
-      if (value != NULL) {
-       for (i=0;i<pos->count;i++) {
-         if ( (pos->values[i]->size == value->size) &&
-              (0 == memcmp(pos->values[i],
-                           value,
-                           size)) ) {
-           FREE(pos->values[i]);
-           ds->max_memory += size;
-           pos->values[i] = pos->values[pos->count-1];
-           GROW(pos->values,
-                pos->count,
-                pos->count-1);
-           if (pos->count == 0) {
-             if (prev == NULL)
-               ds->first = pos->next;
-             else
-               prev->next = pos->next;
-             FREE(pos);
-             ds->max_memory += sizeof(HT_Entry);       
-           }
-           MUTEX_UNLOCK(ds->lock);
-           return OK;
-         }
-       }
-      } else {
-       /* remove entire link */
-       if (prev == NULL)
-         ds->first = pos->next;
-       else
-         prev->next = pos->next;
-       
-       for (i=0;i<pos->count;i++) {
-         ds->max_memory += ntohl(pos->values[i]->size);
-         FREE(pos->values[i]);
-       }
-       GROW(pos->values,
-            pos->count,
-            0);
-       FREE(pos);
-       ds->max_memory += sizeof(HT_Entry);
-      }
-      MUTEX_UNLOCK(ds->lock);
-      return OK;
-    }
-    prev = pos;
-    pos = pos->next;
-  }
-  MUTEX_UNLOCK(ds->lock);
-  return SYSERR; /* not found */
-}
-
-/**
- * Iterate over all keys in the local datastore
- *
- * @param processor function to call on each item
- * @param cls argument to processor
- * @return number of results, SYSERR on error
- */
-static int ds_iterate(void * closure,          
-                     DataProcessor processor,
-                     void * cls) {
-  MemoryDatastore * ds = closure;
-  int ret;
-  HT_Entry * pos;
-  int i;
-
-  if (ds == NULL)
-    return SYSERR;
-
-  MUTEX_LOCK(ds->lock);
-  pos = ds->first;
-  ret = 0;
-  while (pos != NULL) {
-    for (i=0;i<pos->count;i++) {
-      ret++;
-      if (processor != NULL)
-       if (OK != processor(&pos->key,
-                           pos->values[i],
-                           cls)) {
-         MUTEX_UNLOCK(ds->lock);
-         return ret;
-       }
-    }
-    pos = pos->next;
-  }
-  MUTEX_UNLOCK(ds->lock);
-  return SYSERR;
-}
-
-/**
  * Lookup in the local datastore.
  * @return total number of results found
  */
@@ -293,7 +40,10 @@
                  unsigned int type,
                  ResultHandler handler,
                  void * cls) {
-  return 0;
+  return dstore->get(key,
+                    type,
+                    handler,
+                    cls);
 }
 
 /**
@@ -306,7 +56,11 @@
                   const char * data) {
   if (discard_time < get_time())
     return;
-  
+  return dstore->put(key,
+                    type,
+                    discard_time,
+                    size,
+                    data);
 }
   
 /**
@@ -317,6 +71,10 @@
  */
 int init_dht_store(size_t max_size,
                   CoreAPIForApplication * capi) {
+  coreAPI = capi;
+  dstore = coreAPI->requestService("dstore");
+  if (dstore == NULL)
+    return SYSERR;
   return OK;
 }
 
@@ -326,6 +84,10 @@
  * @return OK on success
  */
 int done_dht_store() {
+  coreAPI->releaseService(dstore);
+  coreAPI = NULL;
+  dstore = NULL;
   return OK;
 }
 
+/* end of dstore.c */

Modified: GNUnet/src/applications/dht/module/dstore.h
===================================================================
--- GNUnet/src/applications/dht/module/dstore.h 2006-12-03 05:21:11 UTC (rev 
3857)
+++ GNUnet/src/applications/dht/module/dstore.h 2006-12-03 06:35:19 UTC (rev 
3858)
@@ -28,14 +28,8 @@
 #define DHT_DSTORE_H
 
 #include "gnunet_util.h"
-#include "gnunet_core.h"
+#include "gnunet_dstore_service.h"
 
-typedef void (*ResultHandler)(const HashCode512 * key,
-                             unsigned int type,
-                             unsigned int size,
-                             const char * data,
-                             void * cls);
-
 /**
  * Lookup in the local datastore.
  * @return total number of results found

Added: GNUnet/src/applications/dstore/Makefile.am
===================================================================
--- GNUnet/src/applications/dstore/Makefile.am  2006-12-03 05:21:11 UTC (rev 
3857)
+++ GNUnet/src/applications/dstore/Makefile.am  2006-12-03 06:35:19 UTC (rev 
3858)
@@ -0,0 +1,34 @@
+INCLUDES = -I$(top_srcdir)/src/include
+
+plugindir = $(libdir)/GNUnet
+
+LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la 
+
+plugin_LTLIBRARIES = \
+  libgnunetmodule_dstore.la
+
+check_PROGRAMS = \
+  dstore_test
+
+TESTS = $(check_PROGRAMS)
+
+AM_CPPFLAGS = $(CPPFLAGS) $(SQLITE_CPPFLAGS)
+
+libgnunetmodule_dstore_la_SOURCES = \
+  dstore.c 
+libgnunetmodule_dstore_la_LDFLAGS = \
+  -export-dynamic -avoid-version -module \
+  $(SQLITE_LDFLAGS)
+libgnunetmodule_dstore_la_LIBADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ -lsqlite3
+
+EXTRA_DIST = check.conf
+
+dstore_test_SOURCES = \
+ dstore_test.c 
+dstore_test_LDADD = \
+ $(top_builddir)/src/server/libgnunetcore.la  \
+ $(top_builddir)/src/util/config_impl/libgnunetutil_config.la  \
+ $(top_builddir)/src/util/libgnunetutil.la  

Added: GNUnet/src/applications/dstore/check.conf
===================================================================
--- GNUnet/src/applications/dstore/check.conf   2006-12-03 05:21:11 UTC (rev 
3857)
+++ GNUnet/src/applications/dstore/check.conf   2006-12-03 06:35:19 UTC (rev 
3858)
@@ -0,0 +1,44 @@
+GNUNETD_HOME = /tmp/gnunet-sqlite-sqstore-test
+
+[GNUNETD]
+GNUNETD_HOME = /tmp/gnunet-sqlite-sqstore-test
+HELLOEXPIRES = 1440
+LOGLEVEL = "NOTHING"
+LOGFILE = $GNUNETD_HOME/logs
+KEEPLOG = "0"
+PIDFILE = $GNUNETD_HOME/gnunet.pid
+HOSTS = $GNUNETD_HOME/data/hosts/
+HTTP-PROXY = ""
+HTTP-PROXY-PORT = 1080
+APPLICATIONS = "fs getoption stats traffic"
+PROCESS-PRIORITY = "NORMAL"
+
+[KEYVALUE_DATABASE]
+DIR = $GNUNETD_HOME/data/kv/
+
+[MODULES]
+sqstore = "sqstore_sqlite"
+topology = "topology_default"
+
+[NETWORK]
+PORT = 12087
+INTERFACE = ""
+IP = ""
+HELLOEXCHANGE = YES
+TRUSTED = "127.0.0.0/8;"
+
+[LOAD]
+BASICLIMITING = YES
+INTERFACES = ""
+MAXNETDOWNBPSTOTAL = 50000
+MAXNETUPBPSTOTAL = 50000
+MAXCPULOAD = 50
+
+[FS]
+QUOTA = 1024
+ACTIVEMIGRATION = YES
+DIR = $GNUNETD_HOME/data/fs/
+INDEX-DIRECTORY = $GNUNETD_HOME/data/shared/
+INDEX-QUOTA = 8192
+POOL = 32
+

Added: GNUnet/src/applications/dstore/dstore.c
===================================================================
--- GNUnet/src/applications/dstore/dstore.c     2006-12-03 05:21:11 UTC (rev 
3857)
+++ GNUnet/src/applications/dstore/dstore.c     2006-12-03 06:35:19 UTC (rev 
3858)
@@ -0,0 +1,259 @@
+/*
+     This file is part of GNUnet.
+     (C) 2006 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.
+*/
+
+/**
+ * @file applications/dstore/dstore.c
+ * @brief SQLite based implementation of the dstore service
+ * @author Christian Grothoff
+ * @todo Indexes, statistics
+ *
+ * Database: SQLite
+ *
+ * TODO:
+ * - add bloomfilter to reduce disk IO
+ * - finish Sqlite interaction
+ */
+
+#include "platform.h"
+#include "gnunet_util.h"
+#include "gnunet_dstore_service.h"
+#include <sqlite3.h>
+
+/**
+ * Bytes used
+ */
+static unsigned long long payload;
+
+/**
+ * Maximum bytes available
+ */ 
+static unsigned long long quota;
+
+/**
+ * Filename of this database
+ */
+static char * fn;
+
+static CoreAPIForApplication * coreAPI;
+
+static struct MUTEX * lock;
+
+/**
+ * @brief Prepare a SQL statement
+ */
+static int sq_prepare(sqlite3 * dbh,
+                     const char *zSql,       /* SQL statement, UTF-8 encoded */
+                     sqlite3_stmt **ppStmt) {  /* OUT: Statement handle */
+  char * dummy;
+  return sqlite3_prepare(dbh,
+                        zSql,
+                        strlen(zSql),
+                        ppStmt,
+                        (const char**) &dummy);
+}
+
+static void db_reset() {
+  int fd;
+
+  UNLINK(fn);
+  FREE(fn);
+  fn = STRDUP("/tmp/dstoreXXXXXX");
+  fd = mkstemp(fn);
+  if (fd != -1) 
+    CLOSE(fd);
+}
+
+static void db_init(sqlite3 * dbh) {
+  sqlite3_exec(dbh,
+              "PRAGMA temp_store=MEMORY", 
+              NULL,
+              NULL,
+              NULL);
+  sqlite3_exec(dbh,
+              "PRAGMA synchronous=OFF", 
+              NULL,
+              NULL, 
+              NULL);
+  sqlite3_exec(dbh,
+              "PRAGMA count_changes=OFF", 
+              NULL, 
+              NULL, 
+              NULL);
+  sqlite3_exec(dbh,
+              "PRAGMA page_size=4092", 
+              NULL,
+              NULL, 
+              NULL);
+  sqlite3_exec(dbh,
+              "CREATE TABLE ds071 ("
+              "  size INTEGER NOT NULL DEFAULT 0,"
+              "  type INTEGER NOT NULL DEFAULT 0,"
+              "  puttime INTEGER NOT NULL DEFAULT 0,"
+              "  expire INTEGER NOT NULL DEFAULT 0,"
+              "  key TEXT NOT NULL DEFAULT '',"
+              "  value BLOB NOT NULL DEFAULT '')",
+              NULL,
+              NULL,
+              NULL);
+}
+
+/**
+ * Store an item in the datastore.
+ *
+ * @return OK on success, SYSERR on error
+ */
+static int d_put(const HashCode512 * key,
+                unsigned int type,
+                cron_t discard_time,
+                unsigned int size,
+                const char * data) {
+  sqlite3 * dbh;
+  sqlite3_stmt * stmt;
+  sqlite3_stmt * dstmt;
+
+  MUTEX_LOCK(lock);
+  if (SQLITE_OK != sqlite3_open(fn,
+                               &dbh)) {
+    db_reset(dbh);
+    MUTEX_UNLOCK(lock);    
+    return SYSERR;
+  }
+  db_init(dbh);
+  if (sq_prepare(dbh,
+                "INSERT INTO ds071 "
+                "(size, type, puttime, expire, key, value) "
+                "VALUES (?, ?, ?, ?, ?, ?)",
+                &stmt) != SQLITE_OK) {
+    sqlite3_close(dbh);
+    MUTEX_UNLOCK(lock);
+    return SYSERR;
+  }
+  sqlite3_finalize(stmt);
+  stmt = NULL;
+  dstmt = NULL;
+  payload += size;
+  if (payload > quota) {
+    if ( (sq_prepare(dbh,
+                    "SELECT * FROM ds071 ORDER BY puttime ASC",
+                    &stmt) == SQLITE_OK) &&
+        (sq_prepare(dbh,
+                  "DELETE FROM ds071 "
+                    "WHERE size = ? AND type = ? AND puttime = ? AND expire = 
? AND key = ? AND value = ?",
+                    &dstmt) == SQLITE_OK) ) {
+      while (payload > quota) {
+       /* FIMXE: delete until quota is satisfied again */
+       break; /* for now */
+      }
+      sqlite3_finalize(dstmt);
+      sqlite3_finalize(stmt);
+    } else {
+      GE_BREAK(NULL, 0);
+      if (dstmt != NULL)
+       sqlite3_finalize(dstmt);
+      if (stmt != NULL)
+       sqlite3_finalize(stmt);
+    }
+  }
+  sqlite3_close(dbh);
+  MUTEX_UNLOCK(lock);
+  return OK;
+}
+
+/**
+ * Iterate over the results for a particular key
+ * in the datastore.
+ *
+ * @param key 
+ * @param type entries of which type are relevant?
+ * @param iter maybe NULL (to just count)
+ * @return the number of results, SYSERR if the
+ *   iter is non-NULL and aborted the iteration
+ */
+static int d_get(const HashCode512 * key,
+                unsigned int type,
+                ResultHandler handler,
+                void * closure) {
+  sqlite3 * dbh;
+  sqlite3_stmt * stmt;
+
+  MUTEX_LOCK(lock);
+  if (SQLITE_OK != sqlite3_open(fn,
+                               &dbh)) {
+    db_reset(dbh);
+    MUTEX_UNLOCK(lock);    
+    return SYSERR;
+  }
+  db_init(dbh);
+  if (sq_prepare(dbh,
+                "SELECT * FROM ds071 WHERE key=? AND type=?",
+                &stmt) != SQLITE_OK) {
+    sqlite3_close(dbh);
+    MUTEX_UNLOCK(lock);
+    return SYSERR;
+  }
+  /* FIXME: run GET! */
+
+  sqlite3_finalize(stmt);
+  sqlite3_close(dbh);
+  MUTEX_UNLOCK(lock);
+  return 0;
+}
+
+Dstore_ServiceAPI *
+provide_module_dstore(CoreAPIForApplication * capi) {
+  static Dstore_ServiceAPI api;
+  int fd;
+
+#if DEBUG_SQLITE
+  GE_LOG(capi->ectx,
+        GE_DEBUG | GE_REQUEST | GE_USER,
+        "SQLite Dstore: initializing database\n");
+#endif
+  fn = STRDUP("/tmp/dstoreXXXXXX");
+  fd = mkstemp(fn);
+  if (fd == -1) {
+    FREE(fn);
+    return NULL;
+  }
+  CLOSE(fd);
+  lock = MUTEX_CREATE(NO);
+  coreAPI = capi;
+  api.get = &d_get;
+  api.put = &d_put;
+  return &api;
+}
+
+/**
+ * Shutdown the module.
+ */
+void release_module_dstore() {
+  UNLINK(fn);
+  FREE(fn);
+  fn = NULL;
+#if DEBUG_SQLITE
+  GE_LOG(coreAPI->ectx,
+        GE_DEBUG | GE_REQUEST | GE_USER,
+        "SQLite Dstore: database shutdown\n");
+#endif
+  MUTEX_DESTROY(lock);
+  coreAPI = NULL;
+}
+
+/* end of dstore.c */

Added: GNUnet/src/applications/dstore/dstore_test.c
===================================================================
--- GNUnet/src/applications/dstore/dstore_test.c        2006-12-03 05:21:11 UTC 
(rev 3857)
+++ GNUnet/src/applications/dstore/dstore_test.c        2006-12-03 06:35:19 UTC 
(rev 3858)
@@ -0,0 +1,105 @@
+/*
+     This file is part of GNUnet.
+     (C) 2006 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.
+*/
+/*
+ * @file applications/kvstore_sqlite/kv_sqlitetest.c
+ * @brief Test for the kvstore implementations.
+ * @author Nils Durner
+ */
+
+#include "platform.h"
+#include "gnunet_util.h"
+#include "gnunet_util_cron.h"
+#include "gnunet_util_config_impl.h"
+#include "gnunet_protocols.h"
+#include "gnunet_kvstore_service.h"
+#include "core.h"
+
+#define ASSERT(x) do { if (! (x)) { printf("Error at %s:%d\n", __FILE__, 
__LINE__); goto FAILURE;} } while (0)
+
+
+/**
+ * Add testcode here!
+ */
+static int test(KVstore_ServiceAPI * api) {
+  KVHandle *kv;
+  HashCode512 k, v;
+  HashCode512 *r;
+
+  cron_t timeStmp;
+
+  kv = api->getTable("TEST", "KV");
+  ASSERT(kv != NULL);
+
+  timeStmp = get_time();
+  ASSERT(api->put(kv, (void *) &k, sizeof(k), (void *) &v, sizeof(v),
+    timeStmp) == OK);
+
+  r = api->get(kv, (void *) &k, sizeof(k), 0, 0, NULL, NULL);
+  ASSERT(r != NULL);
+  ASSERT(memcmp(&v, r, sizeof(v)) == 0);
+  FREE(r);
+
+  ASSERT(api->del(kv, (void *) &k, sizeof(k), 0) == OK);
+
+  ASSERT(api->get(kv, (void *) &k, sizeof(k), 0, 0, NULL, NULL) == NULL);
+
+  ASSERT(api->dropTable(kv) == OK);
+
+  api->dropDatabase("TEST");
+
+  return OK;
+
+ FAILURE:
+  api->dropDatabase("TEST");
+  return SYSERR;
+}
+
+#define TEST_DB "/tmp/GNUnet_sqstore_test/"
+
+int main(int argc, char *argv[]) {
+  KVstore_ServiceAPI * api;
+  int ok;
+  struct GC_Configuration * cfg;
+  struct CronManager * cron;
+
+  cfg = GC_create_C_impl();
+  if (-1 == GC_parse_configuration(cfg,
+                                  "check.conf")) {
+    GC_free(cfg);
+    return -1;
+  }
+  cron = cron_create(NULL);
+  initCore(NULL,
+          cfg,
+          cron,
+          NULL);
+  api = requestService("kvstore_sqlite");
+  if (api != NULL) {
+    ok = test(api);
+    releaseService(api);
+  } else
+    ok = SYSERR;
+  doneCore();
+  if (ok == SYSERR)
+    return 1;
+  return 0;
+}
+
+/* end of kv_sqlitetest.c */

Modified: GNUnet/src/include/Makefile.am
===================================================================
--- GNUnet/src/include/Makefile.am      2006-12-03 05:21:11 UTC (rev 3857)
+++ GNUnet/src/include/Makefile.am      2006-12-03 06:35:19 UTC (rev 3858)
@@ -21,6 +21,7 @@
   gnunet_dht_lib.h \
   gnunet_dht_service.h \
   gnunet_directories.h \
+  gnunet_dstore_service.h \
   gnunet_ecrs_lib.h \
   gnunet_fragmentation_service.h \
   gnunet_fs_lib.h \

Added: GNUnet/src/include/gnunet_dstore_service.h
===================================================================
--- GNUnet/src/include/gnunet_dstore_service.h  2006-12-03 05:21:11 UTC (rev 
3857)
+++ GNUnet/src/include/gnunet_dstore_service.h  2006-12-03 06:35:19 UTC (rev 
3858)
@@ -0,0 +1,92 @@
+/*
+     This file is part of GNUnet
+     (C) 2006 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.
+*/
+
+/**
+ * @file include/gnunet_dstore_service.h
+ * @brief An SQ store is responsible for storing blocks with
+ *   additional indices that allow traversing the store in
+ *   order of expiration time or priority, in addition to
+ *   queries by key and block type.  The name comes from SQL,
+ *   because using an SQL database to do this should be
+ *   particularly easy.  But that is of course not the only
+ *   way to implement an dstore.
+ * @author Christian Grothoff
+ */
+
+#ifndef GNUNET_DSTORE_SERVICE_H
+#define GNUNET_DSTORE_SERVICE_H
+
+#include "gnunet_core.h"
+
+#ifdef __cplusplus
+extern "C" {
+#if 0 /* keep Emacsens' auto-indent happy */
+}
+#endif
+#endif
+
+typedef void (*ResultHandler)(const HashCode512 * key,
+                             unsigned int type,
+                             unsigned int size,
+                             const char * data,
+                             void * cls);
+
+/**
+ * @brief Definition of the SQ-Store API.
+ */
+typedef struct {
+
+  /**
+   * Store an item in the datastore.
+   *
+   * @return OK on success, SYSERR on error
+   */
+  int (*put)(const HashCode512 * key,
+            unsigned int type,
+            cron_t discard_time,
+            unsigned int size,
+            const char * data);
+
+  /**
+   * Iterate over the results for a particular key
+   * in the datastore.
+   *
+   * @param key 
+   * @param type entries of which type are relevant?
+   * @param iter maybe NULL (to just count)
+   * @return the number of results, SYSERR if the
+   *   iter is non-NULL and aborted the iteration
+   */
+  int (*get)(const HashCode512 * key,
+            unsigned int type,
+            ResultHandler handler,
+            void * closure);
+
+} Dstore_ServiceAPI;
+
+#if 0 /* keep Emacsens' auto-indent happy */
+{
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+/* end of gnunet_dstore_service.h */
+#endif

Modified: GNUnet/src/include/gnunet_kvstore_service.h
===================================================================
--- GNUnet/src/include/gnunet_kvstore_service.h 2006-12-03 05:21:11 UTC (rev 
3857)
+++ GNUnet/src/include/gnunet_kvstore_service.h 2006-12-03 06:35:19 UTC (rev 
3858)
@@ -40,10 +40,9 @@
 /**
  * @brief Handle to a Key/Value-Table
  */
-typedef struct
-{
-  char *table;
-  char *db;
+typedef struct {
+  char * table;
+  char * db;
 } KVHandle;
 
 /**
@@ -53,7 +52,9 @@
  * @param vallen the length von val
  * @return OK on success
  */
-typedef int (*KVCallback)(void *closure, void *val, int vallen);
+typedef int (*KVCallback)(void *closure, 
+                         void *val, 
+                         int vallen);
 
 
 /**
@@ -65,7 +66,8 @@
    * @param table the name of the Key/Value-Table
    * @return a handle
    */
-  KVHandle *(*getTable)(const char *database, const char *table);
+  KVHandle *(*getTable)(const char *database, 
+                       const char *table);
 
   /**
    * @brief Get data from a Key/Value-Table
@@ -77,8 +79,13 @@
    * @param handler callback function to be called for every result (may be 
NULL)
    * @param closure optional parameter for handler
    */
-  void * (*get)(KVHandle *kv, void *key, int keylen, unsigned int sort,
-    unsigned int limit, KVCallback handler, void *closure);
+  void * (*get)(KVHandle *kv,
+               void *key, 
+               int keylen,
+               unsigned int sort,
+               unsigned int limit,
+               KVCallback handler,
+               void *closure);
 
   /**
    * @brief Store Key/Value-Pair in a table
@@ -90,8 +97,12 @@
    * @param optional creation time
    * @return OK on success, SYSERR otherwise
    */
-  int (* put)(KVHandle *kv, void *key, int keylen, void *val, int vallen,
-    unsigned long long age);
+  int (* put)(KVHandle *kv,
+             void *key, 
+             int keylen,
+             void *val,
+             int vallen,
+             unsigned long long age);
 
   /**
    * @brief Delete values from a Key/Value-Table
@@ -100,7 +111,10 @@
    * @param age age of the items to delete (may be 0)
    * @return OK on success, SYSERR otherwise
    */
-  int (* del)(KVHandle *kv, void *key, int keylen, unsigned long long age);
+  int (* del)(KVHandle *kv,
+             void *key,
+             int keylen,
+             unsigned long long age);
 
   /**
    * @brief Close a handle to a Key/Value-Table
@@ -118,7 +132,7 @@
   /**
    * @brief Delete the database.
    */
-  void (* dropDatabase) (const char *name);
+  void (* dropDatabase)(const char *name);
 
 } KVstore_ServiceAPI;
 





reply via email to

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