dedup

data deduplication program
git clone git://git.2f30.org/dedup.git
Log | Files | Refs | README | LICENSE

commit 8f41ac4be4b5c594892b1be8847706db16405c25
parent d3ec97d4abc70c1e5c87f5ff5f7b4800fdf89bcb
Author: sin <sin@2f30.org>
Date:   Mon, 25 Feb 2019 14:00:40 +0000

Wrap cache global state into a cache context structure

Diffstat:
Mcache.c | 40++++++++++++++++++++++++++++------------
Mdedup.c | 14++++++++------
Mdedup.h | 10++++++----
3 files changed, 42 insertions(+), 22 deletions(-)

diff --git a/cache.c b/cache.c @@ -14,8 +14,11 @@ struct cache_node { struct cache_entry ent; RB_ENTRY(cache_node) e; }; +RB_HEAD(cache_head, cache_node); -static RB_HEAD(cache, cache_node) cache_head; +struct cache { + struct cache_head entries; +}; static int cache_node_cmp(struct cache_node *e1, struct cache_node *e2) @@ -29,8 +32,8 @@ cache_node_cmp(struct cache_node *e1, struct cache_node *e2) return -1; return 0; } -static RB_PROTOTYPE(cache, cache_node, e, cache_node_cmp); -static RB_GENERATE(cache, cache_node, e, cache_node_cmp); +static RB_PROTOTYPE(cache_head, cache_node, e, cache_node_cmp); +static RB_GENERATE(cache_head, cache_node, e, cache_node_cmp); static struct cache_node * alloc_cache_node(struct cache_entry *ent) @@ -51,21 +54,21 @@ free_cache_node(struct cache_node *node) } void -add_cache_entry(struct cache_entry *ent) +add_cache_entry(struct cache *cache, struct cache_entry *ent) { struct cache_node *node; node = alloc_cache_node(ent); - RB_INSERT(cache, &cache_head, node); + RB_INSERT(cache_head, &cache->entries, node); } int -lookup_cache_entry(struct cache_entry *ent) +lookup_cache_entry(struct cache *cache, struct cache_entry *ent) { struct cache_node *node, key; key.ent = *ent; - node = RB_FIND(cache, &cache_head, &key); + node = RB_FIND(cache_head, &cache->entries, &key); if (node != NULL) { *ent = node->ent; return 0; @@ -74,21 +77,34 @@ lookup_cache_entry(struct cache_entry *ent) } void -walk_cache(int (*fn)(struct cache_entry *)) +walk_cache(struct cache *cache, int (*fn)(struct cache_entry *)) { struct cache_node *node; - RB_FOREACH(node, cache, &cache_head) + RB_FOREACH(node, cache_head, &cache->entries) (*fn)(&node->ent); } +struct cache * +alloc_cache(void) +{ + struct cache *cache; + + cache = calloc(1, sizeof(*cache)); + if (cache == NULL) + err(1, "malloc"); + RB_INIT(&cache->entries); + return cache; +} + void -free_cache(void) +free_cache(struct cache *cache) { struct cache_node *node, *tmp; - RB_FOREACH_SAFE(node, cache, &cache_head, tmp) { - RB_REMOVE(cache, &cache_head, node); + RB_FOREACH_SAFE(node, cache_head, &cache->entries, tmp) { + RB_REMOVE(cache_head, &cache->entries, node); free_cache_node(node); } + free(cache); } diff --git a/dedup.c b/dedup.c @@ -32,6 +32,7 @@ struct extract_args { }; static struct snapshot_hdr snaphdr; +static struct cache *cache; static int ifd; static int sfd; static int cfd; @@ -205,7 +206,7 @@ dedup_chunk(struct snapshot *snap, uint8_t *chunkp, size_t chunk_size) snaphdr.st.comp_size += n; memcpy(cache_entry.md, md, sizeof(cache_entry.md)); - if (lookup_cache_entry(&cache_entry) < 0) { + if (lookup_cache_entry(cache, &cache_entry) < 0) { struct blk_desc blk_desc; memcpy(&blk_desc.md, md, sizeof(blk_desc.md)); @@ -218,7 +219,7 @@ dedup_chunk(struct snapshot *snap, uint8_t *chunkp, size_t chunk_size) cache_entry.offset = blk_desc.offset; cache_entry.size = blk_desc.size; cache_dirty = 1; - add_cache_entry(&cache_entry); + add_cache_entry(cache, &cache_entry); cache_misses++; snaphdr.st.dedup_size += blk_desc.size; @@ -387,7 +388,7 @@ rebuild_cache(struct snapshot *snap, void *arg) cache_entry.offset = blk_desc->offset; cache_entry.size = blk_desc->size; cache_dirty = 1; - add_cache_entry(&cache_entry); + add_cache_entry(cache, &cache_entry); } free(buf); return WALK_CONTINUE; @@ -450,7 +451,7 @@ load_cache(void) if (xread(cfd, &cache_entry, sizeof(cache_entry)) == 0) errx(1, "read: unexpected EOF"); - add_cache_entry(&cache_entry); + add_cache_entry(cache, &cache_entry); } } @@ -494,6 +495,7 @@ init(void) xwrite(ifd, &snaphdr, sizeof(snaphdr)); } + cache = alloc_cache(); if (cache_nr_entries() != 0) load_cache(); else @@ -508,9 +510,9 @@ term(void) if (cache_dirty) { xlseek(cfd, 0, SEEK_SET); - walk_cache(flush_cache); + walk_cache(cache, flush_cache); } - free_cache(); + free_cache(cache); fsync(ifd); fsync(sfd); diff --git a/dedup.h b/dedup.h @@ -1,13 +1,15 @@ #include "config.h" #include "types.h" +struct cache; struct chunker; /* cache.c */ -void add_cache_entry(struct cache_entry *ent); -int lookup_cache_entry(struct cache_entry *ent); -void walk_cache(int (*fn)(struct cache_entry *)); -void free_cache(void); +void add_cache_entry(struct cache *cache, struct cache_entry *ent); +int lookup_cache_entry(struct cache *cache, struct cache_entry *ent); +void walk_cache(struct cache *cache, int (*fn)(struct cache_entry *)); +struct cache *alloc_cache(void); +void free_cache(struct cache *cache); /* chunker.c */ struct chunker *alloc_chunker(size_t cap, int fd);