def pns_map_names (self, unicoded, encoded): # index a sequence of names to the index names = tuple (( (n, encode (n, 'UTF-8')) for n in netunicode.decode (unicoded) )) for n, name in names: stored = self.pns_index.get (index) if stored == None: # insert an entry in the index self.pns_index[name] = encoded + chr (1) self.pns_map_names (n, name) elif ( ord (stored[-1]) < self.pns_horizon and stored.find (encoded) < 0 ): # update an entry with a new index field = set () stored = public_names.valid (unicode ( encoded + stored[:-1], 'UTF-8' ), field, self.pns_horizon) if len (field) < self.pns_horizon: # but only below the horizon self.pns_index[name] = (encode ( stored, 'UTF-8' ) + chr (len (field))) return names
def pns_command (self, model): # handle a command from a PNS/TCP session assert None == self.log ( netstring.encode (model), 'command' ) if model[1]: if model[2]: # walk subject down to contexts, let the user # agent walk the graph up and down at once to # test and weight a subject against a set of # contexts (and not implement that common walk # into the client, but rather articulate it). # contexts = set (netunicode.decode ( unicode (model[2], 'UTF-8') )) self.thread_loop_queue (( self.pns_walk_simplest, (model, contexts) )) return # walk down the contexts once, in all contexts self.thread_loop_queue (( self.pns_command_predicate, (model,) )) return # walk up the names once, for in contexts self.thread_loop_queue (( self.pns_command_object, (model,) ))
def pns_walk_down(self, name, contexts): stored = self.pns_routes.get(encode(name, 'UTF-8')) if stored and (ord(stored[-1]) < self.pns_horizon): return contexts & set( netunicode.decode(unicode(stored[:-1], 'UTF-8'))) return NULL_SET
def valid (encoded, field, horizon): "validate encoded Public Names in a field and below a given horizon" # try to decode the articulated public names, strip voids names = tuple (netunicode.decode (encoded, False)) if not names: # inarticulated names if encoded in field: # allready in the field return u"" # new in this field field.add (encoded) return encoded # articulated Public Names valids = [] for name in names: # recursively validate each articulated name name = valid (name, field, horizon) if name: valids.append (name) if len (field) >= horizon: break # but only under this horizon if len (valids) > 1: # sort Public Names and encode valids.sort () return netunicode.encode (valids) if len (valids) > 0: # return a "singleton" return valids[0] return u"" # nothing valid to articulate
def valid(encoded, field, horizon): "validate encoded Public Names in a field and below a given horizon" # try to decode the articulated public names, strip voids names = tuple(netunicode.decode(encoded, False)) if not names: # inarticulated names if encoded in field: # allready in the field return u"" # new in this field field.add(encoded) return encoded # articulated Public Names valids = [] for name in names: # recursively validate each articulated name name = valid(name, field, horizon) if name: valids.append(name) if len(field) >= horizon: break # but only under this horizon if len(valids) > 1: # sort Public Names and encode valids.sort() return netunicode.encode(valids) if len(valids) > 0: # return a "singleton" return valids[0] return u"" # nothing valid to articulate
def pns_walk_down (self, name, contexts): stored = self.pns_routes.get (encode (name, 'UTF-8')) if stored and (ord (stored[-1]) < self.pns_horizon): return contexts & set (netunicode.decode ( unicode (stored[:-1], 'UTF-8') )) return NULL_SET
def pns_walk_up(self, names, walked): index = {} for name in names: stored = self.pns_index.get(encode(name, 'UTF-8')) if stored and (ord(stored[-1]) < self.pns_horizon): for n in ( set(netunicode.decode(unicode(stored[:-1], 'UTF-8'))) - walked): index.setdefault(n, set()).add(name) return index
def pns_walk_up (self, names, walked): index = {} for name in names: stored = self.pns_index.get (encode (name, 'UTF-8')) if stored and (ord (stored[-1]) < self.pns_horizon): for n in (set (netunicode.decode (unicode ( stored[:-1], 'UTF-8' ))) - walked): index.setdefault ( n, set() ).add (name) return index
def pns_walk_simplest(self, model, contexts): subject = unicode(model[0] or model[1], 'UTF-8') walked = set((subject, )) if subject in contexts: routes = {subject: set((subject, ))} else: routes = {} paths = self.pns_walk_down(subject, contexts) if paths: routes.setdefault(subject, set()).update(paths) if len(routes) > 0: self.pns_walk_out(model, routes) return names = list(netunicode.decode(subject)) or [subject] self.thread_loop_queue( (self.pns_walk_simple, (model, contexts, walked, routes, names)))
def pns_walk_simplest (self, model, contexts): subject = unicode (model[0] or model[1], 'UTF-8') walked = set ((subject, )) if subject in contexts: routes = {subject: set ((subject, ))} else: routes = {} paths = self.pns_walk_down (subject, contexts) if paths: routes.setdefault (subject, set ()).update (paths) if len (routes) > 0: self.pns_walk_out (model, routes) return names = list ( netunicode.decode (subject) ) or [subject] self.thread_loop_queue (( self.pns_walk_simple, (model, contexts, walked, routes, names) ))
def pns_command(self, model): # handle a command from a PNS/TCP session assert None == self.log(netstring.encode(model), 'command') if model[1]: if model[2]: # walk subject down to contexts, let the user # agent walk the graph up and down at once to # test and weight a subject against a set of # contexts (and not implement that common walk # into the client, but rather articulate it). # contexts = set(netunicode.decode(unicode(model[2], 'UTF-8'))) self.thread_loop_queue( (self.pns_walk_simplest, (model, contexts))) return # walk down the contexts once, in all contexts self.thread_loop_queue((self.pns_command_predicate, (model, ))) return # walk up the names once, for in contexts self.thread_loop_queue((self.pns_command_object, (model, )))
def pns_map_names(self, unicoded, encoded): # index a sequence of names to the index names = tuple( ((n, encode(n, 'UTF-8')) for n in netunicode.decode(unicoded))) for n, name in names: stored = self.pns_index.get(index) if stored == None: # insert an entry in the index self.pns_index[name] = encoded + chr(1) self.pns_map_names(n, name) elif (ord(stored[-1]) < self.pns_horizon and stored.find(encoded) < 0): # update an entry with a new index field = set() stored = public_names.valid( unicode(encoded + stored[:-1], 'UTF-8'), field, self.pns_horizon) if len(field) < self.pns_horizon: # but only below the horizon self.pns_index[name] = (encode(stored, 'UTF-8') + chr(len(field))) return names