File: cache.h

package info (click to toggle)
xfsprogs 3.2.1
  • links: PTS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 7,276 kB
  • ctags: 9,584
  • sloc: ansic: 96,643; sh: 10,603; makefile: 806
file content (138 lines) | stat: -rw-r--r-- 4,593 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/*
 * Copyright (c) 2006 Silicon Graphics, Inc.
 * All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it would be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write the Free Software Foundation,
 * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
#ifndef __CACHE_H__
#define __CACHE_H__

/*
 * initialisation flags
 */
/*
 * xfs_db always writes changes immediately, and so we need to purge buffers
 * when we get a buffer lookup mismatch due to reading the same block with a
 * different buffer configuration.
 */
#define CACHE_MISCOMPARE_PURGE	(1 << 0)

/*
 * cache object campare return values
 */
enum {
	CACHE_HIT,
	CACHE_MISS,
	CACHE_PURGE,
};

#define	HASH_CACHE_RATIO	8

/*
 * Cache priorities range from BASE to MAX.
 *
 * For prefetch support, the top half of the range starts at
 * CACHE_PREFETCH_PRIORITY and everytime the buffer is fetched
 * and is at or above this priority level, it is reduced to
 * below this level (refer to libxfs_getbuf).
 */

#define CACHE_BASE_PRIORITY	0
#define CACHE_PREFETCH_PRIORITY	8
#define CACHE_MAX_PRIORITY	15

/*
 * Simple, generic implementation of a cache (arbitrary data).
 * Provides a hash table with a capped number of cache entries.
 */

struct cache;
struct cache_node;

typedef void *cache_key_t;

typedef void (*cache_walk_t)(struct cache_node *);
typedef struct cache_node * (*cache_node_alloc_t)(cache_key_t);
typedef void (*cache_node_flush_t)(struct cache_node *);
typedef void (*cache_node_relse_t)(struct cache_node *);
typedef unsigned int (*cache_node_hash_t)(cache_key_t, unsigned int,
					  unsigned int);
typedef int (*cache_node_compare_t)(struct cache_node *, cache_key_t);
typedef unsigned int (*cache_bulk_relse_t)(struct cache *, struct list_head *);

struct cache_operations {
	cache_node_hash_t	hash;
	cache_node_alloc_t	alloc;
	cache_node_flush_t	flush;
	cache_node_relse_t	relse;
	cache_node_compare_t	compare;
	cache_bulk_relse_t	bulkrelse;	/* optional */
};

struct cache_hash {
	struct list_head	ch_list;	/* hash chain head */
	unsigned int		ch_count;	/* hash chain length */
	pthread_mutex_t		ch_mutex;	/* hash chain mutex */
};

struct cache_mru {
	struct list_head	cm_list;	/* MRU head */
	unsigned int		cm_count;	/* MRU length */
	pthread_mutex_t		cm_mutex;	/* MRU lock */
};

struct cache_node {
	struct list_head	cn_hash;	/* hash chain */
	struct list_head	cn_mru;		/* MRU chain */
	unsigned int		cn_count;	/* reference count */
	unsigned int		cn_hashidx;	/* hash chain index */
	int			cn_priority;	/* priority, -1 = free list */
	pthread_mutex_t		cn_mutex;	/* node mutex */
};

struct cache {
	int			c_flags;	/* behavioural flags */
	unsigned int		c_maxcount;	/* max cache nodes */
	unsigned int		c_count;	/* count of nodes */
	pthread_mutex_t		c_mutex;	/* node count mutex */
	cache_node_hash_t	hash;		/* node hash function */
	cache_node_alloc_t	alloc;		/* allocation function */
	cache_node_flush_t	flush;		/* flush dirty data function */
	cache_node_relse_t	relse;		/* memory free function */
	cache_node_compare_t	compare;	/* comparison routine */
	cache_bulk_relse_t	bulkrelse;	/* bulk release routine */
	unsigned int		c_hashsize;	/* hash bucket count */
	unsigned int		c_hashshift;	/* hash key shift */
	struct cache_hash	*c_hash;	/* hash table buckets */
	struct cache_mru	c_mrus[CACHE_MAX_PRIORITY + 1];
	unsigned long long	c_misses;	/* cache misses */
	unsigned long long	c_hits;		/* cache hits */
	unsigned int 		c_max;		/* max nodes ever used */
};

struct cache *cache_init(int, unsigned int, struct cache_operations *);
void cache_destroy(struct cache *);
void cache_walk(struct cache *, cache_walk_t);
void cache_purge(struct cache *);
void cache_flush(struct cache *);

int cache_node_get(struct cache *, cache_key_t, struct cache_node **);
void cache_node_put(struct cache *, struct cache_node *);
void cache_node_set_priority(struct cache *, struct cache_node *, int);
int cache_node_get_priority(struct cache_node *);
int cache_node_purge(struct cache *, cache_key_t, struct cache_node *);
void cache_report(FILE *fp, const char *, struct cache *);
int cache_overflowed(struct cache *);

#endif	/* __CACHE_H__ */