diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-08-10 22:00:34 +0000 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-08-10 22:00:34 +0000 |
commit | 74f7fe561e31637bdbf21aeb817d4a22bbf9c91a (patch) | |
tree | bae9da9f2c749d290ad4f1764dc205bcd23b750e /src/gdbmsetopt.c | |
parent | 6b6dcc80555d77858733e44b72e92d1dc60e2c38 (diff) | |
download | gdbm-74f7fe561e31637bdbf21aeb817d4a22bbf9c91a.tar.gz gdbm-74f7fe561e31637bdbf21aeb817d4a22bbf9c91a.tar.bz2 |
Improve memory mapping support.
The new code is more flexible and performs better when
lots of inserts are being made (e.g. when populating the
database with new data).
* src/gdbm.h.in (GDBM_SETMAXMAPSIZE): New constant.
* src/gdbmconst.h (SIZE_T_MAX): New define.
* src/gdbmdefs.h (gdbm_file_info) <cache_size>: Change type
to size_t.
<mmap_inited,mapped_size_max>: New member.
<mapped_remap>: Remove.
* src/gdbmopen.c: Fix a typo.
(gdbm_open): Initialize new members.
(_gdbm_init_cache): Second argument is size_t.
* src/gdbmsetopt.c (gdbm_setopt): Optval argument is void*.
Handle GDBM_SETMAXMAPSIZE.
Improve error checking.
* src/mmap.c (_GDBM_IN_MAPPED_REGION_P): Fix comparison with
the lower bound.
(_GDBM_NEED_REMAP): Return true if mapped_region is NULL.
(SUM_FILE_SIZE): Rewrite.
(_gdbm_mapped_unmap): Don't call msync.
(_gdbm_internal_remap): Take 2 arguments, the second one
giving the new mapped size.
Unmap the region prior to remapping it.
Always pass NULL as the argument to mmap.
(_gdbm_mapped_remap): Rewrite the logic. Change semantics of the
third argument. All uses updated.
(_gdbm_mapped_init): Reflect the above changes.
(_gdbm_mapped_read,_gdbm_mapped_write): Use mmap_inited to decide
whether to use mmap, because mapped_region can be reset to zero
by another functions (namely, _gdbm_mapped_lseek).
Reset mmap_inited to FALSE, if _gdbm_mapped_remap fails.
(_gdbm_mapped_lseek): Rewrite offset computations. Invalidate
the mapped region.
* src/proto.h (_gdbm_init_cache): Change prototype.
* src/update.c (write_header, _gdbm_end_update): Remove checks
for dbf->mapped_region.
* tests/gtload.c: Implement the -maxmap option (set maximal
mapped memory size).
* doc/gdbm.texinfo: Document GDBM_SETMAXMAPSIZE.
Diffstat (limited to 'src/gdbmsetopt.c')
-rw-r--r-- | src/gdbmsetopt.c | 98 |
1 files changed, 67 insertions, 31 deletions
diff --git a/src/gdbmsetopt.c b/src/gdbmsetopt.c index 47f15fb..54a972f 100644 --- a/src/gdbmsetopt.c +++ b/src/gdbmsetopt.c @@ -23,10 +23,48 @@ /* operate on an already open descriptor. */ -/* ARGSUSED */ +static int +getbool (void *optval, int optlen) +{ + int n; + + if (!optval || optlen != sizeof (int) || + (((n = *(int*)optval) != TRUE) && n != FALSE)) + { + gdbm_errno = GDBM_OPT_ILLEGAL; + return -1; + } + return n; +} + +static int +get_size (void *optval, int optlen, size_t *ret) +{ + if (!optval) + { + gdbm_errno = GDBM_OPT_ILLEGAL; + return -1; + } + if (optlen == sizeof (unsigned)) + *ret = *(unsigned*) optval; + else if (optlen == sizeof (unsigned long)) + *ret = *(unsigned long*) optval; + else if (optlen == sizeof (size_t)) + *ret = *(size_t*) optval; + else + { + gdbm_errno = GDBM_OPT_ILLEGAL; + return -1; + } + return 0; +} + int -gdbm_setopt(GDBM_FILE dbf, int optflag, int *optval, int optlen) +gdbm_setopt (GDBM_FILE dbf, int optflag, void *optval, int optlen) { + int n; + size_t sz; + switch (optflag) { case GDBM_CACHESIZE: @@ -37,52 +75,50 @@ gdbm_setopt(GDBM_FILE dbf, int optflag, int *optval, int optlen) return -1; } - return _gdbm_init_cache(dbf, ((*optval) > 9) ? (*optval) : 10); + if (get_size (optval, optlen, &sz)) + return -1; + return _gdbm_init_cache (dbf, (sz > 9) ? sz : 10); case GDBM_FASTMODE: /* Obsolete form of SYNCMODE. */ - if (!optval || ((*optval != TRUE) && (*optval != FALSE))) - { - gdbm_errno = GDBM_OPT_ILLEGAL; - return -1; - } - - dbf->fast_write = *optval; + if ((n = getbool (optval, optlen)) == -1) + return -1; + dbf->fast_write = n; break; case GDBM_SYNCMODE: /* Optval will point to either true or false. */ - if (!optval || ((*optval != TRUE) && (*optval != FALSE))) - { - gdbm_errno = GDBM_OPT_ILLEGAL; - return -1; - } - - dbf->fast_write = !(*optval); + if ((n = getbool (optval, optlen)) == -1) + return -1; + dbf->fast_write = !n; break; case GDBM_CENTFREE: /* Optval will point to either true or false. */ - if (!optval || ((*optval != TRUE) && (*optval != FALSE))) - { - gdbm_errno = GDBM_OPT_ILLEGAL; - return -1; - } - - dbf->central_free = *optval; + if ((n = getbool (optval, optlen)) == -1) + return -1; + dbf->central_free = n; break; case GDBM_COALESCEBLKS: /* Optval will point to either true or false. */ - if (!optval || ((*optval != TRUE) && (*optval != FALSE))) - { - gdbm_errno = GDBM_OPT_ILLEGAL; - return -1; - } - - dbf->coalesce_blocks = *optval; + if ((n = getbool (optval, optlen)) == -1) + return -1; + dbf->coalesce_blocks = n; break; + case GDBM_SETMAXMAPSIZE: + { + size_t page_size = sysconf (_SC_PAGESIZE); + + if (get_size (optval, optlen, &sz)) + return -1; + dbf->mapped_size_max = ((sz + page_size - 1) / page_size) * + page_size; + _gdbm_mapped_init (dbf); + break; + } + default: gdbm_errno = GDBM_OPT_ILLEGAL; return -1; |