diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2019-11-13 16:47:27 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2019-11-13 16:47:27 +0200 |
commit | 6534535f18c41304b6623c4afd42e20da941e061 (patch) | |
tree | 623d07f88a2f6900c24b97b81faca6f6825f9d80 | |
parent | 5144dd6833fa60ba443d4d36c6cee64d0a382240 (diff) | |
download | gdbm-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.c | 17 | ||||
-rw-r--r-- | src/cachetree.c | 62 | ||||
-rw-r--r-- | src/gdbmdefs.h | 13 | ||||
-rw-r--r-- | src/gdbmopen.c | 2 | ||||
-rw-r--r-- | src/proto.h | 6 |
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 |