summaryrefslogtreecommitdiff
path: root/camel/camel-partition-table.h
blob: b3712c284edb840e2bfd436257e6695265d88086 (plain)
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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
/*
 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
 *
 * This library is free software: you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
 * for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library. If not, see <http://www.gnu.org/licenses/>.
 *
 * Authors: Michael Zucchi <notzed@ximian.com>
 */

#if !defined (__CAMEL_H_INSIDE__) && !defined (CAMEL_COMPILATION)
#error "Only <camel/camel.h> can be included directly."
#endif

#ifndef CAMEL_PARTITION_TABLE_H
#define CAMEL_PARTITION_TABLE_H

#include <camel/camel-block-file.h>

/* Standard GObject macros */
#define CAMEL_TYPE_PARTITION_TABLE \
	(camel_partition_table_get_type ())
#define CAMEL_PARTITION_TABLE(obj) \
	(G_TYPE_CHECK_INSTANCE_CAST \
	((obj), CAMEL_TYPE_PARTITION_TABLE, CamelPartitionTable))
#define CAMEL_PARTITION_TABLE_CLASS(cls) \
	(G_TYPE_CHECK_CLASS_CAST \
	((cls), CAMEL_TYPE_PARTITION_TABLE, CamelPartitionTableClass))
#define CAMEL_IS_PARTITION_TABLE(obj) \
	(G_TYPE_CHECK_INSTANCE_TYPE \
	((obj), CAMEL_TYPE_PARTITION_TABLE))
#define CAMEL_IS_PARTITION_TABLE_CLASS(cls) \
	(G_TYPE_CHECK_CLASS_TYPE \
	((cls), CAMEL_TYPE_PARTITION_TABLE))
#define CAMEL_PARTITION_TABLE_GET_CLASS(obj) \
	(G_TYPE_INSTANCE_GET_CLASS \
	((obj), CAMEL_TYPE_PARTITION_TABLE, CamelPartitionTableClass))

#define CAMEL_TYPE_KEY_TABLE \
	(camel_key_table_get_type ())
#define CAMEL_KEY_TABLE(obj) \
	(G_TYPE_CHECK_INSTANCE_CAST \
	((obj), CAMEL_TYPE_KEY_TABLE, CamelKeyTable))
#define CAMEL_KEY_TABLE_CLASS(cls) \
	(G_TYPE_CHECK_CLASS_CAST \
	((cls), CAMEL_TYPE_KEY_TABLE, CamelKeyTableClass))
#define CAMEL_IS_KEY_TABLE(obj) \
	(G_TYPE_CHECK_INSTANCE_TYPE \
	((obj), CAMEL_TYPE_KEY_TABLE))
#define CAMEL_IS_KEY_TABLE_CLASS(cls) \
	(G_TYPE_CHECK_CLASS_TYPE \
	((cls), CAMEL_TYPE_KEY_TABLE))
#define CAMEL_KEY_TABLE_GET_CLASS(obj) \
	(G_TYPE_INSTANCE_GET_CLASS \
	((obj), CAMEL_TYPE_KEY_TABLE, CamelKeyTableClass))

G_BEGIN_DECLS

/* ********************************************************************** */

/* CamelPartitionTable - index of key to keyid */

typedef guint32 camel_hash_t;	/* a hashed key */

typedef struct _CamelPartitionKey CamelPartitionKey;
typedef struct _CamelPartitionKeyBlock CamelPartitionKeyBlock;
typedef struct _CamelPartitionMap CamelPartitionMap;
typedef struct _CamelPartitionMapBlock CamelPartitionMapBlock;

typedef struct _CamelPartitionTable CamelPartitionTable;
typedef struct _CamelPartitionTableClass CamelPartitionTableClass;
typedef struct _CamelPartitionTablePrivate CamelPartitionTablePrivate;

struct _CamelPartitionKey {
	camel_hash_t hashid;
	camel_key_t keyid;
};

struct _CamelPartitionKeyBlock {
	guint32 used;
	struct _CamelPartitionKey keys[(CAMEL_BLOCK_SIZE - 4) / sizeof (struct _CamelPartitionKey)];
};

