Imported Upstream version 1.11
[platform/upstream/gdbm.git] / src / gdbmcount.c
1 /* gdbmcount.c - get number of items in a gdbm file. */
2
3 /* This file is part of GDBM, the GNU data base manager.
4    Copyright (C) 1993, 1994, 2007, 2011, 2013 Free Software Foundation, Inc.
5
6    GDBM is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3, or (at your option)
9    any later version.
10
11    GDBM is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with GDBM. If not, see <http://www.gnu.org/licenses/>.   */
18
19 /* Include system configuration before all else. */
20 #include "autoconf.h"
21 #include "gdbmdefs.h"
22
23 static int
24 compoff (const void *a, const void *b)
25 {
26   if (*(off_t*)a < *(off_t*)b)
27     return -1;
28   if (*(off_t*)a > *(off_t*)b)
29     return 1;
30   return 0;
31 }
32   
33 int
34 gdbm_count (GDBM_FILE dbf, gdbm_count_t *pcount)
35 {
36   hash_bucket bucket;
37   int nbuckets = GDBM_DIR_COUNT (dbf);
38   off_t *sdir;
39   gdbm_count_t count = 0;
40   int i, last;
41   
42   sdir = malloc (dbf->header->dir_size);
43   if (!sdir)
44     {
45       gdbm_errno = GDBM_MALLOC_ERROR;
46       return -1;
47     }
48   
49   memcpy (sdir, dbf->dir, dbf->header->dir_size);
50   qsort (sdir, nbuckets, sizeof (off_t), compoff);
51
52   for (i = last = 0; i < nbuckets; i++)
53     {
54       if (i == 0 || sdir[i] != sdir[last])
55         {
56           if (_gdbm_read_bucket_at (dbf, sdir[i], &bucket, sizeof bucket))
57             return -1;
58           count += bucket.count;
59           last = i;
60         }
61     }
62   free (sdir);
63   *pcount = count;
64   return 0;
65 }