Not logged in

Artifact c17d316f3c0eab90128e3065e80d36a6bae1fa71:


/* zdb.c

   Copyright © 2013, 2016 Brandon Invergo <brandon@invergo.net>

   This file is part of zeptodb

   zeptodb 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 3 of the License, or
   (at your option) any later version.

   zeptodb 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 zeptodb.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "zdb.h"

GDBM_FILE
zdb_open (char *dbfile, int mode, size_t mmap_size, size_t cache_size,
          size_t block_size, bool verbose)
{
  if (verbose)
    printf ("Opening database %s\n", dbfile);
  GDBM_FILE database;
  int gdbm_mode = 0;
  if ((mode & ZDB_READER) == ZDB_READER)
    gdbm_mode ^= GDBM_READER;
  else if ((mode & ZDB_WRITER) == ZDB_WRITER)
    gdbm_mode ^= GDBM_WRITER;
  else if ((mode & ZDB_CREATOR) == ZDB_CREATOR)
    gdbm_mode ^= GDBM_NEWDB;
  if ((mode & ZDB_SYNC) == ZDB_SYNC)
    gdbm_mode ^= GDBM_SYNC;
  if ((mode & ZDB_NOLOCK) == ZDB_NOLOCK)
    gdbm_mode ^= GDBM_NOLOCK;
  if ((mode & ZDB_NOMMAP) == ZDB_NOMMAP)
    gdbm_mode ^= GDBM_NOMMAP;
  database = gdbm_open (dbfile, (int) block_size, gdbm_mode,
                        S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, NULL);
  if (!database)
    error (EXIT_FAILURE, errno, "Failed to open database %s", dbfile);
  gdbm_setopt (database, GDBM_SETMAXMAPSIZE, &mmap_size, sizeof (size_t));
  gdbm_setopt (database, GDBM_SETCACHESIZE, &cache_size, sizeof (size_t));
  return database;
}

int
zdb_close (GDBM_FILE database, bool verbose)
{
  if (verbose)
    printf ("Closing database\n");
  gdbm_close (database);
  return 0;
}

int
zdb_store (GDBM_FILE database, char *key_str, size_t key_size, char *value_str,
           size_t value_size, bool verbose)
{
  if (verbose)
    printf ("Storing %s|%s                             \n", key_str, value_str);
  datum key, value;
  value.dptr = value_str;
  value.dsize = value_size;
  key.dptr = key_str;
  key.dsize = key_size;
  if (gdbm_store (database, key, value, GDBM_REPLACE))
    return 1;
  return 0;
}

void
printrec (char *key, char *value, char *delim)
{
  if (delim)
    printf ("%s%s%s\n", key, delim, value);
  else
    printf ("%s\n", value);
}

int
zdb_fetch (GDBM_FILE database, char *key_str, size_t key_size, char *delim)
{
  char *value_str;
  datum key, value;
  key.dptr = key_str;
  key.dsize = key_size;
  value = gdbm_fetch (database, key);
  if (value.dptr == NULL)
    return 1;
  value_str = strndup (value.dptr, value.dsize);
  free (value.dptr);
  if (!value_str)
    return 1;
  printrec (key_str, value_str, delim);
  free (value_str);
  return 0;
}

int
zdb_fetchall (GDBM_FILE database, char *delim)
{
  char *key_str;
  char *value_str;
  datum key, nextkey, value;
  key = gdbm_firstkey (database);
  while (key.dptr)
    {
      value = gdbm_fetch (database, key);
      if (value.dptr == NULL)
        error (0, errno, "Key with non-existent value: %s", key.dptr);
      value_str = strndup (value.dptr, value.dsize);
      key_str = strndup (key.dptr, key.dsize);
      printrec (key_str, value_str, delim);
      free (value.dptr);
      free (key_str);
      free (value_str);
      nextkey = gdbm_nextkey (database, key);
      free (key.dptr);
      key = nextkey;
    }
  return (0);
}

int
zdb_remove (GDBM_FILE database, char *key_str, size_t key_size, bool verbose)
{
  if (verbose)
    printf ("Removing %s\r", key_str);
  datum key;
  key.dptr = key_str;
  key.dsize = key_size;
  if (gdbm_delete (database, key))
    return 1;
  return 0;
}

int
zdb_reorganize (GDBM_FILE database)
{
  if (gdbm_reorganize (database))
    return 1;
  return 0;
}

void
zdb_print_info (GDBM_FILE database)
{
  size_t cache_size;
  size_t mmap_size;
  int mmap;
  gdbm_count_t num_records;
  gdbm_setopt (database, GDBM_GETCACHESIZE, &cache_size, sizeof (size_t));
  gdbm_setopt (database, GDBM_GETMAXMAPSIZE, &mmap_size, sizeof (size_t));
  gdbm_setopt (database, GDBM_GETMMAP, &mmap, sizeof (int));
  if (gdbm_count (database, &num_records))
    error (0, errno, "Error counting records");
  printf ("Bucket cache size:\t%zd\n", cache_size);
  if (mmap)
    {
      puts ("Memory-map enabled:\ttrue");
      printf ("Memory-map size:\t%zd\n", mmap_size);
    }
  else
    {
      puts ("Memory-map enabled:\tfalse");
    }
  printf ("Number of records:\t%lld\n", num_records);
  return;
}