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
|
/* SPDX-License-Identifier: LGPL-3.0-or-later */
/*
* dcache.c
*
* Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at>
*/
#define SQFS_BUILDING_DLL
#include "internal.h"
static int dcache_key_compare(const void *ctx, const void *l, const void *r)
{
sqfs_u32 lhs = *((const sqfs_u32 *)l), rhs = *((const sqfs_u32 *)r);
(void)ctx;
return lhs < rhs ? -1 : (lhs > rhs ? 1 : 0);
}
int sqfs_dir_reader_dcache_init(sqfs_dir_reader_t *rd, sqfs_u32 flags)
{
if (!(flags & SQFS_DIR_READER_DOT_ENTRIES))
return 0;
return rbtree_init(&rd->dcache, sizeof(sqfs_u32), sizeof(sqfs_u64),
dcache_key_compare);
}
int sqfs_dir_reader_dcache_init_copy(sqfs_dir_reader_t *copy,
const sqfs_dir_reader_t *rd)
{
if (!(rd->flags & SQFS_DIR_READER_DOT_ENTRIES))
return 0;
return rbtree_copy(&rd->dcache, ©->dcache);
}
void sqfs_dir_reader_dcache_cleanup(sqfs_dir_reader_t *rd)
{
if (!(rd->flags & SQFS_DIR_READER_DOT_ENTRIES))
return;
rbtree_cleanup(&rd->dcache);
}
int sqfs_dir_reader_dcache_add(sqfs_dir_reader_t *rd,
sqfs_u32 inode, sqfs_u64 ref)
{
rbtree_node_t *node;
if (!(rd->flags & SQFS_DIR_READER_DOT_ENTRIES))
return 0;
node = rbtree_lookup(&rd->dcache, &inode);
if (node != NULL)
return 0;
return rbtree_insert(&rd->dcache, &inode, &ref);
}
int sqfs_dir_reader_dcache_find(sqfs_dir_reader_t *rd,
sqfs_u32 inode, sqfs_u64 *ref)
{
rbtree_node_t *node;
if (!(rd->flags & SQFS_DIR_READER_DOT_ENTRIES))
return SQFS_ERROR_NO_ENTRY;
node = rbtree_lookup(&rd->dcache, &inode);
if (node == NULL)
return SQFS_ERROR_NO_ENTRY;
*ref = *((sqfs_u64 *)rbtree_node_value(node));
return 0;
}
|