File: key_large.c

package info (click to toggle)
reiser4progs 1.2.2-1
  • links: PTS
  • area: main
  • in suites: bookworm
  • size: 5,904 kB
  • sloc: ansic: 34,331; sh: 4,251; makefile: 994
file content (394 lines) | stat: -rw-r--r-- 9,829 bytes parent folder | download | duplicates (8)
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
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
/* Copyright (C) 2001-2005 by Hans Reiser, licensing governed by
   reiser4progs/COPYING.
   
   key_large.c -- reiser4 large key plugin. */

#ifdef ENABLE_LARGE_KEYS
#include "key_large.h"

extern reiser4_key_plug_t key_large_plug;

/* Returns minimal key */
static reiser4_key_t *key_large_minimal(void) {
	return key_common_minimal(&key_large_plug);
}

/* Returns maximal key */
static reiser4_key_t *key_large_maximal(void) {
	return key_common_maximal(&key_large_plug);
}

static uint32_t key_large_bodysize(void) {
	return KEY_LARGE_LAST_INDEX;
}

#ifndef ENABLE_MINIMAL
/* Sets up key type */
static void key_large_set_type(reiser4_key_t *key, 
			       key_type_t type) 
{
	aal_assert("umka-634", key != NULL);

	kl_set_minor((key_large_t *)key->body,
		      key_common_type2minor(type));
}

/* Returns key type */
key_type_t key_large_get_type(reiser4_key_t *key) {
	key_minor_t minor;
	
	aal_assert("umka-635", key != NULL);

	minor = kl_get_minor((key_large_t *)key->body);
	return key_common_minor2type(minor);
}

/* Sets up full key objectid */
void key_large_set_fobjectid(reiser4_key_t *key, uint64_t objectid) {
	aal_assert("umka-2345", key != NULL);
	kl_set_fobjectid((key_large_t *)key->body, objectid);
}

/* Returns full key objectid */
uint64_t key_large_get_fobjectid(reiser4_key_t *key) {
	aal_assert("umka-2346", key != NULL);
	return kl_get_fobjectid((key_large_t *)key->body);
}

/* Sets up key locality */
void key_large_set_locality(reiser4_key_t *key, uint64_t locality) {
	aal_assert("umka-636", key != NULL);
	kl_set_locality((key_large_t *)key->body, locality);
}
#endif

/* Returns key locality */
uint64_t key_large_get_locality(reiser4_key_t *key) {
	aal_assert("umka-637", key != NULL);
	return kl_get_locality((key_large_t *)key->body);
}

/* Sets up key ordering (is not used in short keys ) */
void key_large_set_ordering(reiser4_key_t *key, uint64_t ordering) {
	aal_assert("umka-2331", key != NULL);
	kl_set_ordering((key_large_t *)key->body, ordering);
}

/* Returns key ordering (is not used in short keys) */
uint64_t key_large_get_ordering(reiser4_key_t *key) {
	aal_assert("umka-2332", key != NULL);
	return kl_get_ordering((key_large_t *)key->body);
}

/* Sets up key objectid */
void key_large_set_objectid(reiser4_key_t *key, 
			    uint64_t objectid) 
{
	aal_assert("umka-638", key != NULL);
	kl_set_objectid((key_large_t *)key->body, objectid);
}

/* Returns key objectid */
uint64_t key_large_get_objectid(reiser4_key_t *key) {
	aal_assert("umka-639", key != NULL);
	return kl_get_objectid((key_large_t *)key->body);
}

/* Sets up key offset */
void key_large_set_offset(reiser4_key_t *key, 
			  uint64_t offset)
{
	aal_assert("umka-640", key != NULL);
	kl_set_offset((key_large_t *)key->body, offset);
}

/* Returns key offset */
uint64_t key_large_get_offset(reiser4_key_t *key) {
	aal_assert("umka-641", key != NULL);
	return kl_get_offset((key_large_t *)key->body);
}

static int key_large_hashed(reiser4_key_t *key) {
	return (key_large_get_ordering(key) & HASHED_NAME_MASK) ? 1 : 0;
}

