def get_hashes(partition_dir, recalculate=[], do_listdir=False, reclaim_age=ONE_WEEK): """ Get a list of hashes for the suffix dir. do_listdir causes it to mistrust the hash cache for suffix existence at the (unexpectedly high) cost of a listdir. reclaim_age is just passed on to hash_suffix. :param partition_dir: absolute path of partition to get hashes for :param recalculate: list of suffixes which should be recalculated when got :param do_listdir: force existence check for all hashes in the partition :param reclaim_age: age at which to remove tombstones :returns: tuple of (number of suffix dirs hashed, dictionary of hashes) """ hashed = 0 hashes_file = join(partition_dir, HASH_FILE) with lock_path(partition_dir): modified = False hashes = {} try: with open(hashes_file, 'rb') as fp: hashes = pickle.load(fp) except Exception: do_listdir = True if do_listdir: hashes = dict( ((suff, hashes.get(suff, None)) for suff in os.listdir(partition_dir) if len(suff) == 3 and isdir(join(partition_dir, suff)))) modified = True for hash_ in recalculate: hashes[hash_] = None for suffix, hash_ in hashes.items(): if not hash_: suffix_dir = join(partition_dir, suffix) if os.path.exists(suffix_dir): try: hashes[suffix] = hash_suffix(suffix_dir, reclaim_age) hashed += 1 except OSError: logging.exception(_('Error hashing suffix')) hashes[suffix] = None else: del hashes[suffix] modified = True sleep() if modified: write_pickle(hashes, hashes_file, partition_dir, PICKLE_PROTOCOL) return hashed, hashes
def get_hashes(partition_dir, recalculate=[], do_listdir=False, reclaim_age=ONE_WEEK): """ Get a list of hashes for the suffix dir. do_listdir causes it to mistrust the hash cache for suffix existence at the (unexpectedly high) cost of a listdir. reclaim_age is just passed on to hash_suffix. :param partition_dir: absolute path of partition to get hashes for :param recalculate: list of suffixes which should be recalculated when got :param do_listdir: force existence check for all hashes in the partition :param reclaim_age: age at which to remove tombstones :returns: tuple of (number of suffix dirs hashed, dictionary of hashes) """ hashed = 0 hashes_file = join(partition_dir, HASH_FILE) with lock_path(partition_dir): modified = False hashes = {} try: with open(hashes_file, 'rb') as fp: hashes = pickle.load(fp) except Exception: do_listdir = True if do_listdir: hashes = dict(((suff, hashes.get(suff, None)) for suff in os.listdir(partition_dir) if len(suff) == 3 and isdir(join(partition_dir, suff)))) modified = True for hash_ in recalculate: hashes[hash_] = None for suffix, hash_ in hashes.items(): if not hash_: suffix_dir = join(partition_dir, suffix) if os.path.exists(suffix_dir): try: hashes[suffix] = hash_suffix(suffix_dir, reclaim_age) hashed += 1 except OSError: logging.exception(_('Error hashing suffix')) hashes[suffix] = None else: del hashes[suffix] modified = True sleep() if modified: write_pickle(hashes, hashes_file, partition_dir, PICKLE_PROTOCOL) return hashed, hashes
def invalidate_hash(suffix_dir): """ Invalidates the hash for a suffix_dir in the partition's hashes file. :param suffix_dir: absolute path to suffix dir whose hash needs invalidating """ suffix = os.path.basename(suffix_dir) partition_dir = os.path.dirname(suffix_dir) hashes_file = join(partition_dir, HASH_FILE) with lock_path(partition_dir): try: with open(hashes_file, 'rb') as fp: hashes = pickle.load(fp) if suffix in hashes and not hashes[suffix]: return except Exception: return hashes[suffix] = None write_pickle(hashes, hashes_file, partition_dir, PICKLE_PROTOCOL)