summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2018-05-30 14:34:24 +0300
committerSergey Poznyakoff <gray@gnu.org>2018-05-30 14:34:24 +0300
commit156f33c8aa5b5c113987c353bbd32c70f02f6a9d (patch)
treecca8dde609d34b202c1b7d0a5148cfa38b129ba9
parent60605e947884726fe14c8896fa5c766f6e99742a (diff)
downloadgdbm-156f33c8aa5b5c113987c353bbd32c70f02f6a9d.tar.gz
Avoid unnecessary memory reallocations during caching
* src/findkey.c (_gdbm_read_entry): Reallocate cache_entry->ca_data.dptr only if necessary. * src/gdbmdefs.h (data_cache_elem): New member: dsize * src/gdbmdelete.c: Don't free cache_entry->ca_data.dptr * src/gdbmopen.c (_gdbm_init_cache): Initialize ca_data.dsize
-rw-r--r--src/findkey.c39
-rw-r--r--src/gdbmdefs.h11
-rw-r--r--src/gdbmdelete.c7
-rw-r--r--src/gdbmopen.c1
4 files changed, 38 insertions, 20 deletions
diff --git a/src/findkey.c b/src/findkey.c
index 9c8fd71..5560b28 100644
--- a/src/findkey.c
+++ b/src/findkey.c
@@ -46,6 +46,7 @@ _gdbm_read_entry (GDBM_FILE dbf, int elem_loc)
int rc;
int key_size;
int data_size;
+ size_t dsize;
off_t file_pos;
data_cache_elem *data_ca;
@@ -62,24 +63,44 @@ _gdbm_read_entry (GDBM_FILE dbf, int elem_loc)
/* Set sizes and pointers. */
key_size = dbf->bucket->h_table[elem_loc].key_size;
data_size = dbf->bucket->h_table[elem_loc].data_size;
+ dsize = key_size + data_size;
data_ca = &dbf->cache_entry->ca_data;
-
+
/* Set up the cache. */
- if (data_ca->dptr != NULL) free (data_ca->dptr);
data_ca->key_size = key_size;
data_ca->data_size = data_size;
data_ca->elem_loc = elem_loc;
data_ca->hash_val = dbf->bucket->h_table[elem_loc].hash_value;
- if (key_size + data_size == 0)
- data_ca->dptr = (char *) malloc (1);
+ if (dsize <= data_ca->dsize)
+ {
+ if (data_ca->dsize == 0)
+ {
+ data_ca->dptr = malloc (1);
+ if (data_ca->dptr)
+ data_ca->dsize = 1;
+ else
+ {
+ GDBM_SET_ERRNO2 (dbf, GDBM_MALLOC_ERROR, FALSE, GDBM_DEBUG_LOOKUP);
+ _gdbm_fatal (dbf, _("malloc error"));
+ return NULL;
+ }
+ }
+ }
else
- data_ca->dptr = (char *) malloc (key_size + data_size);
- if (data_ca->dptr == NULL)
{
- GDBM_SET_ERRNO2 (dbf, GDBM_MALLOC_ERROR, FALSE, GDBM_DEBUG_LOOKUP);
- _gdbm_fatal (dbf, _("malloc error"));
- return NULL;
+ char *p = realloc (data_ca->dptr, dsize);
+ if (p)
+ {
+ data_ca->dptr = p;
+ data_ca->dsize = dsize;
+ }
+ else
+ {
+ GDBM_SET_ERRNO2 (dbf, GDBM_MALLOC_ERROR, FALSE, GDBM_DEBUG_LOOKUP);
+ _gdbm_fatal (dbf, _("malloc error"));
+ return NULL;
+ }
}
/* Read into the cache. */
diff --git a/src/gdbmdefs.h b/src/gdbmdefs.h
index 4ae646f..af6f09c 100644
--- a/src/gdbmdefs.h
+++ b/src/gdbmdefs.h
@@ -149,11 +149,12 @@ typedef struct
typedef struct
{
- int hash_val;
- int data_size;
- int key_size;
- char *dptr;
- int elem_loc;
+ int hash_val;
+ int data_size;
+ int key_size;
+ char *dptr;
+ size_t dsize;
+ int elem_loc;
} data_cache_elem;
typedef struct
diff --git a/src/gdbmdelete.c b/src/gdbmdelete.c
index 5660d3a..ff13a1a 100644
--- a/src/gdbmdelete.c
+++ b/src/gdbmdelete.c
@@ -88,12 +88,7 @@ gdbm_delete (GDBM_FILE dbf, datum key)
/* Set the flags. */
dbf->bucket_changed = TRUE;
- /* Clear out the data cache for the current bucket. */
- if (dbf->cache_entry->ca_data.dptr != NULL)
- {
- free (dbf->cache_entry->ca_data.dptr);
- dbf->cache_entry->ca_data.dptr = NULL;
- }
+ /* Invalidate data cache for the current bucket. */
dbf->cache_entry->ca_data.hash_val = -1;
dbf->cache_entry->ca_data.key_size = 0;
dbf->cache_entry->ca_data.elem_loc = -1;
diff --git a/src/gdbmopen.c b/src/gdbmopen.c
index 31d8fea..03cc4f4 100644
--- a/src/gdbmopen.c
+++ b/src/gdbmopen.c
@@ -663,6 +663,7 @@ _gdbm_init_cache (GDBM_FILE dbf, size_t size)
return -1;
}
dbf->bucket_cache[index].ca_data.dptr = NULL;
+ dbf->bucket_cache[index].ca_data.dsize = 0;
_gdbm_cache_entry_invalidate (dbf, index);
}
dbf->bucket = dbf->bucket_cache[0].ca_bucket;