/* Extracts name from key */
static char *key_large_get_name(reiser4_key_t *key,
				char *name)
{
	char *ptr;
	uint64_t offset;
	uint64_t objectid;
	uint64_t ordering;

	aal_assert("umka-2352", key != NULL);
	aal_assert("umka-2353", name != NULL);

	/* Check if the key is a hashed one */
	if (key_large_hashed(key))
		return NULL;

	offset = key_large_get_offset(key);
	ordering = key_large_get_ordering(key);
	objectid = kl_get_fobjectid((key_large_t *)key->body);

	/* Check if key is dot one */
	if (objectid == 0ull && offset == 0ull &&
	    ordering == 0ull)
	{
		*name = '.';
		*(name + 1) = '\0';
	} else {
		ordering &= ~FIBRE_MASK;
		ptr = aux_unpack_string(ordering, name);
		ptr = aux_unpack_string(objectid, ptr);
		aux_unpack_string(offset, ptr);
	}

	return name;
}

#ifndef ENABLE_MINIMAL
/* Sets up key offset */
static void key_large_set_hash(reiser4_key_t *key, 
			       uint64_t hash)
{
	aal_assert("vpf-129", key != NULL);
	kl_set_hash((key_large_t *)key->body, hash);
}

/* Returns key offset */
static uint64_t key_large_get_hash(reiser4_key_t *key) {
	aal_assert("vpf-130", key != NULL);
	return kl_get_hash((key_large_t *)key->body);
}
#endif

/* Figures out if items are of one file or not. */
static int key_large_compshort(reiser4_key_t *key1, 
			       reiser4_key_t *key2) 
{
	key_minor_t minor;
	int res;

	aal_assert("umka-2217", key1 != NULL);
	aal_assert("umka-2218", key2 != NULL);

	/* Cheking locality first */
	if ((res = kl_comp_el((key_large_t *)key1->body,
			      (key_large_t *)key2->body, 0)))
	{
		return res;
	}
	
	minor = kl_get_minor((key_large_t *)key1->body);
	
	/* There is nothing to check for entry keys anymore. */
	if (key_common_minor2type(minor) == KEY_FILENAME_TYPE)
		return 0;

	/* Checking ordering. */
	if ((res = kl_comp_el((key_large_t *)key1->body,
			      (key_large_t *)key2->body, 1)))
	{
		return res;
	}
	
	/* Checking objectid  */
	return kl_comp_el((key_large_t *)key1->body,
			  (key_large_t *)key2->body, 2);
}

static int key_large_compraw(void *key1, void *key2) {
	int res;

	if ((res = kl_comp_el((key_large_t *)key1,
			      (key_large_t *)key2, 0)))
	{
		return res;
	}
	
	if ((res = kl_comp_el((key_large_t *)key1,
			      (key_large_t *)key2, 1)))
	{
		return res;
	}
	
	if ((res = kl_comp_el((key_large_t *)key1,
			      (key_large_t *)key2, 2)))
	{
		return res;
	}
	
	return kl_comp_el((key_large_t *)key1,
			  (key_large_t *)key2, 3);
}

/* Compares two passed keys. Returns -1 if key1 lesser than key2, 0 if keys are
   equal and 1 if key1 is bigger then key2. */
static int key_large_compfull(reiser4_key_t *key1, 
			      reiser4_key_t *key2) 
{
	aal_assert("vpf-135", key1 != NULL);
	aal_assert("vpf-136", key2 != NULL);

	return key_large_compraw(key1->body, key2->body);
}

/* Builds hash of the passed @name by means of using a hash plugin */
static void key_large_build_hash(reiser4_key_t *key,
				 reiser4_hash_plug_t *hash,
				 reiser4_fibre_plug_t *fibre,
				 char *name) 
{
	uint16_t len;
	uint64_t offset;
	uint64_t objectid;
	uint64_t ordering;
    
	if ((len = aal_strlen(name)) == 1 && name[0] == '.')
		return;

	aal_assert("vpf-128", hash != NULL); 
	aal_assert("vpf-1568", fibre != NULL);

	ordering = aux_pack_string(name, 1);

	if (len > ORDERING_CHARS) 
		objectid = aux_pack_string(name + ORDERING_CHARS, 0);
	else
		objectid = 0ull;

	if (len <= ORDERING_CHARS + OBJECTID_CHARS + OFFSET_CHARS) {
		if (len > INLINE_CHARS)
			offset = aux_pack_string(name + INLINE_CHARS, 0);
		else
			offset = 0ull;
	} else {
		ordering |= HASHED_NAME_MASK;

		offset = plugcall(hash, build,
				  (unsigned char *)name + INLINE_CHARS,
				  len - INLINE_CHARS);
	}

	ordering |= 
		((uint64_t)plugcall(fibre, build, name, len) << FIBRE_SHIFT);
	
	/* Setting up objectid and offset */
	key_large_set_ordering(key, ordering);
	kl_set_objectid((key_large_t *)key->body, objectid);
	key_large_set_offset(key, offset);
}

