def _get_parent_branch_series(self, query, limit=LOADER_LIMIT, offset=0): """Iterate through parent branches, find cached series for parent branch and return series matching query""" root_branch_query = False _pattern = ".".join(query.pattern.split('.')[:-1]) if not _pattern: _pattern = '*' root_branch_query = True parent_branch_series = self.get_all_cached_series( _pattern, limit=limit, offset=offset) while not parent_branch_series and not root_branch_query: logger.debug("No cached series list for parent branch query %s, " "continuing with more parents", _pattern) _pattern = ".".join(_pattern.split('.')[:-1]) if not _pattern: _pattern = '*' root_branch_query = True parent_branch_series = self.get_all_cached_series( _pattern, limit=limit, offset=offset) if not parent_branch_series: return logger.debug("Found cached parent branch series for parent query %s " "limit %s offset %s", _pattern, limit, offset) series = match_entries(parent_branch_series, query.pattern) \ if is_pattern(query.pattern) \ else [b for b in parent_branch_series if b.startswith(query.pattern)] return series
def search(self, node, split_query, split_path): """Return matching children for each query part in split query starting from given node""" sub_query = split_query[0] keys = [_decode_str(key) for (key, _) in node.children] \ if node.children is not None else [] matched_paths = match_entries(keys, sub_query) matched_children = ( (_decode_str(path), _node) for (path, _node) in node.children if _decode_str(path) in matched_paths) \ if node.children is not None and is_pattern(sub_query) \ else [(sub_query, [n for (k, n) in node.children if _decode_str(k) == sub_query][0])] \ if node.children is not None \ and sub_query in keys else [] for child_name, child_node in matched_children: child_path = split_path[:] child_path.append(child_name) child_query = split_query[1:] if len(child_query) > 0: for sub in self.search(child_node, child_query, child_path): yield sub else: yield (child_path, child_node)
def _get_matched_children(self, sub_query, node): keys = [_decode_str(key) for (key, _) in node.children] \ if node.children is not None else [] matched_paths = match_entries(keys, sub_query) if node.children is not None and is_pattern(sub_query): matched_children = self._get_children_from_matched_paths( matched_paths, node) else: matched_children = [(sub_query, self._get_child_from_string_query( sub_query, node))] \ if node.children is not None \ and sub_query in keys else [] return matched_children
def _search_nodes(self, pattern): parts = pattern.split('.') queue = [('_parent:_root', parts)] while queue: search_term, patterns = queue.pop() pattern = patterns[0] patterns = patterns[1:] # map branches to their resource (the branch full path) and the # retrieved metrics (the leaves) branches = {} for resource, metrics in self._run_search(search_term): if search_term == '_parent:_root': branch = resource else: # XXX column is valid in graphite names branch = resource.rsplit(':', 1)[1] branches[branch] = (resource, metrics) # multi-part pattern if patterns: # walk the branches first for match in match_entries(branches.keys(), pattern): resource, metrics = branches[match] parent_term = resource.replace(':', '\:') parent_term = parent_term.replace('-', '\-') queue.append(('_parent:%s' % parent_term, patterns)) # only one pattern left, match leaves too (i.e. metrics) if len(patterns) == 1: for match in match_entries(metrics, patterns[0]): yield resource, match, True else: # patterns like 'foo', yield only branches for match in match_entries(branches.keys(), pattern): yield match, None, False
def _match(self, metric, pattern): return match_entries([metric], pattern)