+def run_cleaner(backend, inode_map, log):
+ # Determine which segments are poorly utilized and should be cleaned. We
+ # need better heuristics here.
+ for (s, u) in sorted(inode_map.util.segments.items()):
+ if float(u[1]) / u[0] < 0.99 and u[1] > 0:
+ print "Should clean segment", s
+ m = re.match(r"^log-(\d+)-(\d+)$", s)
+ if m: inode_map.obsolete_segments.add((int(m.group(1)), int(m.group(2))))
+
+ # Given that list of segments to clean, scan through those segments to find
+ # data which is still live and mark relevant inodes as needing to be
+ # rewritten.
+ dirty_inodes = set()
+ for s in inode_map.obsolete_segments:
+ filename = "log-%08d-%08d" % s
+ print "Scanning", filename, "for live data"
+ for item in parse_log(backend.read(filename), filename):
+ if item.type in (ITEM_TYPE.DATA, ITEM_TYPE.INODE):
+ if item.inum != 0:
+ dirty_inodes.add(item.inum)
+
+ print "Inodes to rewrite:", dirty_inodes
+ for i in sorted(dirty_inodes):
+ rewrite_inode(backend, inode_map, i, log)
+