aboutsummaryrefslogtreecommitdiff
path: root/src
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 /src
parent60605e947884726fe14c8896fa5c766f6e99742a (diff)
downloadgdbm-156f33c8aa5b5c113987c353bbd32c70f02f6a9d.tar.gz
gdbm-156f33c8aa5b5c113987c353bbd32c70f02f6a9d.tar.bz2
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
Diffstat (limited to 'src')
-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)
46 int rc; 46 int rc;
47 int key_size; 47 int key_size;
48 int data_size; 48 int data_size;
49 size_t dsize;
49 off_t file_pos; 50 off_t file_pos;
50 data_cache_elem *data_ca; 51 data_cache_elem *data_ca;
51 52
@@ -62,24 +63,44 @@ _gdbm_read_entry (GDBM_FILE dbf, int elem_loc)
62 /* Set sizes and pointers. */ 63 /* Set sizes and pointers. */
63 key_size = dbf->bucket->h_table[elem_loc].key_size; 64 key_size = dbf->bucket->h_table[elem_loc].key_size;
64 data_size = dbf->bucket->h_table[elem_loc].data_size; 65 data_size = dbf->bucket->h_table[elem_loc].data_size;
66 dsize = key_size + data_size;
65 data_ca = &dbf->cache_entry->ca_data; 67 data_ca = &dbf->cache_entry->ca_data;
66 68
67 /* Set up the cache. */ 69 /* Set up the cache. */
68 if (data_ca->dptr != NULL) free (data_ca->dptr);
69 data_ca->key_size = key_size; 70 data_ca->key_size = key_size;
70 data_ca->data_size = data_size; 71 data_ca->data_size = data_size;
71 data_ca->elem_loc = elem_loc; 72 data_ca->elem_loc = elem_loc;
72 data_ca->hash_val = dbf->bucket->h_table[elem_loc].hash_value; 73 data_ca->hash_val = dbf->bucket->h_table[elem_loc].hash_value;
73 74
74 if (key_size + data_size == 0) 75 if (dsize <= data_ca->dsize)
75 data_ca->dptr = (char *) malloc (1); 76 {
77 if (data_ca->dsize == 0)
78 {
79 data_ca->dptr = malloc (1);
80 if (data_ca->dptr)
81 data_ca->dsize = 1;
82 else
83 {
84 GDBM_SET_ERRNO2 (dbf, GDBM_MALLOC_ERROR, FALSE, GDBM_DEBUG_LOOKUP);
85 _gdbm_fatal (dbf, _("malloc error"));
86 return NULL;
87 }
88 }
89 }
76 else 90 else
77 data_ca->dptr = (char *) malloc (key_size + data_size);
78 if (data_ca->dptr == NULL)
79 { 91 {
80 GDBM_SET_ERRNO2 (dbf, GDBM_MALLOC_ERROR, FALSE, GDBM_DEBUG_LOOKUP); 92 char *p = realloc (data_ca->dptr, dsize);
81 _gdbm_fatal (dbf, _("malloc error")); 93 if (p)
82 return NULL; 94 {
95 data_ca->dptr = p;
96 data_ca->dsize = dsize;
97 }
98 else
99 {
100 GDBM_SET_ERRNO2 (dbf, GDBM_MALLOC_ERROR, FALSE, GDBM_DEBUG_LOOKUP);
101 _gdbm_fatal (dbf, _("malloc error"));
102 return NULL;
103 }
83 } 104 }
84 105
85 /* Read into the cache. */ 106 /* 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
149 149
150typedef struct 150typedef struct
151{ 151{
152 int hash_val; 152 int hash_val;
153 int data_size; 153 int data_size;
154 int key_size; 154 int key_size;
155 char *dptr; 155 char *dptr;
156 int elem_loc; 156 size_t dsize;
157 int elem_loc;
157} data_cache_elem; 158} data_cache_elem;
158 159
159typedef struct 160typedef 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)
88 /* Set the flags. */ 88 /* Set the flags. */
89 dbf->bucket_changed = TRUE; 89 dbf->bucket_changed = TRUE;
90 90
91 /* Clear out the data cache for the current bucket. */ 91 /* Invalidate data cache for the current bucket. */
92 if (dbf->cache_entry->ca_data.dptr != NULL)
93 {
94 free (dbf->cache_entry->ca_data.dptr);
95 dbf->cache_entry->ca_data.dptr = NULL;
96 }
97 dbf->cache_entry->ca_data.hash_val = -1; 92 dbf->cache_entry->ca_data.hash_val = -1;
98 dbf->cache_entry->ca_data.key_size = 0; 93 dbf->cache_entry->ca_data.key_size = 0;
99 dbf->cache_entry->ca_data.elem_loc = -1; 94 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)
663 return -1; 663 return -1;
664 } 664 }
665 dbf->bucket_cache[index].ca_data.dptr = NULL; 665 dbf->bucket_cache[index].ca_data.dptr = NULL;
666 dbf->bucket_cache[index].ca_data.dsize = 0;
666 _gdbm_cache_entry_invalidate (dbf, index); 667 _gdbm_cache_entry_invalidate (dbf, index);
667 } 668 }
668 dbf->bucket = dbf->bucket_cache[0].ca_bucket; 669 dbf->bucket = dbf->bucket_cache[0].ca_bucket;

Return to:

Send suggestions and report system problems to the System administrator.