diff --git a/src/server/cache-node.c b/src/server/cache-node.c new file mode 100644 index 0000000000000000000000000000000000000000..0568976f63f2577e0acbf9da3186615b8be8d5a5 --- /dev/null +++ b/src/server/cache-node.c @@ -0,0 +1,117 @@ +/* + * cache-node.c + * + * Used in diskomd. + */ + +EXPORT const Cache_node EMPTY_CACHE_NODE = + ((Cache_node){{ 0, 0, 0}, NULL, NULL, 0, 0, 0, 0, NULL, NULL, 0}); + +EXPORT const Cache_node_block EMPTY_CACHE_NODE_BLOCK = + ((Cache_node_block){ 0, NULL, NULL}); + +EXPORT const Cache_node_mcb EMPTY_CACHE_NODE_MCB = + ((Cache_node_mcb){ 0, NULL, 0, 0, NULL, NULL, 0, NULL }); + + +EXPORT void +unlink_lru(Cache_node *node, + Cache_node **lru, + Cache_node **mru) +{ + Cache_node *link; + + link = node->lru; + + if ( node->lru != NULL ) + node->lru->mru = node->mru; + else if (*lru == node) + *lru = node->mru; + + if ( node->mru != NULL ) + node->mru->lru = link; + else if (*mru == node) + *mru = link; +} + +EXPORT void +insert_mru(Cache_node *node, + Cache_node **lru, + Cache_node **mru) +{ + node->mru = NULL; + node->lru = *mru; + *mru = node; + if ( *lru == NULL ) + *lru = node; + + if ( node->lru != NULL ) + node->lru->mru = node; +} + + +EXPORT Cache_node_mcb * +create_cache_node_mcb(int mcb_size, + int table_size) +{ + Cache_node_mcb *tmp; + + tmp = alloc_cache_node_mcb(); + *tmp = EMPTY_CACHE_NODE_MCB; + tmp->lookup_table = smalloc(sizeof(Cache_node *) * table_size); + tmp->lookup_table_size = table_size; + tmp->mcb_size = mcb_size; + tmp->last_block = alloc_cache_node_block(); + + return tmp; +} + +/* +++ No check is done that it is initialized. */ +EXPORT Cache_node * +get_cache_node (Cache_node_mcb *control, + u_long key) +{ + if ( key >= control->lookup_table_size ) + return NULL; + + return control->lookup_table[ key ]; +} + +static Cache_node * +alloc_cache_node(void) +{ + Cache_node *c; + + c = smalloc(sizeof(Cache_node)); + *c = EMPTY_CACHE_NODE; + return c; +} + +EXPORT void +create_cache_node (Cache_node_mcb *control, + u_long key) +{ + if ( key >= control->lookup_table_size ) + restart_kom("ERROR: set_cache_node(%lu, %lu, value): " + "lookup_table_size = %lu\n", + control->lookup_table_size); + + control->lookup_table[ key ] = alloc_cache_node(); +} + + +EXPORT void +set_mru(Cache_node_mcb *mcb, + u_long key) +{ + Cache_node *node; + + node = get_cache_node(mcb, key); + + if (node == NULL) + restart_kom("set_mru(%d): nonexistent.\n", key); + + unlink_lru(node, &mcb->lru, &mcb->mru); + insert_mru(node, &mcb->lru, &mcb->mru); +} + diff --git a/src/server/cache-node.h b/src/server/cache-node.h new file mode 100644 index 0000000000000000000000000000000000000000..19280c075dc509cf849d9c3dccdfa58e764bbac2 --- /dev/null +++ b/src/server/cache-node.h @@ -0,0 +1,81 @@ +/* + * cache-node.h + */ + +typedef struct cache_node { + struct { + u_int exists : 1; + u_int exists_b : 1; + u_int dirty : 1; /* [r *ptr modifierad? */ + } s; + void *snap_shot; /* Dirty data to be written to file B. */ + /* (Dirty relative to file A). */ + void *ptr; /* In-core data. */ + long pos; /* Position to element in file A. */ + long size; /* Size on disk. */ + long pos_b; /* Position to element in file B. */ + long size_b; /* Size in file B. */ + struct cache_node *lru; + struct cache_node *mru; + int lock_cnt; +} Cache_node; + +extern const Cache_node EMPTY_CACHE_NODE; + + +typedef struct cache_node_block { + int next_free; + Cache_node *nodes; /* Pointer to an array with + mcb_size elements. */ + struct cache_node_block *link; /* Points to previous block. */ +} Cache_node_block; + +extern const Cache_node_block EMPTY_CACHE_NODE_BLOCK; + + +typedef struct cache_node_mcb { + int mcb_size; /* Number of cache_nodes in each block. */ + Cache_node_block *last_block; /* The block where new cache_nodes + * can be allocated. */ + u_long hits; + u_long misses; + Cache_node *mru; + Cache_node *lru; + u_long lookup_table_size; + Cache_node *lookup_table; /* Easy to implement, but memory expensive. */ +} Cache_node_mcb; + + +extern const Cache_node_mcb EMPTY_CACHE_NODE_MCB; + +extern void +unlink_lru(Cache_node *node, + Cache_node **lru, + Cache_node **mru); + +extern void +insert_mru(Cache_node *node, + Cache_node **lru, + Cache_node **mru); + + +extern Cache_node_mcb * +create_cache_node_mcb(int mcb_size, + int table_size); + + +extern Cache_node * +get_cache_node (Cache_node_mcb *control, + u_long key); + + +extern void +create_cache_node (Cache_node_mcb *control, + u_long key); + + +extern void +set_mru(Cache_node_mcb *mcb, + u_long key); + +