From: Patrick Rouleau Date: Thu, 22 May 2014 03:36:27 +0000 (-0400) Subject: midx: close the mmap before erasing an midx file X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=0430ecff35e1d9dfee3dc74574f41be20299bca9;p=packages%2Fb%2Fbup.git midx: close the mmap before erasing an midx file Linux allows erasing a file even if it is still memory mapped, but Windows does not. However, Cygwin tries to emulate Linux and, under certain conditions, it silently moves the file to $RECYCLED.BIN/, but not in a way where Windows takes care of it when we use the "empty the recycled bin" command. The erased midx ends up comsuming more and more disk space. To solve this, we have to close the midx's mmap before erasing the midx. Cygwin users: you can use this command to clean up your $RECYCLE.BIN/ directories: find /cygdrive/?/\$RECYCLE.BIN/ -name "\.???[[:xdigit:]]*" -print -delete Signed-off-by: Patrick Rouleau [rlb@defaultvalue.org: adjust commit message] --- diff --git a/lib/bup/git.py b/lib/bup/git.py index 59bc169..826a2d1 100644 --- a/lib/bup/git.py +++ b/lib/bup/git.py @@ -468,6 +468,7 @@ class PackIdxList: ' used by %s\n') % (n, mxf)) broken = True if broken: + mx.close() del mx unlink(full) else: @@ -489,6 +490,7 @@ class PackIdxList: elif not ix.force_keep: debug1('midx: removing redundant: %s\n' % os.path.basename(ix.name)) + ix.close() unlink(ix.name) for full in glob.glob(os.path.join(self.dir,'*.idx')): if not d.get(full): diff --git a/lib/bup/midx.py b/lib/bup/midx.py index 3a06b73..57a4787 100644 --- a/lib/bup/midx.py +++ b/lib/bup/midx.py @@ -18,6 +18,7 @@ class PackMidx: def __init__(self, filename): self.name = filename self.force_keep = False + self.map = None assert(filename.endswith('.midx')) self.map = mmap_read(open(filename)) if str(self.map[0:4]) != 'MIDX': @@ -46,6 +47,9 @@ class PackMidx: self.whichlist = buffer(self.map, self.which_ofs, nsha*4) self.idxnames = str(self.map[self.which_ofs + 4*nsha:]).split('\0') + def __del__(self): + self.close() + def _init_failed(self): self.bits = 0 self.entries = 1 @@ -67,6 +71,11 @@ class PackMidx: def _get_idxname(self, i): return self.idxnames[self._get_idx_i(i)] + def close(self): + if self.map is not None: + self.map.close() + self.map = None + def exists(self, hash, want_source=False): """Return nonempty if the object exists in the index files.""" global _total_searches, _total_steps