aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2019-11-13 16:47:27 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2019-11-13 16:47:27 +0200
commit6534535f18c41304b6623c4afd42e20da941e061 (patch)
tree623d07f88a2f6900c24b97b81faca6f6825f9d80
parent5144dd6833fa60ba443d4d36c6cee64d0a382240 (diff)
downloadgdbm-6534535f18c41304b6623c4afd42e20da941e061.tar.gz
gdbm-6534535f18c41304b6623c4afd42e20da941e061.tar.bz2
Move cache element allocation to bucket.c.
* src/bucket.c (_gdbm_cache_elem_new): Rename to cache_elem_new. Make static. (cache_lookup): Allocate new elem if _gdbm_cache_tree_lookup returned node_new. * src/cachetree.c (cache_tree): Remove dbf. (_gdbm_cache_tree_delete): Use node->adr. (cache_tree_lookup): Rename to _gdbm_cache_tree_lookup. Change signature. Return pointer to the (found or inserted) node. Don't allocate elem, this is responsibility of the caller. (_gdbm_cache_tree_alloc): Change signature. * src/gdbmdefs.h (cache_node): New definition (from cachetree.c) * src/proto.h: Fix protos.
-rw-r--r--src/bucket.c17
-rw-r--r--src/cachetree.c62
-rw-r--r--src/gdbmdefs.h13
-rw-r--r--src/gdbmopen.c2
-rw-r--r--src/proto.h6
5 files changed, 45 insertions, 55 deletions
diff --git a/src/bucket.c b/src/bucket.c
index f04423c..308908b 100644
--- a/src/bucket.c
+++ b/src/bucket.c
@@ -116,8 +116,8 @@ lru_unlink_elem (GDBM_FILE dbf, cache_elem *elem)
but not linked to the LRU list.
Return NULL on error.
*/
-cache_elem *
-_gdbm_cache_elem_new (GDBM_FILE dbf, off_t adr)
+static cache_elem *
+cache_elem_new (GDBM_FILE dbf, off_t adr)
{
cache_elem *elem;
@@ -170,18 +170,29 @@ static int
cache_lookup (GDBM_FILE dbf, off_t adr, cache_elem *ref, cache_elem **ret_elem)
{
int rc;
+ cache_node *node;
cache_elem *elem;
dbf->cache_access_count++;
- rc = _gdbm_cache_tree_lookup (dbf->cache_tree, adr, &elem);
+ rc = _gdbm_cache_tree_lookup (dbf->cache_tree, adr, &node);
switch (rc)
{
case node_found:
+ elem = node->elem;
elem->ca_hits++;
lru_unlink_elem (dbf, elem);
break;
case node_new:
+ elem = cache_elem_new (dbf, adr);
+ if (!elem)
+ {
+ _gdbm_cache_tree_delete (dbf->cache_tree, node);
+ return node_failure;
+ }
+ elem->ca_node = node;
+ node->elem = elem;
+
if (dbf->cache_num > dbf->cache_size)
{
cache_elem *last = dbf->cache_lru;
diff --git a/src/cachetree.c b/src/cachetree.c
index 0851d09..d6d7f1e 100644
--- a/src/cachetree.c
+++ b/src/cachetree.c
@@ -23,19 +23,10 @@
enum cache_node_color { RED, BLACK };
-typedef struct cache_node cache_node;
-struct cache_node
-{
- cache_node *left, *right, *parent;
- enum cache_node_color color;
- cache_elem *elem;
-};
-
struct cache_tree
{
cache_node *root; /* Root of the tree */
cache_node *avail; /* List of available nodes, linked by parent field */
- GDBM_FILE dbf; /* Database this tree belongs to */
};
/* Allocate and return a new node. Pick the head item from the avail
@@ -178,6 +169,7 @@ _gdbm_cache_tree_delete (cache_tree *tree, cache_node *n)
cache_node *p;
for (p = n->left; p->right; p = p->right)
;
+ n->adr = p->adr;
n->elem = p->elem;
n->elem->ca_node = n;
n = p;
@@ -319,7 +311,7 @@ rbt_delete_fixup (cache_tree *tree, cache_node *n)
/* Insertion */
static void rbt_insert_fixup (cache_tree *tree, cache_node *n);
-/* Look up the node with elem->ca_adr equal to ADR.
+/* Look up the node with the given ADR.
If found, put it in *RETVAL and return node_found.
Otherwise, if INSERT is TRUE, create a new node and insert it in the
@@ -329,9 +321,8 @@ static void rbt_insert_fixup (cache_tree *tree, cache_node *n);
Otherwise, if INSERT is FALSE, store NULL in *RETVAL and return node_new.
*/
-static int
-cache_tree_lookup (cache_tree *tree, off_t adr, int insert,
- cache_node **retval)
+int
+_gdbm_cache_tree_lookup (cache_tree *tree, off_t adr, cache_node **retval)
{
int res;
cache_node *node, *parent = NULL;
@@ -340,10 +331,10 @@ cache_tree_lookup (cache_tree *tree, off_t adr, int insert,
nodeptr = &tree->root;
while ((node = *nodeptr) != NULL)
{
- if (adr == node->elem->ca_adr)
+ if (adr == node->adr)
break;
parent = node;
- if (adr < node->elem->ca_adr)
+ if (adr < node->adr)
nodeptr = &node->left;
else
nodeptr = &node->right;
@@ -355,22 +346,13 @@ cache_tree_lookup (cache_tree *tree, off_t adr, int insert,
}
else
{
- if (insert)
- {
- node = rbt_node_alloc (tree);
- if (!node)
- return node_failure;
- node->elem = _gdbm_cache_elem_new (tree->dbf, adr);
- if (!node->elem)
- {
- rbt_node_dealloc (tree, node);
- return node_failure;
- }
- node->elem->ca_node = node;
- *nodeptr = node;
- node->parent = parent;
- rbt_insert_fixup (tree, node);
- }
+ node = rbt_node_alloc (tree);
+ if (!node)
+ return node_failure;
+ *nodeptr = node;
+ node->adr = adr;
+ node->parent = parent;
+ rbt_insert_fixup (tree, node);
res = node_new;
}
*retval = node;
@@ -458,14 +440,13 @@ rbt_insert_fixup (cache_tree *tree, cache_node *n)
/* Create a cache tree structure for the database file DBF. */
cache_tree *
-_gdbm_cache_tree_alloc (GDBM_FILE dbf)
+_gdbm_cache_tree_alloc (void)
{
cache_tree *t = malloc (sizeof (*t));
if (t)
{
t->root = NULL;
t->avail = NULL;
- t->dbf = dbf;
}
return t;
}
@@ -485,17 +466,8 @@ _gdbm_cache_tree_destroy (cache_tree *tree)
free (tree);
}
-/* Look up the node with elem->ca_adr equal to ADR.
- If found, store its pointer in *RETVAL and return node_found.
- Otherwise, return node_new and don't touch RETVAL.
-*/
-int
-_gdbm_cache_tree_lookup (cache_tree *tree, off_t adr, cache_elem **retval)
+void
+_gdbm_node_set_elem (cache_node *node, cache_elem *elem)
{
- cache_node *n;
- int rc = cache_tree_lookup (tree, adr, TRUE, &n);
- if (rc != node_failure)
- *retval = n->elem;
- return rc;
+ node->elem = elem;
}
-
diff --git a/src/gdbmdefs.h b/src/gdbmdefs.h
index 3297cd1..79b5e71 100644
--- a/src/gdbmdefs.h
+++ b/src/gdbmdefs.h
@@ -157,9 +157,18 @@ typedef struct
int elem_loc;
} data_cache_elem;
-typedef struct cache_elem_s cache_elem;
+typedef struct cache_elem cache_elem;
+typedef struct cache_node cache_node;
-struct cache_elem_s
+struct cache_node
+{
+ cache_node *left, *right, *parent;
+ int color;
+ off_t adr;
+ cache_elem *elem;
+};
+
+struct cache_elem
{
hash_bucket * ca_bucket;
off_t ca_adr;
diff --git a/src/gdbmopen.c b/src/gdbmopen.c
index 621d6c7..9a64d78 100644
--- a/src/gdbmopen.c
+++ b/src/gdbmopen.c
@@ -271,7 +271,7 @@ gdbm_fd_open (int fd, const char *file_name, int block_size,
dbf->header = NULL;
/* Initialize cache */
- dbf->cache_tree = _gdbm_cache_tree_alloc (dbf);
+ dbf->cache_tree = _gdbm_cache_tree_alloc ();
_gdbm_cache_init (dbf, DEFAULT_CACHESIZE);
dbf->memory_mapping = FALSE;
diff --git a/src/proto.h b/src/proto.h
index 816da86..155481d 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -29,8 +29,6 @@ int _gdbm_cache_init (GDBM_FILE, size_t);
void _gdbm_cache_free (GDBM_FILE dbf);
int _gdbm_cache_flush (GDBM_FILE dbf);
-cache_elem *_gdbm_cache_elem_new (GDBM_FILE dbf, off_t adr);
-
/* From falloc.c */
off_t _gdbm_alloc (GDBM_FILE, int);
int _gdbm_free (GDBM_FILE, off_t, int);
@@ -88,7 +86,7 @@ int _gdbm_dump (GDBM_FILE dbf, FILE *fp);
int _gdbm_next_bucket_dir (GDBM_FILE dbf, int bucket_dir);
/* cachetree.c */
-cache_tree *_gdbm_cache_tree_alloc (GDBM_FILE dbf);
+cache_tree *_gdbm_cache_tree_alloc (void);
void _gdbm_cache_tree_destroy (cache_tree *tree);
void _gdbm_cache_tree_delete (cache_tree *tree, struct cache_node *n);
@@ -100,7 +98,7 @@ enum
node_failure /* An error occurred. */
};
-int _gdbm_cache_tree_lookup (cache_tree *tree, off_t adr, cache_elem **retval);
+int _gdbm_cache_tree_lookup (cache_tree *tree, off_t adr, cache_node **retval);
/* I/O functions */
static inline ssize_t

Return to:

Send suggestions and report system problems to the System administrator.