aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2016-07-14 21:02:05 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2016-07-14 21:02:05 +0300
commit5580c3248794803a8e45dd58b45933a32637954d (patch)
tree3067db40ccf49fab472d7fe3df31bae17d24df5b /src
parent66eb071ce6202a33dbf53dfc46e52b25d683290c (diff)
downloadgdbm-5580c3248794803a8e45dd58b45933a32637954d.tar.gz
gdbm-5580c3248794803a8e45dd58b45933a32637954d.tar.bz2
Don't use hardcoded constant
* src/gdbmconst.h (GDBM_HASH_BITS): New constant. * src/bucket.c: Use GDBM_HASH_BITS instead of the hardcoded value. * src/findkey.c (_gdbm_findkey): Use _gdbm_hash_key. * src/gdbmtool.c (hash_handler): Use _gdbm_hash_key if the database is open. * src/hash.c (_gdbm_bucket_dir, _gdbm_hash_key): New functions. * src/proto.h (_gdbm_bucket_dir, _gdbm_hash_key): New protos. * src/systems.h (STATBLKSIZE): Take a struct stat as argument. * src/gdbmopen.c (STATBLKSIZE): Takes argument now.
Diffstat (limited to 'src')
-rw-r--r--src/bucket.c8
-rw-r--r--src/findkey.c6
-rw-r--r--src/gdbmconst.h7
-rw-r--r--src/gdbmopen.c2
-rw-r--r--src/gdbmtool.c17
-rw-r--r--src/hash.c25
-rw-r--r--src/proto.h3
-rw-r--r--src/systems.h8
8 files changed, 51 insertions, 25 deletions
diff --git a/src/bucket.c b/src/bucket.c
index 96ed8b4..2696c10 100644
--- a/src/bucket.c
+++ b/src/bucket.c
@@ -180,8 +180,8 @@ _gdbm_split_bucket (GDBM_FILE dbf, int next_insert)
off_t *new_dir; /* Pointer to the new directory. */
off_t dir_adr; /* Address of the new directory. */
int dir_size; /* Size of the new directory. */
- off_t old_adr[31]; /* Address of the old directories. */
- int old_size[31]; /* Size of the old directories. */
+ off_t old_adr[GDBM_HASH_BITS]; /* Address of the old directories. */
+ int old_size[GDBM_HASH_BITS]; /* Size of the old directories. */
int old_count; /* Number of old directories. */
int index; /* Used in array indexing. */
@@ -281,7 +281,7 @@ _gdbm_split_bucket (GDBM_FILE dbf, int next_insert)
for (index = 0; index < dbf->header->bucket_elems; index++)
{
old_el = & (dbf->bucket->h_table[index]);
- select = (old_el->hash_value >> (31-new_bits)) & 1;
+ select = (old_el->hash_value >> (GDBM_HASH_BITS - new_bits)) & 1;
elem_loc = old_el->hash_value % dbf->header->bucket_elems;
while (bucket[select]->h_table[elem_loc].hash_value != -1)
elem_loc = (elem_loc + 1) % dbf->header->bucket_elems;
@@ -334,7 +334,7 @@ _gdbm_split_bucket (GDBM_FILE dbf, int next_insert)
dbf->second_changed = TRUE;
/* Update the cache! */
- dbf->bucket_dir = next_insert >> (31-dbf->header->dir_bits);
+ dbf->bucket_dir = _gdbm_bucket_dir (dbf, next_insert);
/* Invalidate old cache entry. */
old_bucket.av_adr = dbf->cache_entry->ca_adr;
diff --git a/src/findkey.c b/src/findkey.c
index 34091e1..3cd90ce 100644
--- a/src/findkey.c
+++ b/src/findkey.c
@@ -97,15 +97,16 @@ _gdbm_findkey (GDBM_FILE dbf, datum key, char **ret_dptr, int *ret_hash_val)
int bucket_hash_val; /* The hash value from the bucket. */
int new_hash_val; /* Computed hash value for the key */
char *file_key; /* The complete key as stored in the file. */
+ int bucket_dir; /* Number of the bucket in directory. */
int elem_loc; /* The location in the bucket. */
int home_loc; /* The home location in the bucket. */
int key_size; /* Size of the key on the file. */
/* Compute hash value and load proper bucket. */
- new_hash_val = _gdbm_hash (key);
+ _gdbm_hash_key (dbf, key, &new_hash_val, &bucket_dir, &elem_loc);
if (ret_hash_val)
*ret_hash_val = new_hash_val;
- if (_gdbm_get_bucket (dbf, new_hash_val >> (31 - dbf->header->dir_bits)))
+ if (_gdbm_get_bucket (dbf, bucket_dir))
return -1;
/* Is the element the last one found for this bucket? */
@@ -122,7 +123,6 @@ _gdbm_findkey (GDBM_FILE dbf, datum key, char **ret_dptr, int *ret_hash_val)
}
/* It is not the cached value, search for element in the bucket. */
- elem_loc = new_hash_val % dbf->header->bucket_elems;
home_loc = elem_loc;
bucket_hash_val = dbf->bucket->h_table[elem_loc].hash_value;
while (bucket_hash_val != -1)
diff --git a/src/gdbmconst.h b/src/gdbmconst.h
index 0002213..56820db 100644
--- a/src/gdbmconst.h
+++ b/src/gdbmconst.h
@@ -1,8 +1,8 @@
/* gdbmconst.h - The constants defined for use in gdbm. */
/* This file is part of GDBM, the GNU data base manager.
- Copyright (C) 1990, 1991, 1993, 2007, 2011, 2013 Free Software Foundation,
- Inc.
+ Copyright (C) 1990, 1991, 1993, 2007, 2011, 2013,
+ 2016 Free Software Foundation, Inc.
GDBM is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -35,6 +35,9 @@
#define GDBM_MAGIC32_SWAP 0xcd9a5713 /* MAGIC32 swapped. */
#define GDBM_MAGIC64_SWAP 0xcf9a5713 /* MAGIC64 swapped. */
+/* Size of a hash value, in bits */
+#define GDBM_HASH_BITS 31
+
/* In freeing blocks, we will ignore any blocks smaller (and equal) to
IGNORE_SIZE number of bytes. */
#define IGNORE_SIZE 4
diff --git a/src/gdbmopen.c b/src/gdbmopen.c
index e0bb102..52814df 100644
--- a/src/gdbmopen.c
+++ b/src/gdbmopen.c
@@ -216,7 +216,7 @@ gdbm_open (const char *file, int block_size, int flags, int mode,
/* Start with the blocksize. */
if (block_size < 512)
- file_block_size = STATBLKSIZE;
+ file_block_size = STATBLKSIZE(file_stat);
else
file_block_size = block_size;
diff --git a/src/gdbmtool.c b/src/gdbmtool.c
index a7f7363..7c760b4 100644
--- a/src/gdbmtool.c
+++ b/src/gdbmtool.c
@@ -693,12 +693,19 @@ print_header_handler (struct handler_param *param)
void
hash_handler (struct handler_param *param)
{
- int hashval = _gdbm_hash (PARAM_DATUM (param, 0));
- fprintf (param->fp, _("hash value = %x"), hashval);
if (gdbm_file)
- fprintf (param->fp, _(", bucket #%u, slot %u"),
- hashval >> (31 - gdbm_file->header->dir_bits),
- hashval % gdbm_file->header->bucket_elems);
+ fprintf (param->fp, _("hash value = %x"),
+ _gdbm_hash (PARAM_DATUM (param, 0)));
+ else
+ {
+ int hashval, bucket, off;
+ _gdbm_hash_key (gdbm_file, PARAM_DATUM (param, 0),
+ &hashval, &bucket, &off);
+ fprintf (param->fp, _("hash value = %x, bucket #%u, slot %u"),
+ hashval,
+ hashval >> (GDBM_HASH_BITS - gdbm_file->header->dir_bits),
+ hashval % gdbm_file->header->bucket_elems);
+ }
fprintf (param->fp, ".\n");
}
diff --git a/src/hash.c b/src/hash.c
index 316785d..1c6cb8e 100644
--- a/src/hash.c
+++ b/src/hash.c
@@ -22,11 +22,10 @@
#include "gdbmdefs.h"
-
-/* This hash function computes a 31 bit value. The value is used to index
- the hash directory using the top n bits. It is also used in a hash bucket
- to find the home position of the element by taking the value modulo the
- bucket hash table size. */
+/* This hash function computes a GDBM_HASH_BITS-bit value. The value is used
+ to index the hash directory using the top n bits. It is also used in a
+ hash bucket to find the home position of the element by taking the value
+ modulo the bucket hash table size. */
int
_gdbm_hash (datum key)
@@ -34,7 +33,6 @@ _gdbm_hash (datum key)
unsigned int value; /* Used to compute the hash value. */
int index; /* Used to cycle through random values. */
-
/* Set the initial value from key. */
value = 0x238F13AF * key.dsize;
for (index = 0; index < key.dsize; index++)
@@ -45,3 +43,18 @@ _gdbm_hash (datum key)
/* Return the value. */
return((int) value);
}
+
+int
+_gdbm_bucket_dir (GDBM_FILE dbf, int hash)
+{
+ return hash >> (GDBM_HASH_BITS - dbf->header->dir_bits);
+}
+
+void
+_gdbm_hash_key (GDBM_FILE dbf, datum key, int *hash, int *bucket, int *offset)
+{
+ int hashval = _gdbm_hash (key);
+ *hash = hashval;
+ *bucket = _gdbm_bucket_dir (dbf, hashval);
+ *offset = hashval % dbf->header->bucket_elems;
+}
diff --git a/src/proto.h b/src/proto.h
index 07ff378..ce5551f 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -38,6 +38,9 @@ int _gdbm_findkey (GDBM_FILE, datum, char **, int *);
/* From hash.c */
int _gdbm_hash (datum);
+void _gdbm_hash_key (GDBM_FILE dbf, datum key, int *hash, int *bucket,
+ int *offset);
+int _gdbm_bucket_dir (GDBM_FILE dbf, int hash);
/* From update.c */
int _gdbm_end_update (GDBM_FILE);
diff --git a/src/systems.h b/src/systems.h
index 3ebfe21..f10cd8d 100644
--- a/src/systems.h
+++ b/src/systems.h
@@ -1,8 +1,8 @@
/* systems.h - Most of the system dependant code and defines are here. */
/* This file is part of GDBM, the GNU data base manager.
- Copyright (C) 1990, 1991, 1993, 2007, 2011, 2013 Free Software Foundation,
- Inc.
+ Copyright (C) 1990, 1991, 1993, 2007, 2011, 2013,
+ 2016 Free Software Foundation, Inc.
GDBM is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -46,9 +46,9 @@
stat record. This code uses the BSD blocksize from stat. */
#if HAVE_STRUCT_STAT_ST_BLKSIZE
-# define STATBLKSIZE file_stat.st_blksize
+# define STATBLKSIZE(st) (st).st_blksize
#else
-# define STATBLKSIZE 1024
+# define STATBLKSIZE(st) 1024
#endif
/* Do we have ftruncate? */

Return to:

Send suggestions and report system problems to the System administrator.