Mercurial > code > home > repos > light9
changeset 903:bca2e8d754aa
tripleFilter optimization on currentState. optimize how often curvecalc rebuilds Subterm objs
Ignore-this: 7402387bd9f4f99c2e7ef27b8dcfc4db
author | Drew Perttula <drewp@bigasterisk.com> |
---|---|
date | Mon, 10 Jun 2013 06:00:48 +0000 |
parents | f376e7605e25 |
children | 86c6700d1d63 |
files | bin/curvecalc light9/curvecalc/output.py light9/curvecalc/subterm.py light9/rdfdb/currentstategraphapi.py |
diffstat | 4 files changed, 60 insertions(+), 41 deletions(-) [+] |
line wrap: on
line diff
--- a/bin/curvecalc Mon Jun 10 04:22:07 2013 +0000 +++ b/bin/curvecalc Mon Jun 10 06:00:48 2013 +0000 @@ -46,6 +46,7 @@ self.graph, self.opts, self.session = graph, opts, session self.curveset, self.music = curveset, music self.lastSeenInputTime = 0 + self.currentSubterms = [] # Subterm objects that are synced to the graph wtree = self.wtree = gtk.Builder() wtree.add_from_file("light9/curvecalc/curvecalc.glade") @@ -211,17 +212,23 @@ return uri def set_subterms_from_graph(self): + """rebuild all the gtktable 'subterms' widgets and the + self.currentSubterms list""" + song = self.graph.value(self.session, L9['currentSong']) + + newList = [] + for st in set(self.graph.objects(song, L9['subterm'])): + log.info("song %s has subterm %s", song, st) + term = Subterm(self.graph, st, self.songSubtermsContext(), + self.curveset) + newList.append(term) + self.currentSubterms[:] = newList + master = self.wtree.get_object("subterms") log.info("removing subterm widgets") [master.remove(c) for c in master.get_children()] - - song = self.graph.value(self.session, L9['currentSong']) - - for st in set(self.graph.objects(song, L9['subterm'])): - log.info("song %s has subterm %s", song, st) - term = Subterm(self.graph, st, self.songSubtermsContext(), self.curveset) + for term in self.currentSubterms: add_one_subterm(term, self.curveset, master) - master.show_all() log.info("%s table children showing" % len(master.get_children())) @@ -396,12 +403,12 @@ graph.addHandler(curvesetReload) log.debug("startup: output %s", time.time() - startTime) - out = Output(graph, session, music, curveset) mt = MaxTime(graph, session) dispatcher.connect(lambda: mt.get(), "get max time", weak=False) start = Main(graph, opts, session, curveset, music) + out = Output(graph, session, music, curveset, start.currentSubterms) dispatcher.send("show all")
--- a/light9/curvecalc/output.py Mon Jun 10 04:22:07 2013 +0000 +++ b/light9/curvecalc/output.py Mon Jun 10 06:00:48 2013 +0000 @@ -10,8 +10,9 @@ class Output(object): lastsendtime=0 lastsendlevs=None - def __init__(self, graph, session, music, curveset): + def __init__(self, graph, session, music, curveset, currentSubterms): self.graph, self.session, self.music = graph, session, music + self.currentSubterms = currentSubterms self.curveset = curveset self.recent_t=[] @@ -52,14 +53,9 @@ dispatcher.send("curves to sliders", t=t) scaledsubs=[] - with self.graph.currentState() as current: - song = current.value(self.session, L9['currentSong']) - for st in current.objects(song, L9['subterm']): - # this is getting especially broken to have Output - # being able to remake the Subterm on each frame. Some - # object should maintain all the subterms for us. - scl = Subterm(self.graph, st, None, self.curveset).scaled(current, t) - scaledsubs.append(scl) + for st in self.currentSubterms: + scl = st.scaled(t) + scaledsubs.append(scl) out = Submaster.sub_maxes(*scaledsubs) levs = out.get_levels()
--- a/light9/curvecalc/subterm.py Mon Jun 10 04:22:07 2013 +0000 +++ b/light9/curvecalc/subterm.py Mon Jun 10 06:00:48 2013 +0000 @@ -83,37 +83,39 @@ self.submasters = Submaster.get_global_submasters(self.graph) def ensureExpression(self, saveCtx): - with self.graph.currentState() as current: + with self.graph.currentState(tripleFilter=(self.uri, None, None)) as current: if current.value(self.uri, L9['expression']) is None: self.graph.patch(Patch(addQuads=[ (self.uri, L9['expression'], Literal("..."), saveCtx), ])) - def scaled(self, current, t): - subexpr_eval = self.eval(current, t) - # we prevent any exceptions from escaping, since they cause us to - # stop sending levels - try: - if isinstance(subexpr_eval, Submaster.Submaster): - # if the expression returns a submaster, just return it - return subexpr_eval - else: - # otherwise, return our submaster multiplied by the value - # returned - if subexpr_eval == 0: - return Submaster.Submaster("zero", {}) - subUri = current.value(self.uri, L9['sub']) - sub = self.submasters.get_sub_by_uri(subUri) - return sub * subexpr_eval - except Exception, e: - dispatcher.send("expr_error", sender=self.uri, exc=repr(e)) - return Submaster.Submaster(name='Error: %s' % str(e), levels={}) - + def scaled(self, t): + with self.graph.currentState(tripleFilter=(self.uri, None, None)) as current: + subexpr_eval = self.eval(current, t) + # we prevent any exceptions from escaping, since they cause us to + # stop sending levels + try: + if isinstance(subexpr_eval, Submaster.Submaster): + # if the expression returns a submaster, just return it + return subexpr_eval + else: + # otherwise, return our submaster multiplied by the value + # returned + if subexpr_eval == 0: + return Submaster.Submaster("zero", {}) + subUri = current.value(self.uri, L9['sub']) + sub = self.submasters.get_sub_by_uri(subUri) + return sub * subexpr_eval + except Exception, e: + dispatcher.send("expr_error", sender=self.uri, exc=repr(e)) + return Submaster.Submaster(name='Error: %s' % str(e), levels={}) + + def eval(self, current, t): """current graph is being passed as an optimization. It should be equivalent to use self.graph in here.""" - objs = list(current.objects(self.uri, L9.expression)) + objs = list(current.objects(self.uri, L9['expression'])) if len(objs) > 1: raise ValueError("found multiple expressions for %s: %s" % (self.uri, objs))
--- a/light9/rdfdb/currentstategraphapi.py Mon Jun 10 04:22:07 2013 +0000 +++ b/light9/rdfdb/currentstategraphapi.py Mon Jun 10 06:00:48 2013 +0000 @@ -1,14 +1,18 @@ +import logging, traceback from rdflib import ConjunctiveGraph from light9.rdfdb.rdflibpatch import contextsForStatement as rp_contextsForStatement +log = logging.getLogger("currentstate") class CurrentStateGraphApi(object): """ mixin for SyncedGraph, separated here because these methods work together """ - def currentState(self, context=None): + def currentState(self, context=None, tripleFilter=(None, None, None)): """ a graph you can read without being in an addHandler + + you can save some time by passing a triple filter, and we'll only give you the matching triples """ if context is not None: raise NotImplementedError("currentState with context arg") @@ -22,11 +26,21 @@ # before moving on to writes. g = ConjunctiveGraph() - for s,p,o,c in self._graph.quads((None,None,None)): + for s,p,o,c in self._graph.quads(tripleFilter): g.store.add((s,p,o), c) + + if tripleFilter == (None, None, None): + self2.logThisCopy(g) + g.contextsForStatement = lambda t: contextsForStatementNoWildcards(g, t) return g + def logThisCopy(self, g): + log.info("copied graph %s statements because of this:" % len(g)) + for frame in traceback.format_stack(limit=4)[:-2]: + for line in frame.splitlines(): + log.info(" "+line) + def __exit__(self, type, val, tb): return