File: storage.py

package info (click to toggle)
graphite-api 1.1.3-2%2Bdeb9u1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 752 kB
  • sloc: python: 7,757; sh: 215; makefile: 150
file content (78 lines) | stat: -rw-r--r-- 2,446 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import time

from collections import defaultdict

from .utils import is_pattern
from .node import LeafNode
from .intervals import Interval
from .readers import MultiReader


class Store(object):
    def __init__(self, finders=None):
        self.finders = finders

    def find(self, pattern, startTime=None, endTime=None, local=True):
        query = FindQuery(pattern, startTime, endTime)

        matching_nodes = set()

        # Search locally
        for finder in self.finders:
            for node in finder.find_nodes(query):
                matching_nodes.add(node)

        # Group matching nodes by their path
        nodes_by_path = defaultdict(list)
        for node in matching_nodes:
            nodes_by_path[node.path].append(node)

        # Reduce matching nodes for each path to a minimal set
        found_branch_nodes = set()

        for path, nodes in sorted(nodes_by_path.items(), key=lambda k: k[0]):
            leaf_nodes = set()

            # First we dispense with the BranchNodes
            for node in nodes:
                if node.is_leaf:
                    leaf_nodes.add(node)
                elif node.path not in found_branch_nodes:
                    # TODO need to filter branch nodes based on requested
                    # interval... how?!?!?
                    yield node
                    found_branch_nodes.add(node.path)

            if not leaf_nodes:
                continue

            if len(leaf_nodes) == 1:
                yield leaf_nodes.pop()
            elif len(leaf_nodes) > 1:
                reader = MultiReader(leaf_nodes)
                yield LeafNode(path, reader)


class FindQuery(object):
    def __init__(self, pattern, startTime, endTime):
        self.pattern = pattern
        self.startTime = startTime
        self.endTime = endTime
        self.isExact = is_pattern(pattern)
        self.interval = Interval(
            float('-inf') if startTime is None else startTime,
            float('inf') if endTime is None else endTime)

    def __repr__(self):
        if self.startTime is None:
            startString = '*'
        else:
            startString = time.ctime(self.startTime)

        if self.endTime is None:
            endString = '*'
        else:
            endString = time.ctime(self.endTime)

        return '<FindQuery: %s from %s until %s>' % (self.pattern, startString,
                                                     endString)