#!/usr/bin/env python3 """Hunting run: does killing things make more records go active? Uses the labelling and the MEASURED stride from wave3_probe.py -- each record is bounded by the next record's address, not by a constant. Reports, per tick, how many records changed and which unit types they are, so a rise in activity can be tied to the hunt rather than to the clock. """ import os, sys, time, struct, collections, importlib.util SD = __file__.rsplit('/', 1)[0] spec = importlib.util.spec_from_file_location('gmem', SD + '/gmem.py') gmem = importlib.util.module_from_spec(spec); spec.loader.exec_module(gmem) w3 = importlib.util.spec_from_file_location('w3', SD + '/wave3_probe.py') wave3 = importlib.util.module_from_spec(w3); w3.loader.exec_module(wave3) MAXREC = 0x400 def main(): secs = int(sys.argv[1]) if len(sys.argv) > 1 else 200 every = int(sys.argv[2]) if len(sys.argv) > 2 else 10 path = gmem.mem_path() fd = os.open(path, os.O_RDONLY); size = os.fstat(fd).st_size f = os.fdopen(os.dup(fd), 'rb') offs = wave3.find_records(f, fd, size) if not offs: print('NO ENTITY RECORDS'); return 2 lens = [min(MAXREC, offs[i+1] - offs[i]) for i in range(len(offs)-1)] + [0x100] ids = [wave3.resolve_id(f, size, o)[0] or '?' for o in offs] print('records: %d, labelled %d' % (len(offs), sum(1 for i in ids if i != '?'))) print('composition:', collections.Counter(ids).most_common(6)) prev = [wave3.rd(f, o, l) for o, l in zip(offs, lens)] log = open('/tmp/wave4-activity.tsv', 'w'); log.write('t\tactive\tunits\n') t0 = time.time(); series = [] while time.time() - t0 < secs: time.sleep(every) el = round(time.time() - t0) act = [] for k, (o, l) in enumerate(zip(offs, lens)): cur = wave3.rd(f, o, l) if cur != prev[k]: act.append(k) prev[k] = cur types = collections.Counter(ids[k] for k in act) series.append((el, len(act))) line = '%d\t%d\t%s\n' % (el, len(act), dict(types)) log.write(line); log.flush() print(' t=%4ds active=%3d %s' % (el, len(act), [(u.replace('UN_',''), c) for u, c in types.most_common(5)]), flush=True) log.close() print('\nactive-record series:', series) a = [n for _, n in series] if a: print('active: min=%d max=%d first=%d last=%d' % (min(a), max(a), a[0], a[-1])) return 0 if __name__ == '__main__': sys.exit(main())