)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"7993c9ba2c4fd6f80b83d990736501141af12e80","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"placement: add traits support in the AllocationCandidates object"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"This patch add the filter \u0027traits\u0027 to AllocationCandidates object"},{"line_number":10,"context_line":"which enables to filter resource provider with required traits."},{"line_number":11,"context_line":"Also fetches the traits from the DB, and returns traits in the"},{"line_number":12,"context_line":"Provider Summary object."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":10,"id":"5f4e5783_312c3498","line":9,"range":{"start_line":9,"start_character":27,"end_line":9,"end_character":33},"updated":"2017-10-12 15:44:43.000000000","message":"required","commit_id":"7377c4ff684c161edc369805ae7d8749de2ed351"}],"nova/objects/resource_provider.py":[{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"7993c9ba2c4fd6f80b83d990736501141af12e80","unresolved":false,"context_lines":[{"line_number":2472,"context_line":"        # requested resources or are associated with the providers that"},{"line_number":2473,"context_line":"        # share one or more of the requested resource(s)"},{"line_number":2474,"context_line":"        resources \u003d filters.get(\u0027resources\u0027)"},{"line_number":2475,"context_line":"        required_traits \u003d filters.get(\u0027traits\u0027)"},{"line_number":2476,"context_line":"        if not resources:"},{"line_number":2477,"context_line":"            raise ValueError(_(\"Supply a resources collection in filters.\"))"},{"line_number":2478,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"5f4e5783_a929da9b","line":2475,"range":{"start_line":2475,"start_character":39,"end_line":2475,"end_character":45},"updated":"2017-10-12 15:44:43.000000000","message":"Per spec, this is called \u0027required\u0027.  (I like the variable being named `required_traits`, though.)","commit_id":"7377c4ff684c161edc369805ae7d8749de2ed351"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"7993c9ba2c4fd6f80b83d990736501141af12e80","unresolved":false,"context_lines":[{"line_number":2482,"context_line":"            for key, value in resources.items()"},{"line_number":2483,"context_line":"        }"},{"line_number":2484,"context_line":""},{"line_number":2485,"context_line":"        roots \u003d [r[0] for r in _get_all_with_shared(context, resources)]"},{"line_number":2486,"context_line":""},{"line_number":2487,"context_line":"        if not roots:"},{"line_number":2488,"context_line":"            return [], []"}],"source_content_type":"text/x-python","patch_set":10,"id":"5f4e5783_74fe1aaf","line":2485,"updated":"2017-10-12 15:44:43.000000000","message":"Looks like we\u0027re turning this into a set every time we use it (except L2624, where I think a set would be fine too).  For efficiency, consider using curly braces here instead.","commit_id":"7377c4ff684c161edc369805ae7d8749de2ed351"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"7993c9ba2c4fd6f80b83d990736501141af12e80","unresolved":false,"context_lines":[{"line_number":2544,"context_line":"            roots_with_required_traits \u003d set()"},{"line_number":2545,"context_line":"            sharing_rps_with_required_traits \u003d set()"},{"line_number":2546,"context_line":"            roots_with_any_trait \u003d _get_provider_ids_with_any_trait(context,"},{"line_number":2547,"context_line":"                required_traits, set(roots))"},{"line_number":2548,"context_line":""},{"line_number":2549,"context_line":"            # In the case we only request a trait in the shared RP, there may"},{"line_number":2550,"context_line":"            # no any trait in the root RP, but we stil need to go through them."}],"source_content_type":"text/x-python","patch_set":10,"id":"5f4e5783_94c0767d","line":2547,"range":{"start_line":2547,"start_character":33,"end_line":2547,"end_character":43},"updated":"2017-10-12 15:44:43.000000000","message":"Use keys for named kwargs","commit_id":"7377c4ff684c161edc369805ae7d8749de2ed351"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"9a212db82181b5ff83c481ceea05e832423cfe5b","unresolved":false,"context_lines":[{"line_number":2546,"context_line":"            roots_with_any_trait \u003d _get_provider_ids_with_any_trait(context,"},{"line_number":2547,"context_line":"                required_traits, set(roots))"},{"line_number":2548,"context_line":""},{"line_number":2549,"context_line":"            # In the case we only request a trait in the shared RP, there may"},{"line_number":2550,"context_line":"            # no any trait in the root RP, but we stil need to go through them."},{"line_number":2551,"context_line":"            for root in set(roots) - set(roots_with_any_trait.keys()):"},{"line_number":2552,"context_line":"                roots_with_any_trait[root] \u003d set()"}],"source_content_type":"text/x-python","patch_set":10,"id":"5f4e5783_293a2ecb","line":2549,"range":{"start_line":2549,"start_character":29,"end_line":2549,"end_character":66},"updated":"2017-10-16 18:35:43.000000000","message":"See late comments on [1] - this is going to break pretty hard once nested RPs are in play (if it hasn\u0027t already).  We should reconsider how this works with shared RPs and whether we can rip out any consideration of aggregates for the time being until that\u0027s figured out.\n\n[1] https://review.openstack.org/#/c/497713/10","commit_id":"7377c4ff684c161edc369805ae7d8749de2ed351"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"7993c9ba2c4fd6f80b83d990736501141af12e80","unresolved":false,"context_lines":[{"line_number":2547,"context_line":"                required_traits, set(roots))"},{"line_number":2548,"context_line":""},{"line_number":2549,"context_line":"            # In the case we only request a trait in the shared RP, there may"},{"line_number":2550,"context_line":"            # no any trait in the root RP, but we stil need to go through them."},{"line_number":2551,"context_line":"            for root in set(roots) - set(roots_with_any_trait.keys()):"},{"line_number":2552,"context_line":"                roots_with_any_trait[root] \u003d set()"},{"line_number":2553,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"5f4e5783_d1604004","line":2550,"range":{"start_line":2550,"start_character":14,"end_line":2550,"end_character":16},"updated":"2017-10-12 15:44:43.000000000","message":"not be","commit_id":"7377c4ff684c161edc369805ae7d8749de2ed351"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"7993c9ba2c4fd6f80b83d990736501141af12e80","unresolved":false,"context_lines":[{"line_number":2547,"context_line":"                required_traits, set(roots))"},{"line_number":2548,"context_line":""},{"line_number":2549,"context_line":"            # In the case we only request a trait in the shared RP, there may"},{"line_number":2550,"context_line":"            # no any trait in the root RP, but we stil need to go through them."},{"line_number":2551,"context_line":"            for root in set(roots) - set(roots_with_any_trait.keys()):"},{"line_number":2552,"context_line":"                roots_with_any_trait[root] \u003d set()"},{"line_number":2553,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"5f4e5783_b15b8452","line":2550,"range":{"start_line":2550,"start_character":50,"end_line":2550,"end_character":54},"updated":"2017-10-12 15:44:43.000000000","message":"still","commit_id":"7377c4ff684c161edc369805ae7d8749de2ed351"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"7993c9ba2c4fd6f80b83d990736501141af12e80","unresolved":false,"context_lines":[{"line_number":2548,"context_line":""},{"line_number":2549,"context_line":"            # In the case we only request a trait in the shared RP, there may"},{"line_number":2550,"context_line":"            # no any trait in the root RP, but we stil need to go through them."},{"line_number":2551,"context_line":"            for root in set(roots) - set(roots_with_any_trait.keys()):"},{"line_number":2552,"context_line":"                roots_with_any_trait[root] \u003d set()"},{"line_number":2553,"context_line":""},{"line_number":2554,"context_line":"            sharing_rps_with_any_trait \u003d _get_provider_ids_with_any_trait("}],"source_content_type":"text/x-python","patch_set":10,"id":"5f4e5783_b43c92bf","line":2551,"range":{"start_line":2551,"start_character":61,"end_line":2551,"end_character":68},"updated":"2017-10-12 15:44:43.000000000","message":".keys() is redundant","commit_id":"7377c4ff684c161edc369805ae7d8749de2ed351"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"7993c9ba2c4fd6f80b83d990736501141af12e80","unresolved":false,"context_lines":[{"line_number":2548,"context_line":""},{"line_number":2549,"context_line":"            # In the case we only request a trait in the shared RP, there may"},{"line_number":2550,"context_line":"            # no any trait in the root RP, but we stil need to go through them."},{"line_number":2551,"context_line":"            for root in set(roots) - set(roots_with_any_trait.keys()):"},{"line_number":2552,"context_line":"                roots_with_any_trait[root] \u003d set()"},{"line_number":2553,"context_line":""},{"line_number":2554,"context_line":"            sharing_rps_with_any_trait \u003d _get_provider_ids_with_any_trait("}],"source_content_type":"text/x-python","patch_set":10,"id":"5f4e5783_d495ce41","line":2551,"range":{"start_line":2551,"start_character":24,"end_line":2551,"end_character":70},"updated":"2017-10-12 15:44:43.000000000","message":"Is set(roots) - set(roots_with_any_trait) the same as sharing_providers ?","commit_id":"7377c4ff684c161edc369805ae7d8749de2ed351"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"e8f1b6ba57ee5bf3e4d8b04bd16606d1808c1e2f","unresolved":false,"context_lines":[{"line_number":2549,"context_line":"            # In the case we only request a trait in the shared RP, there may"},{"line_number":2550,"context_line":"            # no any trait in the root RP, but we stil need to go through them."},{"line_number":2551,"context_line":"            for root in set(roots) - set(roots_with_any_trait.keys()):"},{"line_number":2552,"context_line":"                roots_with_any_trait[root] \u003d set()"},{"line_number":2553,"context_line":""},{"line_number":2554,"context_line":"            sharing_rps_with_any_trait \u003d _get_provider_ids_with_any_trait("},{"line_number":2555,"context_line":"                context,"}],"source_content_type":"text/x-python","patch_set":10,"id":"3f4b6375_02bb3b0e","line":2552,"range":{"start_line":2552,"start_character":16,"end_line":2552,"end_character":36},"updated":"2017-10-20 14:36:11.000000000","message":"Is this changing the list we are iterating on?\nAlso roots_with_any_trait is a defaultdict(set) if I understand correctly so setting the value at the root key only meaningful here if the root key is already in the roots_with_any_trait in which case it will replace the value generated by _get_provider_ids_with_any_trait with an empty set. Is it the intention here?","commit_id":"7377c4ff684c161edc369805ae7d8749de2ed351"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"e2091a1c49d245ab75239f13224c9d3866b9e20b","unresolved":false,"context_lines":[{"line_number":2549,"context_line":"            # In the case we only request a trait in the shared RP, there may"},{"line_number":2550,"context_line":"            # no any trait in the root RP, but we stil need to go through them."},{"line_number":2551,"context_line":"            for root in set(roots) - set(roots_with_any_trait.keys()):"},{"line_number":2552,"context_line":"                roots_with_any_trait[root] \u003d set()"},{"line_number":2553,"context_line":""},{"line_number":2554,"context_line":"            sharing_rps_with_any_trait \u003d _get_provider_ids_with_any_trait("},{"line_number":2555,"context_line":"                context,"}],"source_content_type":"text/x-python","patch_set":10,"id":"3f4b6375_4d795f91","line":2552,"range":{"start_line":2552,"start_character":16,"end_line":2552,"end_character":36},"in_reply_to":"3f4b6375_02bb3b0e","updated":"2017-10-20 20:10:57.000000000","message":"It\u0027s not changing the dict we\u0027re iterating on.  L2551 creates a new iterable.\n\nThe set we\u0027re iterating over will not contain any of the keys originally in roots_with_any_trait, so we\u0027ll never overwrite an existing key from that guy.\n\nThis loop is needed so that the loop on 2560 will still walk through all the RPs that match the requested resources.\n\n\u003cnerdy\u003e\nIt could have been done more tersely (and cryptically) in one like like:\n\n[roots_with_any_trait[root] for root in roots]\n\n...which will create (and not do anything with) a list of values in the defaultdict for every root.  Referencing them will be a no-op if they\u0027re there, but will initialize them if they\u0027re not.\n\nhttp://paste.openstack.org/show/624221/\n\u003c/nerdy\u003e","commit_id":"7377c4ff684c161edc369805ae7d8749de2ed351"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"7993c9ba2c4fd6f80b83d990736501141af12e80","unresolved":false,"context_lines":[{"line_number":2554,"context_line":"            sharing_rps_with_any_trait \u003d _get_provider_ids_with_any_trait("},{"line_number":2555,"context_line":"                context,"},{"line_number":2556,"context_line":"                required_traits,"},{"line_number":2557,"context_line":"                set(itertools.chain(*sharing_providers.values())))"},{"line_number":2558,"context_line":""},{"line_number":2559,"context_line":"            for root, traits in roots_with_any_trait.items():"},{"line_number":2560,"context_line":"                root_summary \u003d summaries[root]"}],"source_content_type":"text/x-python","patch_set":10,"id":"5f4e5783_14100601","line":2557,"range":{"start_line":2557,"start_character":16,"end_line":2557,"end_character":65},"updated":"2017-10-12 15:44:43.000000000","message":"Use keys for named kwargs","commit_id":"7377c4ff684c161edc369805ae7d8749de2ed351"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"7993c9ba2c4fd6f80b83d990736501141af12e80","unresolved":false,"context_lines":[{"line_number":2559,"context_line":"            for root, traits in roots_with_any_trait.items():"},{"line_number":2560,"context_line":"                root_summary \u003d summaries[root]"},{"line_number":2561,"context_line":"                shared_resources \u003d set("},{"line_number":2562,"context_line":"                    rc_id for rc_id in resources.keys()"},{"line_number":2563,"context_line":"                    if rc_id not in root_summary[\u0027resources\u0027]"},{"line_number":2564,"context_line":"                )"},{"line_number":2565,"context_line":"                # If there is no sharing resources and the root rp doesn\u0027t"}],"source_content_type":"text/x-python","patch_set":10,"id":"5f4e5783_1447e67a","line":2562,"range":{"start_line":2562,"start_character":48,"end_line":2562,"end_character":55},"updated":"2017-10-12 15:44:43.000000000","message":"redundant","commit_id":"7377c4ff684c161edc369805ae7d8749de2ed351"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"7993c9ba2c4fd6f80b83d990736501141af12e80","unresolved":false,"context_lines":[{"line_number":2569,"context_line":"                        roots_with_required_traits.add(root)"},{"line_number":2570,"context_line":"                    continue"},{"line_number":2571,"context_line":"                # The required traits may spread in sharing rps. So"},{"line_number":2572,"context_line":"                # generate the combiantions of the sharing rps and"},{"line_number":2573,"context_line":"                # calculate the tratis in each combination."},{"line_number":2574,"context_line":"                sharing_rps_tuple \u003d _get_sharing_rp_combinations("},{"line_number":2575,"context_line":"                    sharing_providers)"}],"source_content_type":"text/x-python","patch_set":10,"id":"5f4e5783_541b1e80","line":2572,"range":{"start_line":2572,"start_character":31,"end_line":2572,"end_character":43},"updated":"2017-10-12 15:44:43.000000000","message":"combinations","commit_id":"7377c4ff684c161edc369805ae7d8749de2ed351"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"7993c9ba2c4fd6f80b83d990736501141af12e80","unresolved":false,"context_lines":[{"line_number":2575,"context_line":"                    sharing_providers)"},{"line_number":2576,"context_line":"                for sharing_rps in sharing_rps_tuple:"},{"line_number":2577,"context_line":"                    sharing_traits \u003d set()"},{"line_number":2578,"context_line":"                    for sharing_rp in list(*sharing_rps):"},{"line_number":2579,"context_line":"                        sharing_traits |\u003d sharing_rps_with_any_trait["},{"line_number":2580,"context_line":"                            sharing_rp]"},{"line_number":2581,"context_line":"                    if (len(required_traits) \u003d\u003d"}],"source_content_type":"text/x-python","patch_set":10,"id":"5f4e5783_d7af10e1","line":2578,"range":{"start_line":2578,"start_character":38,"end_line":2578,"end_character":56},"updated":"2017-10-12 15:44:43.000000000","message":"list() is unnecessary","commit_id":"7377c4ff684c161edc369805ae7d8749de2ed351"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"7993c9ba2c4fd6f80b83d990736501141af12e80","unresolved":false,"context_lines":[{"line_number":2582,"context_line":"                            len(roots_with_any_trait[root] | sharing_traits)):"},{"line_number":2583,"context_line":"                        roots_with_required_traits.add(root)"},{"line_number":2584,"context_line":"                        sharing_rps_with_required_traits |\u003d set("},{"line_number":2585,"context_line":"                            list(*sharing_rps))"},{"line_number":2586,"context_line":""},{"line_number":2587,"context_line":"            # filter out the rps which doesn\u0027t have enough required traits."},{"line_number":2588,"context_line":"            roots \u003d set(roots) \u0026 roots_with_required_traits"}],"source_content_type":"text/x-python","patch_set":10,"id":"5f4e5783_97b9982f","line":2585,"range":{"start_line":2585,"start_character":28,"end_line":2585,"end_character":46},"updated":"2017-10-12 15:44:43.000000000","message":"list() is unnecessary","commit_id":"7377c4ff684c161edc369805ae7d8749de2ed351"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"527a8a665e8223551692f11e720401b902061b81","unresolved":false,"context_lines":[{"line_number":2593,"context_line":"            summaries \u003d {rp_id: summary"},{"line_number":2594,"context_line":"                for rp_id, summary in summaries.items()"},{"line_number":2595,"context_line":"                    if rp_id in (roots_with_required_traits |"},{"line_number":2596,"context_line":"                                     sharing_rps_with_required_traits)}"},{"line_number":2597,"context_line":""},{"line_number":2598,"context_line":"        # Next, build up a list of allocation requests. These allocation"},{"line_number":2599,"context_line":"        # requests are AllocationRequest objects, containing resource provider"}],"source_content_type":"text/x-python","patch_set":10,"id":"5f4e5783_6ad3dd39","line":2596,"updated":"2017-10-12 07:42:21.000000000","message":"I probably will separate the whole block code into separated methods, and test them separately.","commit_id":"7377c4ff684c161edc369805ae7d8749de2ed351"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"e8f1b6ba57ee5bf3e4d8b04bd16606d1808c1e2f","unresolved":false,"context_lines":[{"line_number":2593,"context_line":"            summaries \u003d {rp_id: summary"},{"line_number":2594,"context_line":"                for rp_id, summary in summaries.items()"},{"line_number":2595,"context_line":"                    if rp_id in (roots_with_required_traits |"},{"line_number":2596,"context_line":"                                     sharing_rps_with_required_traits)}"},{"line_number":2597,"context_line":""},{"line_number":2598,"context_line":"        # Next, build up a list of allocation requests. These allocation"},{"line_number":2599,"context_line":"        # requests are AllocationRequest objects, containing resource provider"}],"source_content_type":"text/x-python","patch_set":10,"id":"3f4b6375_42cb7371","line":2596,"in_reply_to":"5f4e5783_6ad3dd39","updated":"2017-10-20 14:36:11.000000000","message":"+++++","commit_id":"7377c4ff684c161edc369805ae7d8749de2ed351"}],"nova/tests/functional/db/test_resource_provider.py":[{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"7993c9ba2c4fd6f80b83d990736501141af12e80","unresolved":false,"context_lines":[{"line_number":3169,"context_line":"        self.assertEqual(set(), rp_dict[cn1.id])"},{"line_number":3170,"context_line":"        self.assertEqual(set(), rp_dict[cn2.id])"},{"line_number":3171,"context_line":"        self.assertEqual(set([t_a.id, t_b.id]), rp_dict[cn3.id])"},{"line_number":3172,"context_line":""},{"line_number":3173,"context_line":"    def test_local_with_traits(self):"},{"line_number":3174,"context_line":"        # Create two compute node providers with VCPU, RAM and local disk"},{"line_number":3175,"context_line":"        cn1_uuid \u003d uuidsentinel.cn1"}],"source_content_type":"text/x-python","patch_set":10,"id":"5f4e5783_570680d0","line":3172,"updated":"2017-10-12 15:44:43.000000000","message":"These tests are only looking at the provider_summaries of the results.  They should also be inspecting the allocation_requests to ensure the correct ones are returned.","commit_id":"7377c4ff684c161edc369805ae7d8749de2ed351"}]}
