#!/usr/local/cpython-3.10/bin/python3 """Count the true bits in an on-disk bit set (bloom filter).""" import os import sys verbose = False def usage(retval): """Output a usage message an exit.""" if retval == 0: w = sys.stdout.write else: w = sys.stderr.write w(f'Usage: {sys.argv[0]} --verbose --help\n') w('\n') w('Just write a count of true bits in a file.\n') w('If --verbose is given, list the bit numbers that are true.\n') sys.exit(retval) while sys.argv[1:]: if sys.argv[1] == '--verbose': verbose = True elif sys.argv[1] in ('-h', '--help'): usage(0) else: print(f'{sys.argv[0]}: unrecognized option: {sys.argv[1]}', file=sys.stderr) usage(1) del sys.argv[1] total_bits = 0 bits_set = 0 while True: block = os.read(0, 2**19) if not block: break total_bits += len(block) * 8 for byteno, byte in enumerate(block): for exponent in range(8): bitmask = 2**exponent if byte & bitmask != 0: if verbose: print(f'byteno {byteno}, bitmask {bitmask}') bits_set += 1 print('%s set, %s present, %6.2f%%' % (bits_set, total_bits, bits_set * 100.0 / total_bits))