aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog18
-rw-r--r--doc/gdbm.texinfo79
-rw-r--r--src/gdbm.h.in30
-rw-r--r--src/gdbmconst.h23
-rw-r--r--src/gdbmdefs.h3
-rw-r--r--src/gdbmopen.c11
-rw-r--r--src/gdbmreorg.c2
-rw-r--r--src/gdbmsetopt.c114
-rw-r--r--src/mmap.c10
9 files changed, 228 insertions, 62 deletions
diff --git a/ChangeLog b/ChangeLog
index 1b358b9..f7a97c6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,23 @@
2011-08-11 Sergey Poznyakoff <gray@gnu.org.ua>
+ Improve gdbm_setopt interface.
+
+ * src/gdbm.h.in (GDBM_OPENMASK): New constant.
+ * src/gdbmconst.h: Remove constants duplicated in
+ gdbm.h.in.
+ * src/gdbmdefs.h (gdbm_file_info) <allow_mmap>
+ <mmap_inited>: Replace with a single member: memory_mapping.
+ All callers updated.
+ (GDBM_SETCACHESIZE,GDBM_SETSYNCMODE)
+ (GDBM_SETCENTFREE,GDBM_SETCOALESCEBLKS): New option names.
+ (GDBM_SETMMAP,GDBM_GETMMAP,GDBM_GETFLAGS)
+ (GDBM_GETCACHESIZE,GDBM_GETSYNCMODE,GDBM_GETCENTFREE)
+ (GDBM_GETCOALESCEBLKS,GDBM_GETMAXMAPSIZE): New option codes.
+ * src/gdbmsetopt.c: Implement new options.
+ * doc/gdbm.texinfo: Document new options.
+
+2011-08-11 Sergey Poznyakoff <gray@gnu.org.ua>
+
Improve memory mapping support.
The new code is more flexible and performs better when
diff --git a/doc/gdbm.texinfo b/doc/gdbm.texinfo
index 5dc8a97..04efeea 100644
--- a/doc/gdbm.texinfo
+++ b/doc/gdbm.texinfo
@@ -739,7 +739,7 @@ open database.
@deftypefn {gdbm interface} int gdbm_setopt (GDBM_FILE @var{dbf}, int @var{option}, @
void *@var{value}, int @var{size})
-Sets an option on the database.
+Sets an option on the database or returns the value of an option.
The parameters are:
@@ -747,9 +747,10 @@ The parameters are:
@item dbf
The pointer returned by @code{gdbm_open}.
@item option
-The option to be set.
+The option to be set or retreived.
@item value
-A pointer to the value to which @var{option} will be set.
+A pointer to the value to which @var{option} will be set or where to
+place the option value (depending on the option).
@item size
The length of the data pointed to by @var{value}.
@end table
@@ -759,11 +760,29 @@ The valid options are:
@table @asis
@kwindex GDBM_CACHESIZE
-@item GDBM_CACHESIZE
+@kwindex GDBM_SETCACHESIZE
+@item GDBM_SETCACHESIZE
+@itemx GDBM_CACHESIZE
Set the size of the internal bucket cache. This option may only be
set once on each GDBM_FILE descriptor, and is set automatically to 100
upon the first access to the database. The @var{value} should point
-to an integer holding the desired cache size.
+to a @code{size_t} holding the desired cache size.
+
+The @samp{GDBM_CACHESIZE} option is provided for compatibility with
+earlier versions.
+
+@kwindex GDBM_GETCACHESIZE
+@item GDBM_GETCACHESIZE
+Return the size of the internal bucket cache. The @var{value} should
+point to a @code{size_t} variable, where the size will be stored.
+
+@kwindex GDBM_GETFLAGS
+@item GDBM_GETFLAGS
+Return the flags describing the state of the database. The @var{value} should
+point to a @code{int} variable where to store the flags. The return
+is the same as the flags used when opening the database (@pxref{Open,
+gdbm_open}), except that it reflects the current state (which may have
+been altered by another calls to @code{gdbm_setopt}.
@kwindex GDBM_FASTMODE
@item GDBM_FASTMODE
@@ -773,22 +792,34 @@ to an integer: @samp{TRUE} to enable fast mode, and @samp{FALSE} to
disable it.
This option is retained for compatibility with previous versions of
-@code{gdbm}. Its effect is the reverse of @code{GDBM_SYNCMODE}
+@code{gdbm}. Its effect is the reverse of @code{GDBM_SETSYNCMODE}
(see below).
+@kwindex GDBM_SETSYNCMODE
@kwindex GDBM_SYNCMODE
-@item GDBM_SYNCMODE
+@item GDBM_SETSYNCMODE
+@itemx GDBM_SYNCMODE
Turn on or off file system synchronization operations. This
setting defaults to off. The @var{value} should point
to an integer: @samp{TRUE} to turn synchronization on, and @samp{FALSE} to
turn it off.
Note, that this option is a reverse of @code{GDBM_FASTMODE},
-i.e. calling @code{GDBM_SYNCMODE} with @samp{TRUE} has the same effect
+i.e. calling @code{GDBM_SETSYNCMODE} with @samp{TRUE} has the same effect
as calling @code{GDBM_FASTMODE} with @samp{FALSE}.
+The @samp{GDBM_SYNCMODE} option is provided for compatibility with
+earlier versions.
+
+@kwindex GDBM_GETSYNCMODE
+@item GDBM_GETSYNCMODE
+Return the current synchronization status. The @var{value} should
+point to an @code{int} where the status will be stored.
+
+@kwindex GDBM_SETCENTFREE
@kwindex GDBM_CENTFREE
-@item GDBM_CENTFREE
+@item GDBM_SETCENTFREE
+@itemx GDBM_CENTFREE
@emph{NOTICE: This feature is still under study.}
Set central free block pool to either on or off. The default is off,
@@ -798,8 +829,13 @@ set, this option causes all subsequent free blocks to be placed in the
more quickly. The @var{value} should point to an integer: @samp{TRUE} to
turn central block pool on, and @samp{FALSE} to turn it off.
+The @samp{GDBM_CENTFREE} option is provided for compatibility with
+earlier versions.
+
+@kwindex GDBM_SETCOALESCEBLKS
@kwindex GDBM_COALESCEBLKS
-@item GDBM_COALESCEBLKS
+@item GDBM_SETCOALESCEBLKS
+@itemx GDBM_COALESCEBLKS
@emph{NOTICE: This feature is still under study.}
Set free block merging to either on or off. The default is off, which
@@ -810,13 +846,34 @@ used in conjunction with GDBM_CENTFREE. The @var{value} should point
to an integer: @samp{TRUE} to turn free block merging on, and @samp{FALSE} to
turn it off.
+@kwindex GDBM_GETCOALESCEBLKS
+@item GDBM_GETCOALESCEBLKS
+Return the current status of free block merging. The @var{value} should
+point to an @code{int} where the status will be stored.
+
@kwindex GDBM_SETMAXMAPSIZE
@item GDBM_SETMAXMAPSIZE
-Sets maximum size of the memory mapped region. The @var{value} should
+Sets maximum size of a memory mapped region. The @var{value} should
point to a value of type @code{size_t}, @code{unsigned long} or
@code{unsigned}. The actual value is rounded to the nearest page
boundary (the page size is obtained from
@code{sysconf(_SC_PAGESIZE)}).
+
+@kwindex GDBM_GETMAXMAPSIZE
+@item GDBM_GETMAXMAPSIZE
+Return the maximum size of a memory mapped region. The @var{value} should
+point to a value of type @code{size_t} where to return the data.
+
+@kwindex GDBM_SETMMAP
+@item GDBM_SETMMAP
+Enable or disable memory mapping mode. The @var{value} should point
+to an integer: @samp{TRUE} to enable memory mapping or @samp{FALSE} to
+disable it.
+
+@kwindex GDBM_GETMMAP
+@item GDBM_GETMMAP
+Check whether memory mapping is enabled. The @var{value} should point
+to an integer where to return the status.
@end table
The return value will be @samp{-1} upon failure, or @samp{0} upon
diff --git a/src/gdbm.h.in b/src/gdbm.h.in
index 8eaee79..da88777 100644
--- a/src/gdbm.h.in
+++ b/src/gdbm.h.in
@@ -35,6 +35,8 @@
#define GDBM_WRITER 1 /* A writer. */
#define GDBM_WRCREAT 2 /* A writer. Create the db if needed. */
#define GDBM_NEWDB 3 /* A writer. Always create a new db. */
+#define GDBM_OPENMASK 7 /* Mask for the above. */
+
#define GDBM_FAST 0x10 /* Write fast! => No fsyncs. OBSOLETE. */
#define GDBM_SYNC 0x20 /* Sync operations to the disk. */
#define GDBM_NOLOCK 0x40 /* Don't do file locking operations. */
@@ -46,12 +48,28 @@
#define GDBM_REPLACE 1 /* Always replace old data with new. */
/* Parameters to gdbm_setopt, specifing the type of operation to perform. */
-#define GDBM_CACHESIZE 1 /* Set the cache size. */
-#define GDBM_FASTMODE 2 /* Toggle fast mode. OBSOLETE. */
-#define GDBM_SYNCMODE 3 /* Turn on or off sync operations. */
-#define GDBM_CENTFREE 4 /* Keep all free blocks in the header. */
-#define GDBM_COALESCEBLKS 5 /* Attempt to coalesce free blocks. */
-#define GDBM_SETMAXMAPSIZE 6 /* Set maximum mapped memory size */
+#define GDBM_SETCACHESIZE 1 /* Set the cache size. */
+#define GDBM_FASTMODE 2 /* Toggle fast mode. OBSOLETE. */
+#define GDBM_SETSYNCMODE 3 /* Turn on or off sync operations. */
+#define GDBM_SETCENTFREE 4 /* Keep all free blocks in the header. */
+#define GDBM_SETCOALESCEBLKS 5 /* Attempt to coalesce free blocks. */
+#define GDBM_SETMAXMAPSIZE 6 /* Set maximum mapped memory size */
+#define GDBM_SETMMAP 7
+
+/* Compatibility defines: */
+#define GDBM_CACHESIZE GDBM_SETCACHESIZE
+#define GDBM_SYNCMODE GDBM_SETSYNCMODE
+#define GDBM_CENTFREE GDBM_SETCENTFREE
+#define GDBM_COALESCEBLKS GDBM_SETCENTFREE
+
+#define GDBM_GETFLAGS 8
+#define GDBM_GETMMAP 9
+#define GDBM_GETCACHESIZE 10
+#define GDBM_GETSYNCMODE 11
+#define GDBM_GETCENTFREE 12
+#define GDBM_GETCOALESCEBLKS 13
+#define GDBM_GETMAXMAPSIZE 14
+
/* The data and key structure. */
typedef struct {
diff --git a/src/gdbmconst.h b/src/gdbmconst.h
index 7a3f5b9..24eac5f 100644
--- a/src/gdbmconst.h
+++ b/src/gdbmconst.h
@@ -35,29 +35,6 @@
#define GDBM_MAGIC32_SWAP 0xcd9a5713 /* MAGIC32 swapped. */
#define GDBM_MAGIC64_SWAP 0xcf9a5713 /* MAGIC64 swapped. */
-/* Parameters to gdbm_open. */
-#define GDBM_READER 0 /* READERS only. */
-#define GDBM_WRITER 1 /* READERS and WRITERS. Can not create. */
-#define GDBM_WRCREAT 2 /* If not found, create the db. */
-#define GDBM_NEWDB 3 /* ALWAYS create a new db. (WRITER) */
-#define GDBM_OPENMASK 7 /* Mask for the above. */
-#define GDBM_FAST 0x10 /* Write fast! => No fsyncs. OBSOLETE. */
-#define GDBM_SYNC 0x20 /* Sync operations to the disk. */
-#define GDBM_NOLOCK 0x40 /* Don't do file locking operations. */
-#define GDBM_NOMMAP 0x80 /* Don't use mmap(). */
-
-/* Parameters to gdbm_store for simple insertion or replacement in the
- case a key to store is already in the database. */
-#define GDBM_INSERT 0 /* Do not overwrite data in the database. */
-#define GDBM_REPLACE 1 /* Replace the old value with the new value. */
-
-/* Parameters to gdbm_setopt, specifing the type of operation to perform. */
-#define GDBM_CACHESIZE 1 /* Set the cache size. */
-#define GDBM_FASTMODE 2 /* Turn on or off fast mode. OBSOLETE. */
-#define GDBM_SYNCMODE 3 /* Turn on or off sync operations. */
-#define GDBM_CENTFREE 4 /* Keep all free blocks in the header. */
-#define GDBM_COALESCEBLKS 5 /* Attempt to coalesce free blocks. */
-
/* 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/gdbmdefs.h b/src/gdbmdefs.h
index 2221aa5..e45abf8 100644
--- a/src/gdbmdefs.h
+++ b/src/gdbmdefs.h
@@ -150,8 +150,7 @@ struct gdbm_file_info {
unsigned file_locking :1;
/* Whether or not we're allowing mmap() use. */
- unsigned allow_mmap :1;
- unsigned mmap_inited :1;
+ unsigned memory_mapping :1;
/* Type of file locking in use. */
enum { LOCKING_NONE = 0, LOCKING_FLOCK, LOCKING_LOCKF,
diff --git a/src/gdbmopen.c b/src/gdbmopen.c
index a110d64..b1b38b4 100644
--- a/src/gdbmopen.c
+++ b/src/gdbmopen.c
@@ -84,7 +84,7 @@ gdbm_open (const char *file, int block_size, int flags, int mode,
dbf->bucket_cache = NULL;
dbf->cache_size = 0;
- dbf->mmap_inited = FALSE;
+ dbf->memory_mapping = FALSE;
dbf->mapped_size_max = SIZE_T_MAX;
dbf->mapped_region = NULL;
dbf->mapped_size = 0;
@@ -109,7 +109,6 @@ gdbm_open (const char *file, int block_size, int flags, int mode,
dbf->file_locking = TRUE; /* Default to doing file locking. */
dbf->central_free = FALSE; /* Default to not using central_free. */
dbf->coalesce_blocks = FALSE; /* Default to not coalescing blocks. */
- dbf->allow_mmap = TRUE; /* Default to using mmap(). */
/* GDBM_FAST used to determine whether or not we set fast_write. */
if (flags & GDBM_SYNC)
@@ -121,10 +120,6 @@ gdbm_open (const char *file, int block_size, int flags, int mode,
{
dbf->file_locking = FALSE;
}
- if (flags & GDBM_NOMMAP)
- {
- dbf->allow_mmap = FALSE;
- }
/* Open the file. */
need_trunc = FALSE;
@@ -395,10 +390,10 @@ gdbm_open (const char *file, int block_size, int flags, int mode,
}
#if HAVE_MMAP
- if (dbf->allow_mmap)
+ if (!(flags & GDBM_NOMMAP))
{
if (_gdbm_mapped_init (dbf) == 0)
- dbf->mmap_inited = TRUE;
+ dbf->memory_mapping = TRUE;
else
{
/* gdbm_errno should already be set. */
diff --git a/src/gdbmreorg.c b/src/gdbmreorg.c
index aed372e..6bde222 100644
--- a/src/gdbmreorg.c
+++ b/src/gdbmreorg.c
@@ -176,7 +176,7 @@ gdbm_reorganize (GDBM_FILE dbf)
}
/* Re-initialize mapping if required */
- if (dbf->allow_mmap)
+ if (dbf->memory_mapping)
_gdbm_mapped_init (dbf);
dbf->desc = new_dbf->desc;
diff --git a/src/gdbmsetopt.c b/src/gdbmsetopt.c
index 54a972f..f9494d0 100644
--- a/src/gdbmsetopt.c
+++ b/src/gdbmsetopt.c
@@ -67,7 +67,9 @@ gdbm_setopt (GDBM_FILE dbf, int optflag, void *optval, int optlen)
switch (optflag)
{
- case GDBM_CACHESIZE:
+ /* Cache size: */
+
+ case GDBM_SETCACHESIZE:
/* Optval will point to the new size of the cache. */
if (dbf->bucket_cache != NULL)
{
@@ -79,34 +81,105 @@ gdbm_setopt (GDBM_FILE dbf, int optflag, void *optval, int optlen)
return -1;
return _gdbm_init_cache (dbf, (sz > 9) ? sz : 10);
+ case GDBM_GETCACHESIZE:
+ if (!optval || optlen != sizeof (size_t))
+ {
+ gdbm_errno = GDBM_OPT_ILLEGAL;
+ return -1;
+ }
+ *(size_t*) optval = dbf->cache_size;
+ break;
+
+ /* Obsolete form of GDBM_SETSYNCMODE. */
case GDBM_FASTMODE:
- /* Obsolete form of SYNCMODE. */
if ((n = getbool (optval, optlen)) == -1)
return -1;
dbf->fast_write = n;
break;
-
- case GDBM_SYNCMODE:
+
+ /* SYNC mode: */
+
+ case GDBM_SETSYNCMODE:
/* Optval will point to either true or false. */
if ((n = getbool (optval, optlen)) == -1)
return -1;
dbf->fast_write = !n;
break;
- case GDBM_CENTFREE:
+ case GDBM_GETSYNCMODE:
+ if (!optval || optlen != sizeof (int))
+ {
+ gdbm_errno = GDBM_OPT_ILLEGAL;
+ return -1;
+ }
+ *(int*) optval = !dbf->fast_write;
+ break;
+
+ /* CENTFREE - set or get the stat of the central block repository */
+ case GDBM_SETCENTFREE:
/* Optval will point to either true or false. */
if ((n = getbool (optval, optlen)) == -1)
return -1;
dbf->central_free = n;
break;
- case GDBM_COALESCEBLKS:
+ case GDBM_GETCENTFREE:
+ if (!optval || optlen != sizeof (int))
+ {
+ gdbm_errno = GDBM_OPT_ILLEGAL;
+ return -1;
+ }
+ *(int*) optval = !dbf->central_free;
+ break;
+
+ /* Coalesce state: */
+ case GDBM_SETCOALESCEBLKS:
/* Optval will point to either true or false. */
if ((n = getbool (optval, optlen)) == -1)
return -1;
dbf->coalesce_blocks = n;
break;
+ case GDBM_GETCOALESCEBLKS:
+ if (!optval || optlen != sizeof (int))
+ {
+ gdbm_errno = GDBM_OPT_ILLEGAL;
+ return -1;
+ }
+ *(int*) optval = dbf->coalesce_blocks;
+ break;
+
+ /* Mmap mode */
+ case GDBM_SETMMAP:
+ if ((n = getbool (optval, optlen)) == -1)
+ return -1;
+ __fsync (dbf);
+ if (n == dbf->memory_mapping)
+ return 0;
+ if (n)
+ {
+ if (_gdbm_mapped_init (dbf) == 0)
+ dbf->memory_mapping = TRUE;
+ else
+ return -1;
+ }
+ else
+ {
+ _gdbm_mapped_unmap (dbf);
+ dbf->memory_mapping = FALSE;
+ }
+ break;
+
+ case GDBM_GETMMAP:
+ if (!optval || optlen != sizeof (int))
+ {
+ gdbm_errno = GDBM_OPT_ILLEGAL;
+ return -1;
+ }
+ *(int*) optval = dbf->memory_mapping;
+ break;
+
+ /* Maximum size of a memory mapped region */
case GDBM_SETMAXMAPSIZE:
{
size_t page_size = sysconf (_SC_PAGESIZE);
@@ -119,6 +192,35 @@ gdbm_setopt (GDBM_FILE dbf, int optflag, void *optval, int optlen)
break;
}
+ case GDBM_GETMAXMAPSIZE:
+ if (!optval || optlen != sizeof (size_t))
+ {
+ gdbm_errno = GDBM_OPT_ILLEGAL;
+ return -1;
+ }
+ *(size_t*) optval = dbf->mapped_size_max;
+ break;
+
+ /* Flags */
+ case GDBM_GETFLAGS:
+ if (!optval || optlen != sizeof (int))
+ {
+ gdbm_errno = GDBM_OPT_ILLEGAL;
+ return -1;
+ }
+ else
+ {
+ int flags = dbf->read_write;
+ if (!dbf->fast_write)
+ flags |= GDBM_SYNC;
+ if (!dbf->file_locking)
+ flags |= GDBM_NOLOCK;
+ if (!dbf->memory_mapping)
+ flags |= GDBM_NOMMAP;
+ *(int*) optval = flags;
+ }
+ break;
+
default:
gdbm_errno = GDBM_OPT_ILLEGAL;
return -1;
diff --git a/src/mmap.c b/src/mmap.c
index 2107bd6..f654af3 100644
--- a/src/mmap.c
+++ b/src/mmap.c
@@ -208,7 +208,7 @@ _gdbm_mapped_init (GDBM_FILE dbf)
ssize_t
_gdbm_mapped_read (GDBM_FILE dbf, void *buffer, size_t len)
{
- if (dbf->mmap_inited)
+ if (dbf->memory_mapping)
{
ssize_t total = 0;
char *cbuf = buffer;
@@ -225,7 +225,7 @@ _gdbm_mapped_read (GDBM_FILE dbf, void *buffer, size_t len)
{
int rc;
- dbf->mmap_inited = FALSE;
+ dbf->memory_mapping = FALSE;
if (lseek (dbf->desc, pos, SEEK_SET) != pos)
return total > 0 ? total : -1;
rc = read (dbf->desc, cbuf, len);
@@ -258,7 +258,7 @@ _gdbm_mapped_read (GDBM_FILE dbf, void *buffer, size_t len)
ssize_t
_gdbm_mapped_write (GDBM_FILE dbf, void *buffer, size_t len)
{
- if (dbf->mmap_inited)
+ if (dbf->memory_mapping)
{
ssize_t total = 0;
char *cbuf = buffer;
@@ -275,7 +275,7 @@ _gdbm_mapped_write (GDBM_FILE dbf, void *buffer, size_t len)
{
int rc;
- dbf->mmap_inited = FALSE;
+ dbf->memory_mapping = FALSE;
if (lseek (dbf->desc, pos, SEEK_SET) != pos)
return total > 0 ? total : -1;
rc = write (dbf->desc, cbuf, len);
@@ -312,7 +312,7 @@ _gdbm_mapped_write (GDBM_FILE dbf, void *buffer, size_t len)
off_t
_gdbm_mapped_lseek (GDBM_FILE dbf, off_t offset, int whence)
{
- if (dbf->mmap_inited)
+ if (dbf->memory_mapping)
{
off_t needle;

Return to:

Send suggestions and report system problems to the System administrator.