/*
 * $Id: cache-node.h,v 0.4 1991/08/28 02:22:00 ceder Exp $
 *
 * 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 *prev;	/* Points towards most recently used. */
    struct cache_node *next;	/* Points towards least recently used. */
    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 void
destruct_cache_node(Cache_node_mcb  *control,
		    u_long           key);

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
zero_init_cache_node (Cache_node_mcb *control,
		      u_long          key);

extern void
set_mru(Cache_node_mcb *mcb,
	u_long         key);


extern void
free_cache_node_mcb(Cache_node_mcb *control);