diff --git a/dedupestore/cache.py b/dedupestore/cache.py index 89bfc7282..ed957a67f 100644 --- a/dedupestore/cache.py +++ b/dedupestore/cache.py @@ -1,3 +1,4 @@ +from itertools import ifilter import logging import msgpack import os @@ -14,7 +15,6 @@ def __init__(self, store, crypto): self.path = os.path.join(os.path.expanduser('~'), '.dedupestore', 'cache', '%s.cache' % self.store.uuid) self.tid = -1 - self.file_chunks = {} self.open() if self.tid != self.store.tid: self.init(crypto) @@ -24,21 +24,17 @@ def open(self): return cache = msgpack.unpackb(open(self.path, 'rb').read()) assert cache['version'] == 1 - if cache['store'] != self.store.uuid: - raise Exception('Cache UUID mismatch') - self.chunkmap = cache['chunkmap'] + self.chunk_counts = cache['chunk_counts'] # Discard old file_chunks entries - for hash, entry in cache['file_chunks'].iteritems(): - count = entry[0] - if count < 8: - self.file_chunks[hash] = [count + 1] + list(entry[1:]) + self.file_chunks = cache['file_chunks'] self.tid = cache['tid'] def init(self, crypto): """Initializes cache by fetching and reading all archive indicies """ logging.info('Initializing cache...') - self.chunkmap = {} + self.chunk_counts = {} + self.file_chunks = {} self.tid = self.store.tid if self.store.tid == 0: return @@ -47,19 +43,19 @@ def init(self, crypto): cindex = msgpack.unpackb(data) for id, size in cindex['chunks']: try: - count, size = self.chunkmap[id] - self.chunkmap[id] = count + 1, size + count, size = self.chunk_counts[id] + self.chunk_counts[id] = count + 1, size except KeyError: - self.chunkmap[id] = 1, size + self.chunk_counts[id] = 1, size self.save() def save(self): assert self.store.state == self.store.OPEN cache = {'version': 1, - 'store': self.store.uuid, - 'chunkmap': self.chunkmap, 'tid': self.store.tid, - 'file_chunks': self.file_chunks, + 'chunk_counts': self.chunk_counts, + 'file_chunks': dict(ifilter(lambda i: i[1][0] < 8, + self.file_chunks.iteritems())), } data = msgpack.packb(cache) cachedir = os.path.dirname(self.path) @@ -74,31 +70,31 @@ def add_chunk(self, id, data, crypto): data, hash = crypto.encrypt_read(data) csize = len(data) self.store.put(NS_CHUNK, id, data) - self.chunkmap[id] = (1, csize) + self.chunk_counts[id] = (1, csize) return csize def seen_chunk(self, id): - count, size = self.chunkmap.get(id, (0, 0)) - return count + return self.chunk_counts.get(id, (0, 0))[0] def chunk_incref(self, id): - count, size = self.chunkmap[id] - self.chunkmap[id] = (count + 1, size) + count, size = self.chunk_counts[id] + self.chunk_counts[id] = (count + 1, size) return size def chunk_decref(self, id): - count, size = self.chunkmap[id] + count, size = self.chunk_counts[id] if count == 1: - del self.chunkmap[id] + del self.chunk_counts[id] self.store.delete(NS_CHUNK, id) else: - self.chunkmap[id] = (count - 1, size) + self.chunk_counts[id] = (count - 1, size) def file_known_and_unchanged(self, path_hash, st): entry = self.file_chunks.get(path_hash) - if (entry and entry[1] == st.st_ino - and entry[2] == st.st_size and entry[3] == st.st_mtime): - entry[0] = 0 # reset entry age + if (entry and entry[3] == st.st_mtime + and entry[2] == st.st_size and entry[1] == st.st_ino): + # reset entry age + self.file_chunks[path_hash] = (0,) + entry[1:] return entry[4], entry[2] else: return None, 0