ticache.c - dedup - data deduplication program
HTML git clone git://bitreich.org/dedup/ git://hg6vgqziawt5s4dj.onion/dedup/
DIR Log
DIR Files
DIR Refs
DIR Tags
DIR README
DIR LICENSE
---
ticache.c (1928B)
---
1 #include <sys/types.h>
2
3 #include <err.h>
4 #include <stdint.h>
5 #include <stdlib.h>
6 #include <string.h>
7
8 #include "blake2.h"
9 #include "dedup.h"
10 #include "tree.h"
11
12 struct node {
13 struct blk_desc desc;
14 RB_ENTRY(node) e;
15 };
16 RB_HEAD(icache_head, node);
17
18 struct icache {
19 struct icache_head nodes;
20 unsigned long long hits;
21 unsigned long long misses;
22 };
23
24 static int
25 node_cmp(struct node *e1, struct node *e2)
26 {
27 int r;
28
29 r = memcmp(e1->desc.md, e2->desc.md, sizeof(e1->desc.md));
30 if (r > 0)
31 return 1;
32 else if (r < 0)
33 return -1;
34 return 0;
35 }
36 static RB_PROTOTYPE(icache_head, node, e, node_cmp);
37 static RB_GENERATE(icache_head, node, e, node_cmp);
38
39 static struct node *
40 alloc_node(struct blk_desc *desc)
41 {
42 struct node *node;
43
44 node = calloc(1, sizeof(*node));
45 if (node == NULL)
46 err(1, "calloc");
47 node->desc = *desc;
48 return node;
49 }
50
51 static void
52 free_node(struct node *node)
53 {
54 free(node);
55 }
56
57 struct icache *
58 alloc_icache(void)
59 {
60 struct icache *icache;
61
62 icache = calloc(1, sizeof(*icache));
63 if (icache == NULL)
64 err(1, "calloc");
65 RB_INIT(&icache->nodes);
66 return icache;
67 }
68
69 void
70 free_icache(struct icache *icache)
71 {
72 struct node *node, *tmp;
73
74 RB_FOREACH_SAFE(node, icache_head, &icache->nodes, tmp) {
75 RB_REMOVE(icache_head, &icache->nodes, node);
76 free_node(node);
77 }
78 free(icache);
79 }
80
81 void
82 insert_icache(struct icache *icache, struct blk_desc *desc)
83 {
84 struct node *node;
85
86 node = alloc_node(desc);
87 if (RB_INSERT(icache_head, &icache->nodes, node) != NULL)
88 free_node(node);
89 }
90
91 int
92 lookup_icache(struct icache *icache, struct blk_desc *desc)
93 {
94 struct node *node, key;
95
96 key.desc = *desc;
97 node = RB_FIND(icache_head, &icache->nodes, &key);
98 if (node != NULL) {
99 icache->hits++;
100 *desc = node->desc;
101 return 0;
102 }
103 icache->misses++;
104 return -1;
105 }
106
107 void
108 icache_stats(struct icache *icache, unsigned long long *hits,
109 unsigned long long *misses)
110 {
111 *hits = icache->hits;
112 *misses = icache->misses;
113 }
114