def annotate_snapshot(self, snapshot): """ Store additional statistical data in snapshot. """ if hasattr(snapshot, 'classes'): return snapshot.classes = {} for classname in list(self.index.keys()): total = 0 active = 0 merged = Asized(0, 0) for tobj in self.index[classname]: _merge_objects(snapshot.timestamp, merged, tobj) total += tobj.get_size_at_time(snapshot.timestamp) if (tobj.birth < snapshot.timestamp and (tobj.death is None or tobj.death > snapshot.timestamp)): active += 1 try: pct = total * 100.0 / snapshot.total except ZeroDivisionError: # pragma: no cover pct = 0 try: avg = total / active except ZeroDivisionError: avg = 0 snapshot.classes[classname] = dict(sum=total, avg=avg, pct=pct, active=active) snapshot.classes[classname]['merged'] = merged
def _merge_asized(base: Asized, other: Asized, level: int = 0) -> None: """ Merge **Asized** instances `base` and `other` into `base`. """ base.size += other.size base.flat += other.flat if level > 0: base.name = _ref2key(base) # Add refs from other to base. Any new refs are appended. base.refs = list(base.refs) # we may need to append items refs = {} for ref in base.refs: refs[_ref2key(ref)] = ref for ref in other.refs: key = _ref2key(ref) if key in refs: _merge_asized(refs[key], ref, level=level + 1) else: # Don't modify existing Asized instances => deepcopy base.refs.append(deepcopy(ref)) base.refs[-1].name = key