diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2016-07-19 12:01:48 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2016-07-19 12:58:16 +0300 |
commit | 85f1e72da83e3078e2ae1f78093ef0966e43cec1 (patch) | |
tree | b00707979e9088d5f7b7880d438260eb063c9160 /src/gdbmcount.c | |
parent | 8e83f209342e2b035bbb19efa87ec5295158ef65 (diff) | |
download | gdbm-85f1e72da83e3078e2ae1f78093ef0966e43cec1.tar.gz gdbm-85f1e72da83e3078e2ae1f78093ef0966e43cec1.tar.bz2 |
Implement gdbm_recover function
* configure.ac: Don't check for rename.
* src/Makefile.am (libgdbm_la_SOURCES): Add recover.c
* src/recover.c: New file.
* src/bucket.c (_gdbm_get_bucket): Remove extra space before [
* src/err.c (prerror): Take additional argument
(gdbm_perror): Print system errno if necessary.
* src/gdbm.h.in (GDBM_CLOERROR): New flag.
(gdbm_fd_open, gdbm_copy_meta): New proto.
(gdbm_last_syserr,gdbm_db_strerror,gdbm_recover): New proto.
(gdbm_syserr): New extern.
(gdbm_recovery): New struct.
(GDBM_RCVR_DEFAULT,GDBM_RCVR_ERRFUN)
(GDBM_RCVR_MAX_FAILED_KEYS)
(GDBM_RCVR_MAX_FAILED_BUCKETS)
(GDBM_RCVR_MAX_FAILURES)
(GDBM_RCVR_BACKUP): New flags.
(GDBM_BACKUP_FAILED): New error code.
* src/gdbmclose.c (gdbm_close): Work correctly if dbf->desc == -1.
* src/gdbmcount.c (gdbm_count): Remove spurious sorting.
Use _gdbm_next_bucket_dir for iterating over the buckets.
* src/gdbmdefs.h (struct gdbm_file_info)<last_syserror>
<last_errstr>: New members.
* src/gdbmerrno.c (gdbm_set_errno): Set last_syserror as well.
(gdbm_clear_error): Reset last_syserror.
(gdbm_last_syserr): New function.
(gdbm_errlist): New entry for GDBM_BACKUP_FAILED.
(gdbm_db_strerror): New function.
(gdbm_syserr): New global.
* src/gdbmload.c (get_parms): Buffer can be NULL.
* src/gdbmopen.c (gdbm_fd_open): New function.
(gdbm_open): Rewrite as a wrapper over gdbm_fd_open.
* src/gdbmreorg.c (gdbm_reorganize): Rewrite as a wrapper
over gdbm_recover.
* src/proto.h (_gdbm_next_bucket_dir): New proto.
* src/gdbmtool.c: New command: recover.
* tests/.gitignore: Add gtrecover
* tests/gtrecover.c: New test program.
* tests/Makefile.am: Build gtrecover
Diffstat (limited to 'src/gdbmcount.c')
-rw-r--r-- | src/gdbmcount.c | 44 |
1 files changed, 6 insertions, 38 deletions
diff --git a/src/gdbmcount.c b/src/gdbmcount.c index 861a708..b84696c 100644 --- a/src/gdbmcount.c +++ b/src/gdbmcount.c @@ -21,54 +21,22 @@ #include "autoconf.h" #include "gdbmdefs.h" -static int -compoff (const void *a, const void *b) -{ - if (*(off_t*)a < *(off_t*)b) - return -1; - if (*(off_t*)a > *(off_t*)b) - return 1; - return 0; -} - int gdbm_count (GDBM_FILE dbf, gdbm_count_t *pcount) { - hash_bucket bucket; int nbuckets = GDBM_DIR_COUNT (dbf); - off_t *sdir; gdbm_count_t count = 0; - int i, last; - int result; + int i; /* Return immediately if the database needs recovery */ GDBM_ASSERT_CONSISTENCY (dbf, -1); - sdir = malloc (dbf->header->dir_size); - if (!sdir) + for (i = 0; i < nbuckets; i = _gdbm_next_bucket_dir (dbf, i)) { - gdbm_set_errno (dbf, GDBM_MALLOC_ERROR, FALSE); - return -1; + if (_gdbm_get_bucket (dbf, i)) + return -1; + count += dbf->bucket->count; } - - memcpy (sdir, dbf->dir, dbf->header->dir_size); - qsort (sdir, nbuckets, sizeof (off_t), compoff); - - result = 0; - for (i = last = 0; i < nbuckets; i++) - { - if (i == 0 || sdir[i] != sdir[last]) - { - if (_gdbm_read_bucket_at (dbf, sdir[i], &bucket, sizeof bucket)) - { - result = -1; - break; - } - count += bucket.count; - last = i; - } - } - free (sdir); *pcount = count; - return result; + return 0; } |