浏览代码

Persist cache info.

Jonas Borgström 15 年之前
父节点
当前提交
1d76aab21e
共有 2 个文件被更改,包括 33 次插入6 次删除
  1. 29 3
      dedupstore/archiver.py
  2. 4 3
      dedupstore/repository.py

+ 29 - 3
dedupstore/archiver.py

@@ -13,13 +13,30 @@ class Cache(object):
     """
     """
     def __init__(self, path, repo):
     def __init__(self, path, repo):
         self.repo = repo
         self.repo = repo
+        self.path = path
         self.chunkmap = {}
         self.chunkmap = {}
         self.archives = []
         self.archives = []
-        self.open(path)
+        self.tid = -1
+        self.open()
+        if self.tid != self.repo.tid:
+            print self.tid, self.repo.tid
+            self.create()
 
 
-    def open(self, path):
+    def open(self):
         if self.repo.tid == 0:
         if self.repo.tid == 0:
             return
             return
+        filename = os.path.join(self.path, '%s.cache' % self.repo.uuid)
+        if not os.path.exists(filename):
+            return
+        print 'Reading cache: ', filename, '...'
+        data = cPickle.loads(zlib.decompress(open(filename, 'rb').read()))
+        self.chunkmap = data['chunkmap']
+        self.tid = data['tid']
+        self.archives = data['archives']
+        print 'done'
+
+    def create(self):
+        print 'Recreating cache...'
         for archive in self.repo.listdir('archives'):
         for archive in self.repo.listdir('archives'):
             self.archives.append(archive)
             self.archives.append(archive)
             data = self.repo.get_file(os.path.join('archives', archive))
             data = self.repo.get_file(os.path.join('archives', archive))
@@ -27,11 +44,19 @@ class Cache(object):
             for item in a['items']:
             for item in a['items']:
                 if item['type'] == 'FILE':
                 if item['type'] == 'FILE':
                     for c in item['chunks']:
                     for c in item['chunks']:
-                        print 'adding chunk', c.encode('hex')
                         self.chunk_incref(c)
                         self.chunk_incref(c)
+        self.tid = self.repo.tid
+        print 'done'
 
 
     def save(self):
     def save(self):
         assert self.repo.state == Repository.OPEN
         assert self.repo.state == Repository.OPEN
+        print 'saving',self.tid, self.repo.tid
+        data = {'chunkmap': self.chunkmap, 'tid': self.repo.tid, 'archives': self.archives}
+        filename = os.path.join(self.path, '%s.cache' % self.repo.uuid)
+        print 'Saving cache as:', filename
+        with open(filename, 'wb') as fd:
+            fd.write(zlib.compress(cPickle.dumps(data)))
+        print 'done'
 
 
     def chunk_filename(self, sha):
     def chunk_filename(self, sha):
         hex = sha.encode('hex')
         hex = sha.encode('hex')
@@ -78,6 +103,7 @@ class Archiver(object):
         archive = {'name': name, 'items': items}
         archive = {'name': name, 'items': items}
         zdata = zlib.compress(cPickle.dumps(archive))
         zdata = zlib.compress(cPickle.dumps(archive))
         self.repo.put_file(os.path.join('archives', archive_name), zdata)
         self.repo.put_file(os.path.join('archives', archive_name), zdata)
+        self.cache.archives.append(archive_name)
         print 'Archive file size: %d' % len(zdata)
         print 'Archive file size: %d' % len(zdata)
         self.repo.commit()
         self.repo.commit()
         self.cache.save()
         self.cache.save()

+ 4 - 3
dedupstore/repository.py

@@ -10,7 +10,6 @@ import uuid
 
 
 log = logging.getLogger('')
 log = logging.getLogger('')
 
 
-# FIXME: UUID
 
 
 class Repository(object):
 class Repository(object):
     """
     """
@@ -103,6 +102,7 @@ class Repository(object):
         os.rename(os.path.join(self.path, 'txn-commit'),
         os.rename(os.path.join(self.path, 'txn-commit'),
                   os.path.join(self.path, 'txn-applied'))
                   os.path.join(self.path, 'txn-applied'))
         shutil.rmtree(os.path.join(self.path, 'txn-applied'))
         shutil.rmtree(os.path.join(self.path, 'txn-applied'))
+        self.tid = tid
         self.state = Repository.OPEN
         self.state = Repository.OPEN
 
 
     def rollback(self):
     def rollback(self):
@@ -137,12 +137,13 @@ class Repository(object):
         """
         """
         """
         """
         self.prepare_txn()
         self.prepare_txn()
-        if os.path.exists(os.path.join(self.path, 'txn-active', 'add', path)):
+        if (path in self.txn_added or
+           (path not in self.txn_removed and os.path.exists(os.path.join(self.path, 'data', path)))):
             raise Exception('FileAlreadyExists: %s' % path)
             raise Exception('FileAlreadyExists: %s' % path)
         if path in self.txn_removed:
         if path in self.txn_removed:
             self.txn_removed.remove(path)
             self.txn_removed.remove(path)
         if path not in self.txn_added:
         if path not in self.txn_added:
-                self.txn_added.append(path)
+            self.txn_added.append(path)
         filename = os.path.join(self.path, 'txn-active', 'add', path)
         filename = os.path.join(self.path, 'txn-active', 'add', path)
         if not os.path.exists(os.path.dirname(filename)):
         if not os.path.exists(os.path.dirname(filename)):
             os.makedirs(os.path.dirname(filename))  
             os.makedirs(os.path.dirname(filename))