def insert(self, app: Application): """Insert an Application in the store.""" if app.pid == 0: raise ValueError("Applications must have a valid PID.") if not app.desktopid: raise ValueError("Applications must have a Desktop identifier.") tstart = app.getTimeOfStart() tend = app.getTimeOfEnd() if tstart > tend: raise ValueError("Applications must have valid times of start and " "end.") # Get the list of instances for this PID, and find this app's place. pids = self.pidStore.get(app.pid, list()) # type: list neighbourCheckupIndex = -1 for (index, bpp) in enumerate(pids): bstart = bpp.getTimeOfStart() bend = bpp.getTimeOfEnd() # other item before ours, keep moving if (bend < tstart): continue # other item after ours, we found our position if (bstart > tend): pids.insert(index, app) neighbourCheckupIndex = index break # time period conflict, merge apps if same id or alert of a problem if (bend >= tstart) or (bstart <= tend): if app.hasSameDesktopId(bpp, resolveInterpreter=True): bpp.merge(app) pids[index] = bpp neighbourCheckupIndex = index else: # Apps A (which we insert) and B (which we compare to) are # overlapping. We now determine their respective orders to # dispatch them to the appropriate app splitting algorithm. print("Warning: Applications %s and %s overlap on PID %d" % (app.desktopid, bpp.desktopid, app.pid), file=sys.stderr) pids = self.dispatchSplit(pids, index, app, bpp) # Now, merge the inserted app with neighbours if applicable # but note that we don't really know where it is, how many # times it was split, and how much the list has grown. Even # if we pulled that info from the split functions, doing # merges on both edges of the newly inserted sequence would # be more complicated (thus error-prone) than browsing the # whole (short) list of pids. So let's keep it fool-proof. pids = self._mergePidList(pids) # raise ValueError("Applications %s and %s have the same " # "PID (%d) and their runtimes overlap:\n" # "\t%s \t %s\n\t%s \t %s\nbut they have " # "different identities. This is a bug " # "in the collected data." % ( # app.desktopid, # bpp.desktopid, # app.pid, # time2Str(app.getTimeOfStart()), # time2Str(app.getTimeOfEnd()), # time2Str(bpp.getTimeOfStart()), # time2Str(bpp.getTimeOfEnd()))) break # app is the last item on the list! else: pids.append(app) # Now, we check if the neighbours to the newly inserted Application # have the same Desktop ID. If they do, and if they are within a given # proximity window, we merge the items. This is needed to help Events # from Zeitgeist and PreloadLogger to synchronise. if neighbourCheckupIndex >= 0: pids = self._mergePidItem(pids, neighbourCheckupIndex) self.pidStore[app.getPid()] = pids self.nameStoreClean = False