aboutsummaryrefslogtreecommitdiff
path: root/src/gdbmsetopt.c
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2011-08-10 22:00:34 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2011-08-10 22:00:34 +0000
commit74f7fe561e31637bdbf21aeb817d4a22bbf9c91a (patch)
treebae9da9f2c749d290ad4f1764dc205bcd23b750e /src/gdbmsetopt.c
parent6b6dcc80555d77858733e44b72e92d1dc60e2c38 (diff)
downloadgdbm-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.c98
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;

Return to:

Send suggestions and report system problems to the System administrator.