diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2016-07-14 21:02:05 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2016-07-14 21:02:05 +0300 |
commit | 5580c3248794803a8e45dd58b45933a32637954d (patch) | |
tree | 3067db40ccf49fab472d7fe3df31bae17d24df5b | |
parent | 66eb071ce6202a33dbf53dfc46e52b25d683290c (diff) | |
download | gdbm-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.
-rw-r--r-- | src/bucket.c | 8 | ||||
-rw-r--r-- | src/findkey.c | 6 | ||||
-rw-r--r-- | src/gdbmconst.h | 7 | ||||
-rw-r--r-- | src/gdbmopen.c | 2 | ||||
-rw-r--r-- | src/gdbmtool.c | 17 | ||||
-rw-r--r-- | src/hash.c | 25 | ||||
-rw-r--r-- | src/proto.h | 3 | ||||
-rw-r--r-- | src/systems.h | 8 |
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"); } @@ -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? */ |