)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"5b9bb79a21621bfcadf8317e9ff8c2b4b4ddec16","unresolved":false,"context_lines":[{"line_number":4,"context_line":"Commit:     Sean Mooney \u003cwork@seanmooney.info\u003e"},{"line_number":5,"context_line":"CommitDate: 2020-06-23 18:25:02 +0000"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"[WIP] make provider tree and proviers iterable"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"this change adds __iter__ and __reper__"},{"line_number":10,"context_line":"for ProviderTree and Provier classes"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"bf51134e_95f6afd6","line":7,"range":{"start_line":7,"start_character":5,"end_line":7,"end_character":46},"updated":"2020-06-23 23:48:39.000000000","message":"to your top level question the reason for doing this are basically as follows.\n\n- in my mental model trees are collections and since providers contain a list of there childeren they are also collections. collection in python are normally iterable so i expect to be able to iterate over a ProviderTree like any other python collection using \"for provider in provider_tree: ...\" or \"for child in parent:..\"\n\n- if we make the trees iterable it then allows us to use list /dict/tuple comprehensions over the provider in a provier tree or there children. This also allows us to use itertools and friends if it makes sense to do so.\n\n- by making the iterators generator function we can avoid copies when not need and iterate in a coperative thread sharing way without first needing to build a list of all the providers and iterate over that.\n\n- by creating the __repr__ function we simplfy debug by making the ProviderTree and Provider classes trivialy logable/printable.\n\nthose are the reason i want to do this\n\nthe motivation however is i am starting to work on the numa in placment feature and i want a simple way to work with the trees and providers and print the result of the tree before and after so that i can visually asset my tests are correct and the transformation of the tree is doing what i want.\n\nas you said this might actully help the lots-of-ironic-nodes case although for now at least im still going to have \nget_provider_uuids return a list of uuid instead of converting it also to a generator but that could be done as a followup  initaly i do not want the refactor to change to signigure of get_provider_uuids or get_provider_uuids_in_tree but we could look into what optimisation are posible once the inital refactor is done. i just dont want to mix a change in behavior with the introduction of iteration so im not sure if this will have and driect performance impovement in this patch.","commit_id":"0d0e91b354fdea2af97edea69f8c05cc601473a8"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"05908391b08cc5eae1ff3bde3d17d280e690be32","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"[WIP] make provider tree and proviers iterable"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"this change adds __iter__ and __reper__"},{"line_number":10,"context_line":"for ProviderTree and Provier classes"},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"TODO: invert the logic so get_provider_uuids"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"bf51134e_1f0be0d5","line":9,"range":{"start_line":9,"start_character":35,"end_line":9,"end_character":36},"updated":"2020-06-23 18:53:32.000000000","message":"no e in __repr__","commit_id":"0d0e91b354fdea2af97edea69f8c05cc601473a8"}],"nova/compute/provider_tree.py":[{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"05908391b08cc5eae1ff3bde3d17d280e690be32","unresolved":false,"context_lines":[{"line_number":95,"context_line":"        \"\"\"Returns a list, in top-down traversal order, of UUIDs of this"},{"line_number":96,"context_line":"        provider and all its descendants."},{"line_number":97,"context_line":"        \"\"\""},{"line_number":98,"context_line":"        ret \u003d [self.uuid]"},{"line_number":99,"context_line":"        for child in self.children.values():"},{"line_number":100,"context_line":"            ret.extend(child.get_provider_uuids())"},{"line_number":101,"context_line":"        return ret"},{"line_number":102,"context_line":""},{"line_number":103,"context_line":"    def __iter__(self):"},{"line_number":104,"context_line":"        for child in self.children.values():"}],"source_content_type":"text/x-python","patch_set":1,"id":"bf51134e_9fda5075","line":101,"range":{"start_line":98,"start_character":8,"end_line":101,"end_character":18},"updated":"2020-06-23 18:53:32.000000000","message":"as noted in the commit message i should be inverting the logice so baseically get_provider_uuids in provier or ProviderTree\n\ncan become something like this\n\ndef get_provider_uuids(self):\n    return [provider.uuid for provider in self]\n\nwith the iteration logic then handeld by __iter__","commit_id":"0d0e91b354fdea2af97edea69f8c05cc601473a8"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"05908391b08cc5eae1ff3bde3d17d280e690be32","unresolved":false,"context_lines":[{"line_number":265,"context_line":"    def roots(self):"},{"line_number":266,"context_line":"        return six.itervalues(self.roots_by_uuid)"},{"line_number":267,"context_line":""},{"line_number":268,"context_line":"    def get_provider_uuids(self, name_or_uuid\u003dNone):"},{"line_number":269,"context_line":"        \"\"\"Return a list, in top-down traversable order, of the UUIDs of all"},{"line_number":270,"context_line":"        providers (in a (sub)tree)."},{"line_number":271,"context_line":""},{"line_number":272,"context_line":"        :param name_or_uuid: Provider name or UUID representing the root of a"},{"line_number":273,"context_line":"                             (sub)tree for which to return UUIDs.  If not"},{"line_number":274,"context_line":"                             specified, the method returns all UUIDs in the"},{"line_number":275,"context_line":"                             ProviderTree."},{"line_number":276,"context_line":"        \"\"\""},{"line_number":277,"context_line":"        if name_or_uuid is not None:"},{"line_number":278,"context_line":"            with self.lock:"},{"line_number":279,"context_line":"                return self._find_with_lock(name_or_uuid).get_provider_uuids()"},{"line_number":280,"context_line":""},{"line_number":281,"context_line":"        # If no name_or_uuid, get UUIDs for all providers recursively."},{"line_number":282,"context_line":"        ret \u003d []"},{"line_number":283,"context_line":"        with self.lock:"},{"line_number":284,"context_line":"            for root in self.roots:"},{"line_number":285,"context_line":"                ret.extend(root.get_provider_uuids())"},{"line_number":286,"context_line":"        return ret"},{"line_number":287,"context_line":""},{"line_number":288,"context_line":"    def get_provider_uuids_in_tree(self, name_or_uuid):"},{"line_number":289,"context_line":"        \"\"\"Returns a list, in top-down traversable order, of the UUIDs of all"},{"line_number":290,"context_line":"        providers in the whole tree of which the provider identified by"},{"line_number":291,"context_line":"        ``name_or_uuid`` is a member."},{"line_number":292,"context_line":""},{"line_number":293,"context_line":"        :param name_or_uuid: Provider name or UUID representing any member of"},{"line_number":294,"context_line":"                             whole tree for which to return UUIDs."},{"line_number":295,"context_line":"        \"\"\""},{"line_number":296,"context_line":"        with self.lock:"},{"line_number":297,"context_line":"            return self._find_with_lock("},{"line_number":298,"context_line":"                name_or_uuid, return_root\u003dTrue).get_provider_uuids()"},{"line_number":299,"context_line":""},{"line_number":300,"context_line":"    def __iter__(self):"},{"line_number":301,"context_line":"        for uuid in self.get_provider_uuids():"},{"line_number":302,"context_line":"            yield self._find_with_lock(uuid)"},{"line_number":303,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"bf51134e_7f3e5c8b","line":300,"range":{"start_line":268,"start_character":3,"end_line":300,"end_character":23},"updated":"2020-06-23 18:53:32.000000000","message":"because these version can take a name_or_uuid i wont quite\nbe able to just do \n\ndef get_provider_uuids(self):\n    return [provider.uuid for provider in self]\n\nbut something like \n\ndef get_provider_uuids(self,  name_or_uuid\u003dNone):\n    if  name_or_uuid is None:\n       return [provider.uuid for provider in self]\n    with self.lock:\n        return self._find_with_lock(name_or_uuid).get_provider_uuids()\n\nshould be all that is needed.\n\nthen the actual iteration can live in the __iter__ function and this can basically just be the list comprehence to turn the iterator of provider into a list of there uuids\n\nthen anywhere in the code that you want to iterate over the provider in a provider tree you can now do \n\nfor provider in provider_tree:\n  do_stuff(provider)\n\nand the same will work with providers\ne.g.\n\nfor child in provider:\n  do_work(child)","commit_id":"0d0e91b354fdea2af97edea69f8c05cc601473a8"},{"author":{"_account_id":26458,"name":"Brin Zhang","email":"zhangbailin@inspur.com","username":"zhangbailin"},"change_message_id":"aa156fa3b2cb76501bd169b019d368aee20f702b","unresolved":false,"context_lines":[{"line_number":446,"context_line":"    def __getitem__(self, name_or_uuid):"},{"line_number":447,"context_line":"        # Optimization for large number of roots (e.g. ironic): if name_or_uuid"},{"line_number":448,"context_line":"        # represents a root, this is O(1)."},{"line_number":449,"context_line":"        found \u003d self.roots_by_uuid.get(name_or_uuid)"},{"line_number":450,"context_line":"        if found is not None:"},{"line_number":451,"context_line":"            return found"},{"line_number":452,"context_line":"        found \u003d self.roots_by_name.get(name_or_uuid)"}],"source_content_type":"text/x-python","patch_set":4,"id":"bf51134e_5dd88051","line":449,"range":{"start_line":449,"start_character":39,"end_line":449,"end_character":51},"updated":"2020-06-28 02:18:01.000000000","message":"Note to myself: I would like to use uuidutils.is_uuid_like(name_or_uuid) to ensure is this a uuid, but it has any exception, so it\u0027s not suitable.","commit_id":"7dc57e4e9e20e474d483a06f708da1f6773ce4bf"},{"author":{"_account_id":26458,"name":"Brin Zhang","email":"zhangbailin@inspur.com","username":"zhangbailin"},"change_message_id":"aa156fa3b2cb76501bd169b019d368aee20f702b","unresolved":false,"context_lines":[{"line_number":447,"context_line":"        # Optimization for large number of roots (e.g. ironic): if name_or_uuid"},{"line_number":448,"context_line":"        # represents a root, this is O(1)."},{"line_number":449,"context_line":"        found \u003d self.roots_by_uuid.get(name_or_uuid)"},{"line_number":450,"context_line":"        if found is not None:"},{"line_number":451,"context_line":"            return found"},{"line_number":452,"context_line":"        found \u003d self.roots_by_name.get(name_or_uuid)"},{"line_number":453,"context_line":"        if found is not None:"}],"source_content_type":"text/x-python","patch_set":4,"id":"bf51134e_dd1e500a","line":450,"range":{"start_line":450,"start_character":7,"end_line":450,"end_character":29},"updated":"2020-06-28 02:18:01.000000000","message":"I think use \"if found: return found\" instead above is ok.","commit_id":"7dc57e4e9e20e474d483a06f708da1f6773ce4bf"},{"author":{"_account_id":26458,"name":"Brin Zhang","email":"zhangbailin@inspur.com","username":"zhangbailin"},"change_message_id":"aa156fa3b2cb76501bd169b019d368aee20f702b","unresolved":false,"context_lines":[{"line_number":450,"context_line":"        if found is not None:"},{"line_number":451,"context_line":"            return found"},{"line_number":452,"context_line":"        found \u003d self.roots_by_name.get(name_or_uuid)"},{"line_number":453,"context_line":"        if found is not None:"},{"line_number":454,"context_line":"            return found"},{"line_number":455,"context_line":""},{"line_number":456,"context_line":"        # Okay, it\u0027s a child; do it the hard way."}],"source_content_type":"text/x-python","patch_set":4,"id":"bf51134e_3d1aec15","line":453,"range":{"start_line":453,"start_character":11,"end_line":453,"end_character":28},"updated":"2020-06-28 02:18:01.000000000","message":"ditto.","commit_id":"7dc57e4e9e20e474d483a06f708da1f6773ce4bf"},{"author":{"_account_id":26458,"name":"Brin Zhang","email":"zhangbailin@inspur.com","username":"zhangbailin"},"change_message_id":"aa156fa3b2cb76501bd169b019d368aee20f702b","unresolved":false,"context_lines":[{"line_number":456,"context_line":"        # Okay, it\u0027s a child; do it the hard way."},{"line_number":457,"context_line":"        for root in self.roots:"},{"line_number":458,"context_line":"            found \u003d root.find(name_or_uuid)"},{"line_number":459,"context_line":"            if found is not None:"},{"line_number":460,"context_line":"                return found"},{"line_number":461,"context_line":"        raise ValueError(_(\"No such provider %s\") % name_or_uuid)"},{"line_number":462,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"bf51134e_9dde983b","line":459,"range":{"start_line":459,"start_character":15,"end_line":459,"end_character":32},"updated":"2020-06-28 02:18:01.000000000","message":"ditto","commit_id":"7dc57e4e9e20e474d483a06f708da1f6773ce4bf"}]}