struct _CamelPartitionMap {
	camel_hash_t hashid;
	camel_block_t blockid;
};

struct _CamelPartitionMapBlock {
	camel_block_t next;
	guint32 used;
	struct _CamelPartitionMap partition[(CAMEL_BLOCK_SIZE - 8) / sizeof (struct _CamelPartitionMap)];
};

struct _CamelPartitionTable {
	GObject parent;
	CamelPartitionTablePrivate *priv;

	CamelBlockFile *blocks;
	camel_block_t rootid;

	gint (*is_key)(CamelPartitionTable *cpi, const gchar *key, camel_key_t keyid, gpointer data);
	gpointer is_key_data;

	/* we keep a list of partition blocks active at all times */
	GQueue partition;
};

struct _CamelPartitionTableClass {
	GObjectClass parent;
};

GType		camel_partition_table_get_type	(void);
CamelPartitionTable *
		camel_partition_table_new	(struct _CamelBlockFile *bs,
						 camel_block_t root);
gint		camel_partition_table_sync	(CamelPartitionTable *cpi);
gint		camel_partition_table_add	(CamelPartitionTable *cpi,
						 const gchar *key,
						 camel_key_t keyid);
camel_key_t	camel_partition_table_lookup	(CamelPartitionTable *cpi,
						 const gchar *key);
gboolean	camel_partition_table_remove	(CamelPartitionTable *cpi,
						 const gchar *key);

/* ********************************************************************** */

/* CamelKeyTable - index of keyid to key and flag and data mapping */

typedef struct _CamelKeyBlock CamelKeyBlock;
typedef struct _CamelKeyRootBlock CamelKeyRootBlock;

typedef struct _CamelKeyTable CamelKeyTable;
typedef struct _CamelKeyTableClass CamelKeyTableClass;
typedef struct _CamelKeyTablePrivate CamelKeyTablePrivate;

struct _CamelKeyRootBlock {
	camel_block_t first;
	camel_block_t last;
	camel_key_t free;	/* free list */
};

struct _CamelKeyKey {
	camel_block_t data;
	guint offset : 10;
	guint flags : 22;
};

struct _CamelKeyBlock {
	camel_block_t next;
	guint32 used;
	union {
		struct _CamelKeyKey keys[(CAMEL_BLOCK_SIZE - 8) / sizeof (struct _CamelKeyKey)];
		gchar keydata[CAMEL_BLOCK_SIZE - 8];
	} u;
};

#define CAMEL_KEY_TABLE_MAX_KEY (128) /* max size of any key */

struct _CamelKeyTable {
	GObject parent;
	CamelKeyTablePrivate *priv;

	CamelBlockFile *blocks;

	camel_block_t rootid;

	CamelKeyRootBlock *root;
	CamelBlock *root_block;
};

struct _CamelKeyTableClass {
	GObjectClass parent;
};

GType		camel_key_table_get_type	(void);
CamelKeyTable *	camel_key_table_new		(CamelBlockFile *bs,
						 camel_block_t root);
gint		camel_key_table_sync		(CamelKeyTable *ki);
camel_key_t	camel_key_table_add		(CamelKeyTable *ki,
						 const gchar *key,
						 camel_block_t data,
						 guint flags);
gboolean	camel_key_table_set_data	(CamelKeyTable *ki,
						 camel_key_t keyid,
						 camel_block_t data);
gboolean	camel_key_table_set_flags	(CamelKeyTable *ki,
						 camel_key_t keyid,
						 guint flags,
						 guint set);
camel_block_t	camel_key_table_lookup		(CamelKeyTable *ki,
						 camel_key_t keyid,
						 gchar **key,
						 guint *flags);
camel_key_t	camel_key_table_next		(CamelKeyTable *ki,
						 camel_key_t next,
						 gchar **keyp,
						 guint *flagsp,
						 camel_block_t *datap);

G_END_DECLS

#endif /* CAMEL_PARTITION_TABLE_H */