/* Builds key by passed locality, objectid, and name. It is suitable for
   creating entry keys. */
static void key_large_build_hashed(reiser4_key_t *key,
				   reiser4_hash_plug_t *hash,
				   reiser4_fibre_plug_t *fibre,
				   uint64_t locality,
				   uint64_t objectid,
				   char *name) 
{
	key_type_t type;
	
	aal_assert("vpf-140", key != NULL);
	aal_assert("umka-667", name != NULL);

	type = key_common_minor2type(KEY_FILENAME_MINOR);
	
	aal_memset(key, 0, sizeof(*key));
	key->plug = &key_large_plug;
	kl_set_locality((key_large_t *)key->body, objectid);
	kl_set_minor((key_large_t *)key->body,
		      key_common_type2minor(type));
	
	key_large_build_hash(key, hash, fibre, name);
}

/* Builds generic key by all its components */
static errno_t key_large_build_generic(reiser4_key_t *key,
				       key_type_t type,
				       uint64_t locality,
				       uint64_t ordering,
				       uint64_t objectid,
				       uint64_t offset)
{
	aal_assert("vpf-141", key != NULL);

	aal_memset(key, 0, sizeof(*key));
	key->plug = &key_large_plug;
	
	kl_set_locality((key_large_t *)key->body, locality);	
	kl_set_ordering((key_large_t *)key->body, ordering);
	
	if (type == KEY_FILENAME_TYPE) {
		kl_set_fobjectid((key_large_t *)key->body, objectid);
	} else {
		kl_set_objectid((key_large_t *)key->body, objectid);
	}
	
	kl_set_minor((key_large_t *)key->body,
		     key_common_type2minor(type));
	
	kl_set_offset((key_large_t *)key->body, offset);

	return 0;
}

#ifndef ENABLE_MINIMAL
extern void key_large_print(reiser4_key_t *key,
			    aal_stream_t *stream,
			    uint16_t options);

extern errno_t key_large_check_struct(reiser4_key_t *key);
#endif

reiser4_key_plug_t key_large_plug = {
	.p = {
		.id    = {KEY_LARGE_ID, 0, KEY_PLUG_TYPE},
#ifndef ENABLE_MINIMAL
		.label = "key_large",
		.desc  = "Large key plugin.",
#endif
	},
	
	.hashed		= key_large_hashed,
	.minimal	= key_large_minimal,
	.maximal	= key_large_maximal,
	.bodysize	= key_large_bodysize,
	.compraw	= key_large_compraw,
	.compfull	= key_large_compfull,
	.compshort	= key_large_compshort,

	.build_hashed   = key_large_build_hashed,
	.build_generic  = key_large_build_generic,
	
#ifndef ENABLE_MINIMAL
	.check_struct	= key_large_check_struct,
	.print		= key_large_print,

	.set_hash	= key_large_set_hash,
	.get_hash	= key_large_get_hash,

	.set_type	= key_large_set_type,		
	.get_type	= key_large_get_type,

	.set_fobjectid	= key_large_set_fobjectid,
	.get_fobjectid	= key_large_get_fobjectid,
	
	.set_locality	= key_large_set_locality,
#endif
	.get_locality	= key_large_get_locality,

	.set_objectid	= key_large_set_objectid,
	.get_objectid	= key_large_get_objectid,
	
	.set_ordering	= key_large_set_ordering,
	.get_ordering	= key_large_get_ordering,
	
	.set_offset	= key_large_set_offset,
	.get_offset	= key_large_get_offset,
	.get_name	= key_large_get_name
};
#endif