diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/findkey.c | 39 | ||||
-rw-r--r-- | src/gdbmdefs.h | 11 | ||||
-rw-r--r-- | src/gdbmdelete.c | 7 | ||||
-rw-r--r-- | src/gdbmopen.c | 1 |
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; |