def fetch(self, key, varenv): '''fetch a single namespace entry from the graph''' args = (self.namemap.bootstrap.has_key[1:], self.guid[1:], quote(key)) qs = '(typeguid=%s left=%s value=%s comparator="octet" datatype=string pagesize=2 result=((value left right)))' % args r = self.namemap.gc.read_varenv(qs, varenv) # we asked for pagesize=2 just to check this if len(r) > 1: LOG.warning('mql.duplicate.key', '%s in namespace %s' % (key, self.guid)) elif len(r) == 0: return False (value, nsg, g) = (unquote(r[0][0]), '#' + r[0][1], '#' + r[0][2]) if nsg != self.guid: raise MQLInternalError(None, "Mismatched namespace query", value=value, namespace=self.guid, returned_namespace=nsg, guid=g) # this assert can fail because of graphd case-insensitivity #assert unquote(value) == key, "%s != %s" % (unquote(value), key) self.store(key, g) return g
def list_or_item(self, result, varenv): # return a list if we want a list or the first item if we don't if self.query.list: return result elif len(result) == 1: return result[0] elif len(result) == 0: return None elif varenv.get('uniqueness_failure', None) == 'soft': # this supresses the exception in favor of a warning message LOG.warning( 'soft.uniqueness.failure', repr(self.query), result=repr(result)) return result[0] else: # this mutates the result, but we don't want it anyway... varenv.lookup_manager.do_id_lookups() result = varenv.lookup_manager.substitute_ids(result) raise MQLTooManyValuesForUniqueQuery( self.query, results=result, count=len(result))
def lookup_by_guid_oneoff(self, g, varenv): root_ns_guid = self.bootstrap.root_namespace res = [] name = [] found = set() next = g # this is ridiculously deep - 18 ply. for i in xrange(6): res = self.lookup_by_guid_oneoff_internal(next, varenv) if not res: # we've ceased to make progress - bail LOG.warning('mql.namespace.error', 'id for guid not found', guid=g) return g for pair in res: name.append(pair[0]) next = pair[1] if next == root_ns_guid: name.reverse() return "/" + "/".join(name) if next in found: LOG.warning('mql.namespace.error', 'cycle in namespace looking for guid', guid=g) return g found.add(next) LOG.warning('mql.namespace.error', 'depth limit exceeded in namespace lookup', guid=g) return g
def cmdline_main(): LOG.warning("benchmark", "test start") start_time = time.time() from mql.mql import cmdline op = cmdline.OP("testing") op.add_option( "-n", dest="num", default=1000, type="int", help="number of iterations") op.add_option( "-P", dest="profile", default=None, help="run profiler with output to file") op.add_option("-c", dest="call", default=None, help="function to call") op.add_option( "-f", dest="query_file", default=None, help="file containing query") op.add_option( "--flush", dest="flush", default=None, help="flush cache between every request") op.add_option("-t", dest="type", default="mql", help="graph or MQL query") options, args = op.parse_args() stop_time = time.time() op.ctx.gc.totalcost["dt"] = stop_time - start_time LOG.warning("start cost", { "nreqs": op.ctx.gc.nrequests, "cost": op.ctx.gc.totalcost }) options, args = op.parse_args() queryfile = options.query_file if queryfile is not None: qf = open(queryfile, "r") query = "".join(qf.readlines()) regex = re.compile("[\n\t]+") query = regex.sub(" ", query) qf.close() elif options.call: query = globals()[options.call]() elif len(args) == 1: query = args[0] else: op.error("Must specify a query argument") if options.type == "mql": # XXX should eventually use unicode, for now utf8 query = json.loads(query, encoding="utf-8", result_encoding="utf-8") elif options.type == "graph": pass else: op.error("-t must be 'mql' or 'graph'") if options.profile: if profiler == "hotshot": profile = hotshot.Profile(options.profile) profile.runcall(test_run, op.ctx, op.varenv, options, query) LOG.warning( "benchmark", "Saving hotshot profile in Stats format to %s" % options.profile) elif profiler == "cProfile": profile = cProfile.Profile() profile.runcall(test_run, op.ctx, op.varenv, options, query) LOG.warning( "benchmark", "Saving cProfile data in kcachegrind format to %s" % options.profile) # get from http://jcalderone.livejournal.com/21124.html # and put in thirdparty/pyroot from mql.mql import lsprofcalltree k = lsprofcalltree.KCacheGrind(profile) k.output(open(options.profile, "w")) else: LOG.warning("benchmark", "No profiler available, not running benchmark") else: reslist = test_run(op.ctx, op.varenv, options, query) LOG.warning("run cost", { "nreqs": op.ctx.gc.nrequests, "cost": op.ctx.gc.totalcost })