Beispiel #1
0
    def ListDescendentPathInfos(self,
                                client_id,
                                path_type,
                                components,
                                max_depth=None):
        """Lists path info records that correspond to children of given path."""
        result = []

        for path_idx, path_record in iteritems(self.path_records):
            other_client_id, other_path_type, other_components = path_idx
            if client_id != other_client_id or path_type != other_path_type:
                continue
            if len(other_components) == len(components):
                continue
            if not collection.StartsWith(other_components, components):
                continue
            if (max_depth is not None
                    and len(other_components) - len(components) > max_depth):
                continue

            result.append(path_record.GetPathInfo())

        result.sort(key=lambda _: tuple(_.components))
        return result
Beispiel #2
0
 def testNonListIterable(self):
   self.assertTrue(collection.StartsWith((5, 4, 3), (5, 4)))
Beispiel #3
0
 def testString(self):
   self.assertTrue(collection.StartsWith("foobar", "foo"))
Beispiel #4
0
 def testStringList(self):
   self.assertTrue(collection.StartsWith(["a", "b", "c"], ["a", "b"]))
Beispiel #5
0
 def testDifferentElement(self):
   self.assertFalse(collection.StartsWith([1, 2, 3], [1, 4, 5]))
Beispiel #6
0
 def testProperPrefix(self):
   self.assertTrue(collection.StartsWith([1, 2, 3], [1, 2]))
   self.assertTrue(collection.StartsWith([1, 2, 3], [1]))
Beispiel #7
0
 def testEqual(self):
   self.assertTrue(collection.StartsWith([1, 2, 3], [1, 2, 3]))
Beispiel #8
0
 def testEmptyDoesNotStartWithNonEmpty(self):
   self.assertFalse(collection.StartsWith([], [1, 2, 3]))
Beispiel #9
0
 def testNonEmptyStartsWithEmpty(self):
   self.assertTrue(collection.StartsWith([1, 2, 3], []))
Beispiel #10
0
 def testEmptyStartsWithEmpty(self):
   self.assertTrue(collection.StartsWith([], []))
Beispiel #11
0
    def ListDescendentPathInfos(self,
                                client_id,
                                path_type,
                                components,
                                timestamp=None,
                                max_depth=None):
        """Lists path info records that correspond to children of given path."""
        result = []

        for path_idx, path_record in iteritems(self.path_records):
            other_client_id, other_path_type, other_components = path_idx
            if client_id != other_client_id or path_type != other_path_type:
                continue
            if len(other_components) == len(components):
                continue
            if not collection.StartsWith(other_components, components):
                continue
            if (max_depth is not None
                    and len(other_components) - len(components) > max_depth):
                continue

            result.append(path_record.GetPathInfo(timestamp=timestamp))

        if timestamp is None:
            return sorted(result, key=lambda _: tuple(_.components))

        # We need to filter implicit path infos if specific timestamp is given.

        # TODO(hanuszczak): If we were to switch to use path trie instead of storing
        # records by path id, everything would be much easier.

        class TrieNode(object):
            """A trie of path components with path infos as values."""
            def __init__(self):
                self.path_info = None
                self.children = {}
                self.explicit = False

            def Add(self, path_info, idx=0):
                """Adds given path info to the trie (or one of its subtrees)."""
                components = path_info.components
                if idx == len(components):
                    self.path_info = path_info
                    self.explicit |= (path_info.HasField("stat_entry")
                                      or path_info.HasField("hash_entry"))
                else:
                    child = self.children.setdefault(components[idx],
                                                     TrieNode())
                    child.Add(path_info, idx=idx + 1)
                    self.explicit |= child.explicit

            def Collect(self, path_infos):
                if self.path_info is not None and self.explicit:
                    path_infos.append(self.path_info)

                for component in sorted(iterkeys(self.children)):
                    self.children[component].Collect(path_infos)

        trie = TrieNode()
        for path_info in result:
            trie.Add(path_info)

        explicit_path_infos = []
        trie.Collect(explicit_path_infos)
        return explicit_path_infos