)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"c53fad91761da20ab052fcfb523e2f2c497db47c","unresolved":false,"context_lines":[{"line_number":4,"context_line":"Commit:     Eric Fried \u003cefried@us.ibm.com\u003e"},{"line_number":5,"context_line":"CommitDate: 2017-11-15 08:04:41 -0600"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"begin refactor AllocCandidates._get_by_filters()"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"The AllocationCandidates._get_by_filters() method is a long, complex"},{"line_number":10,"context_line":"mega-method. We want to detangle it and make the code in it"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":10,"id":"1f485f77_50ef38e8","line":7,"range":{"start_line":7,"start_character":31,"end_line":7,"end_character":46},"updated":"2017-11-17 21:15:48.000000000","message":"Hah, just realized this is now _get_by_requests in the code.","commit_id":"039c94a6b98546573f34e0dc9c0a7cd6d84caa5f"}],"nova/objects/resource_provider.py":[{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"0b82cfebfdbe90f5fe4702378a953b8c0cff251e","unresolved":false,"context_lines":[{"line_number":2424,"context_line":"    return ctx.session.execute(query).fetchall()"},{"line_number":2425,"context_line":""},{"line_number":2426,"context_line":""},{"line_number":2427,"context_line":"@db_api.api_context_manager.reader"},{"line_number":2428,"context_line":"def _get_provider_ids_matching_all(ctx, resources):"},{"line_number":2429,"context_line":"    \"\"\"Returns a list of resource provider internal IDs that have available"},{"line_number":2430,"context_line":"    inventory to satisfy all the supplied requests for resources."}],"source_content_type":"text/x-python","patch_set":1,"id":"3f4b6375_e5201ffa","line":2427,"updated":"2017-10-31 22:09:48.000000000","message":"I\u0027ve convinced myself via functional test that this does what it says.  I still need to come back and figure out how it works.\n\nI recognize that I\u0027m still a bit new to this sqlalchemy business, but I wonder if this could somehow be made simpler or more readable for mere mortals.","commit_id":"1402b575a5299cd5a66ef2431f77db16d07dbc5b"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"0b82cfebfdbe90f5fe4702378a953b8c0cff251e","unresolved":false,"context_lines":[{"line_number":2425,"context_line":""},{"line_number":2426,"context_line":""},{"line_number":2427,"context_line":"@db_api.api_context_manager.reader"},{"line_number":2428,"context_line":"def _get_provider_ids_matching_all(ctx, resources):"},{"line_number":2429,"context_line":"    \"\"\"Returns a list of resource provider internal IDs that have available"},{"line_number":2430,"context_line":"    inventory to satisfy all the supplied requests for resources."},{"line_number":2431,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"3f4b6375_98c31358","line":2428,"range":{"start_line":2428,"start_character":4,"end_line":2428,"end_character":34},"updated":"2017-10-31 22:09:48.000000000","message":"Per our IRC discussion, this method is ultimately only going to be useful for the use_same_provider\u003dTrue (\"numbered\") request groups.  (Although at that time, we\u0027ll probably want to chain in a traits condition.)  In the current code base, we\u0027re not handling nested RPs - the compute node RP is flying solo - so this method can be used for the optimized case where no sharing RPs are in play.\n\nThis is mostly a note-to-self, but a code comment describing the above wouldn\u0027t go amiss.","commit_id":"1402b575a5299cd5a66ef2431f77db16d07dbc5b"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"0b82cfebfdbe90f5fe4702378a953b8c0cff251e","unresolved":false,"context_lines":[{"line_number":2448,"context_line":"    }"},{"line_number":2449,"context_line":""},{"line_number":2450,"context_line":"    # Dict, keyed by resource class ID, of a derived table (subquery in the"},{"line_number":2451,"context_line":"    # FROM clause or JOIN) against the allocations table  winnowed to only that"},{"line_number":2452,"context_line":"    # resource class, grouped by resource provider."},{"line_number":2453,"context_line":"    usage_tables \u003d {"},{"line_number":2454,"context_line":"        rc_id: sa.alias("}],"source_content_type":"text/x-python","patch_set":1,"id":"3f4b6375_33ffa068","line":2451,"range":{"start_line":2451,"start_character":56,"end_line":2451,"end_character":58},"updated":"2017-10-31 22:09:48.000000000","message":"egads, extra space!","commit_id":"1402b575a5299cd5a66ef2431f77db16d07dbc5b"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"0b82cfebfdbe90f5fe4702378a953b8c0cff251e","unresolved":false,"context_lines":[{"line_number":2518,"context_line":""},{"line_number":2519,"context_line":"    sel \u003d sel.select_from(join_chain)"},{"line_number":2520,"context_line":"    sel \u003d sel.where(sa.and_(*where_conds))"},{"line_number":2521,"context_line":"    sel \u003d sel.group_by(rpt.c.id)"},{"line_number":2522,"context_line":""},{"line_number":2523,"context_line":"    return [r[0] for r in ctx.session.execute(sel)]"},{"line_number":2524,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"3f4b6375_d3216cfe","line":2521,"updated":"2017-10-31 22:09:48.000000000","message":"Does this group_by do the same thing as .distinct(rpt.c.id) would?  Else we have the possibility of getting duplicates in the list.  (Which we could turn into a set, but more efficient to do the DISTINCT in the db, right?)","commit_id":"1402b575a5299cd5a66ef2431f77db16d07dbc5b"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"0b82cfebfdbe90f5fe4702378a953b8c0cff251e","unresolved":false,"context_lines":[{"line_number":2594,"context_line":"            rc_id: _get_providers_with_shared_capacity(context, rc_id, amount)"},{"line_number":2595,"context_line":"            for rc_id, amount in resources.items()"},{"line_number":2596,"context_line":"        }"},{"line_number":2597,"context_line":"        have_sharing \u003d any(sharing for sharing in sharing_providers.values())"},{"line_number":2598,"context_line":"        if not have_sharing:"},{"line_number":2599,"context_line":"            # We know there\u0027s no sharing providers, so we can more efficiently"},{"line_number":2600,"context_line":"            # get a list of resource provider IDs that have ALL the requested"}],"source_content_type":"text/x-python","patch_set":1,"id":"3f4b6375_05d57bb7","line":2597,"range":{"start_line":2597,"start_character":8,"end_line":2597,"end_character":20},"updated":"2017-10-31 22:09:48.000000000","message":"Could fold this into the conditional, since it\u0027s not used anywhere else.","commit_id":"1402b575a5299cd5a66ef2431f77db16d07dbc5b"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"0b82cfebfdbe90f5fe4702378a953b8c0cff251e","unresolved":false,"context_lines":[{"line_number":2594,"context_line":"            rc_id: _get_providers_with_shared_capacity(context, rc_id, amount)"},{"line_number":2595,"context_line":"            for rc_id, amount in resources.items()"},{"line_number":2596,"context_line":"        }"},{"line_number":2597,"context_line":"        have_sharing \u003d any(sharing for sharing in sharing_providers.values())"},{"line_number":2598,"context_line":"        if not have_sharing:"},{"line_number":2599,"context_line":"            # We know there\u0027s no sharing providers, so we can more efficiently"},{"line_number":2600,"context_line":"            # get a list of resource provider IDs that have ALL the requested"}],"source_content_type":"text/x-python","patch_set":1,"id":"3f4b6375_85084b91","line":2597,"range":{"start_line":2597,"start_character":27,"end_line":2597,"end_character":76},"updated":"2017-10-31 22:09:48.000000000","message":"I would think this could just be\n\n any(sharing_providers.values())","commit_id":"1402b575a5299cd5a66ef2431f77db16d07dbc5b"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"0b82cfebfdbe90f5fe4702378a953b8c0cff251e","unresolved":false,"context_lines":[{"line_number":2595,"context_line":"            for rc_id, amount in resources.items()"},{"line_number":2596,"context_line":"        }"},{"line_number":2597,"context_line":"        have_sharing \u003d any(sharing for sharing in sharing_providers.values())"},{"line_number":2598,"context_line":"        if not have_sharing:"},{"line_number":2599,"context_line":"            # We know there\u0027s no sharing providers, so we can more efficiently"},{"line_number":2600,"context_line":"            # get a list of resource provider IDs that have ALL the requested"},{"line_number":2601,"context_line":"            # resources"}],"source_content_type":"text/x-python","patch_set":1,"id":"3f4b6375_0550db5d","line":2598,"range":{"start_line":2598,"start_character":8,"end_line":2598,"end_character":28},"updated":"2017-10-31 22:09:48.000000000","message":"nit: personal preference for\n\n if condition:\n     A\n else:\n     B\n\nversus\n\n if not condition:\n     B\n else:\n     A","commit_id":"1402b575a5299cd5a66ef2431f77db16d07dbc5b"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"0b82cfebfdbe90f5fe4702378a953b8c0cff251e","unresolved":false,"context_lines":[{"line_number":2598,"context_line":"        if not have_sharing:"},{"line_number":2599,"context_line":"            # We know there\u0027s no sharing providers, so we can more efficiently"},{"line_number":2600,"context_line":"            # get a list of resource provider IDs that have ALL the requested"},{"line_number":2601,"context_line":"            # resources"},{"line_number":2602,"context_line":"            non_sharing_rp_ids \u003d _get_provider_ids_matching_all("},{"line_number":2603,"context_line":"                context, resources)"},{"line_number":2604,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":1,"id":"3f4b6375_65342f4b","line":2601,"updated":"2017-10-31 22:09:48.000000000","message":"NOTE(whoever): This still assumes the non-sharing provider is a singleton (no nested RP trees).","commit_id":"1402b575a5299cd5a66ef2431f77db16d07dbc5b"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"0b82cfebfdbe90f5fe4702378a953b8c0cff251e","unresolved":false,"context_lines":[{"line_number":2614,"context_line":"        # resources with it. In other words, this is the list of resource"},{"line_number":2615,"context_line":"        # provider IDs that are NOT sharing resources."},{"line_number":2616,"context_line":"        if not non_sharing_rp_ids:"},{"line_number":2617,"context_line":"            return [], []"},{"line_number":2618,"context_line":""},{"line_number":2619,"context_line":"        # We need to grab usage information for all the providers identified as"},{"line_number":2620,"context_line":"        # potentially fulfilling part of the resource request. This includes"}],"source_content_type":"text/x-python","patch_set":1,"id":"3f4b6375_05fe9b37","line":2617,"updated":"2017-10-31 22:09:48.000000000","message":"Hum, do we really want to short out here without checking the sharing_providers?  Isn\u0027t it hypothetically legal for me to get *all* my resources from sharing providers associated with my aggregate?  IRL (for now, for computes) it\u0027s unlikely to happen, but in the general case?","commit_id":"1402b575a5299cd5a66ef2431f77db16d07dbc5b"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"b0a5c99565114e98c706ff99d0e25d8c58b934bb","unresolved":false,"context_lines":[{"line_number":2427,"context_line":"@db_api.api_context_manager.reader"},{"line_number":2428,"context_line":"def _get_provider_ids_matching_all(ctx, resources):"},{"line_number":2429,"context_line":"    \"\"\"Returns a list of resource provider internal IDs that have available"},{"line_number":2430,"context_line":"    inventory to satisfy all the supplied requests for resources."},{"line_number":2431,"context_line":""},{"line_number":2432,"context_line":"    :param ctx: Session context to use"},{"line_number":2433,"context_line":"    :param resources: A dict, keyed by resource class ID, of the amount"}],"source_content_type":"text/x-python","patch_set":2,"id":"3f4b6375_942d1748","line":2430,"range":{"start_line":2430,"start_character":25,"end_line":2430,"end_character":65},"updated":"2017-11-01 02:25:43.000000000","message":"How do we implement filter on nested RP?\n\nEric pointed out a case in my series about\n\nthere are two child RPs. both them have resource X and Y, when the first RP\u0027s Y is exhausted, then Y can be allocated from the seconds RP.\n\nThe final result is X allocated from the First RP and Y allocated from the second RP.","commit_id":"20cac8c21f5c6c79fed13c07b7dfca79409c55dc"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"f0408ba56b6d351c77bf1806ef559a7739f91389","unresolved":false,"context_lines":[{"line_number":2427,"context_line":"@db_api.api_context_manager.reader"},{"line_number":2428,"context_line":"def _get_provider_ids_matching_all(ctx, resources):"},{"line_number":2429,"context_line":"    \"\"\"Returns a list of resource provider internal IDs that have available"},{"line_number":2430,"context_line":"    inventory to satisfy all the supplied requests for resources."},{"line_number":2431,"context_line":""},{"line_number":2432,"context_line":"    :param ctx: Session context to use"},{"line_number":2433,"context_line":"    :param resources: A dict, keyed by resource class ID, of the amount"}],"source_content_type":"text/x-python","patch_set":2,"id":"3f4b6375_704859cb","line":2430,"range":{"start_line":2430,"start_character":25,"end_line":2430,"end_character":65},"in_reply_to":"3f4b6375_0d4fd292","updated":"2017-11-01 12:55:23.000000000","message":"I didn\u0027t see how this isn\u0027t for the nested scenario.\n\nFrom the last patch, there are two paths, one for non-shared resources, another for shared resources. The one for non-shared resources, I thought it should consider the nested scenario also.","commit_id":"20cac8c21f5c6c79fed13c07b7dfca79409c55dc"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"c14a5f740b5cc78842e3f853c2c0d29f325e70d9","unresolved":false,"context_lines":[{"line_number":2427,"context_line":"@db_api.api_context_manager.reader"},{"line_number":2428,"context_line":"def _get_provider_ids_matching_all(ctx, resources):"},{"line_number":2429,"context_line":"    \"\"\"Returns a list of resource provider internal IDs that have available"},{"line_number":2430,"context_line":"    inventory to satisfy all the supplied requests for resources."},{"line_number":2431,"context_line":""},{"line_number":2432,"context_line":"    :param ctx: Session context to use"},{"line_number":2433,"context_line":"    :param resources: A dict, keyed by resource class ID, of the amount"}],"source_content_type":"text/x-python","patch_set":2,"id":"3f4b6375_a259d935","line":2430,"range":{"start_line":2430,"start_character":25,"end_line":2430,"end_character":65},"in_reply_to":"3f4b6375_704859cb","updated":"2017-11-01 22:02:45.000000000","message":"I\u0027m leaving nested out of this series. It will be handled in later patches once n-r-p is actually merged...","commit_id":"20cac8c21f5c6c79fed13c07b7dfca79409c55dc"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"b9f7b68fdfd8551a58b78ecb04d04f5b4acec7a3","unresolved":false,"context_lines":[{"line_number":2427,"context_line":"@db_api.api_context_manager.reader"},{"line_number":2428,"context_line":"def _get_provider_ids_matching_all(ctx, resources):"},{"line_number":2429,"context_line":"    \"\"\"Returns a list of resource provider internal IDs that have available"},{"line_number":2430,"context_line":"    inventory to satisfy all the supplied requests for resources."},{"line_number":2431,"context_line":""},{"line_number":2432,"context_line":"    :param ctx: Session context to use"},{"line_number":2433,"context_line":"    :param resources: A dict, keyed by resource class ID, of the amount"}],"source_content_type":"text/x-python","patch_set":2,"id":"3f4b6375_0d4fd292","line":2430,"range":{"start_line":2430,"start_character":25,"end_line":2430,"end_character":65},"in_reply_to":"3f4b6375_942d1748","updated":"2017-11-01 12:28:27.000000000","message":"See my comments in PS1 - this method is not going to be used for the unnumbered group in a nested scenario.","commit_id":"20cac8c21f5c6c79fed13c07b7dfca79409c55dc"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"6f02d13f9d72f8f4495c4c94fc11131ff619f774","unresolved":false,"context_lines":[{"line_number":2476,"context_line":"    # The last inventory join"},{"line_number":2477,"context_line":"    lastij \u003d None"},{"line_number":2478,"context_line":""},{"line_number":2479,"context_line":"    for rc_id, amount in resources.items():"},{"line_number":2480,"context_line":"        it \u003d inv_tables[rc_id]"},{"line_number":2481,"context_line":"        ut \u003d usage_tables[rc_id]"},{"line_number":2482,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"3f4b6375_9c6e4e94","line":2479,"updated":"2017-11-01 16:20:55.000000000","message":"This loop is puréeing my brain.  I think more comments and more descriptive variable names would help quite a bit.  E.g. I think I\u0027ve picked up that jc is a join condition?  But what is it a join condition on?  Resource providers and inventory?  So rp_inv_join_cond would be easier to read.  I know it\u0027ll force L2488 to two lines, but I think it\u0027s worth it.  (or could alias resource_provider_id to rp_id)","commit_id":"20cac8c21f5c6c79fed13c07b7dfca79409c55dc"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"27b5f7ac64e4c827e18e510d8da5c93f3413878a","unresolved":false,"context_lines":[{"line_number":2476,"context_line":"    # The last inventory join"},{"line_number":2477,"context_line":"    lastij \u003d None"},{"line_number":2478,"context_line":""},{"line_number":2479,"context_line":"    for rc_id, amount in resources.items():"},{"line_number":2480,"context_line":"        it \u003d inv_tables[rc_id]"},{"line_number":2481,"context_line":"        ut \u003d usage_tables[rc_id]"},{"line_number":2482,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"3f4b6375_bfb1f2e3","line":2479,"in_reply_to":"3f4b6375_9c6e4e94","updated":"2017-11-01 21:58:44.000000000","message":"Done","commit_id":"20cac8c21f5c6c79fed13c07b7dfca79409c55dc"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"6f02d13f9d72f8f4495c4c94fc11131ff619f774","unresolved":false,"context_lines":[{"line_number":2481,"context_line":"        ut \u003d usage_tables[rc_id]"},{"line_number":2482,"context_line":""},{"line_number":2483,"context_line":"        if join_chain is None:"},{"line_number":2484,"context_line":"            rp_link \u003d rpt"},{"line_number":2485,"context_line":"            jc \u003d rpt.c.id \u003d\u003d it.c.resource_provider_id"},{"line_number":2486,"context_line":"        else:"},{"line_number":2487,"context_line":"            rp_link \u003d join_chain"}],"source_content_type":"text/x-python","patch_set":2,"id":"3f4b6375_a27684d7","line":2484,"range":{"start_line":2484,"start_character":12,"end_line":2484,"end_character":19},"updated":"2017-11-01 16:20:55.000000000","message":"This var isn\u0027t needed - use join_chain.","commit_id":"20cac8c21f5c6c79fed13c07b7dfca79409c55dc"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"27b5f7ac64e4c827e18e510d8da5c93f3413878a","unresolved":false,"context_lines":[{"line_number":2481,"context_line":"        ut \u003d usage_tables[rc_id]"},{"line_number":2482,"context_line":""},{"line_number":2483,"context_line":"        if join_chain is None:"},{"line_number":2484,"context_line":"            rp_link \u003d rpt"},{"line_number":2485,"context_line":"            jc \u003d rpt.c.id \u003d\u003d it.c.resource_provider_id"},{"line_number":2486,"context_line":"        else:"},{"line_number":2487,"context_line":"            rp_link \u003d join_chain"}],"source_content_type":"text/x-python","patch_set":2,"id":"3f4b6375_9fb4f6d2","line":2484,"range":{"start_line":2484,"start_character":12,"end_line":2484,"end_character":19},"in_reply_to":"3f4b6375_a27684d7","updated":"2017-11-01 21:58:44.000000000","message":"Done","commit_id":"20cac8c21f5c6c79fed13c07b7dfca79409c55dc"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"6f02d13f9d72f8f4495c4c94fc11131ff619f774","unresolved":false,"context_lines":[{"line_number":2485,"context_line":"            jc \u003d rpt.c.id \u003d\u003d it.c.resource_provider_id"},{"line_number":2486,"context_line":"        else:"},{"line_number":2487,"context_line":"            rp_link \u003d join_chain"},{"line_number":2488,"context_line":"            jc \u003d lastij.c.resource_provider_id \u003d\u003d it.c.resource_provider_id"},{"line_number":2489,"context_line":""},{"line_number":2490,"context_line":"        # We can do a more efficient INNER JOIN because we don\u0027t have shared"},{"line_number":2491,"context_line":"        # resource providers to deal with"}],"source_content_type":"text/x-python","patch_set":2,"id":"3f4b6375_052b2282","line":2488,"range":{"start_line":2488,"start_character":17,"end_line":2488,"end_character":46},"updated":"2017-11-01 16:20:55.000000000","message":"This can just be rpt.c.id.","commit_id":"20cac8c21f5c6c79fed13c07b7dfca79409c55dc"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"27b5f7ac64e4c827e18e510d8da5c93f3413878a","unresolved":false,"context_lines":[{"line_number":2485,"context_line":"            jc \u003d rpt.c.id \u003d\u003d it.c.resource_provider_id"},{"line_number":2486,"context_line":"        else:"},{"line_number":2487,"context_line":"            rp_link \u003d join_chain"},{"line_number":2488,"context_line":"            jc \u003d lastij.c.resource_provider_id \u003d\u003d it.c.resource_provider_id"},{"line_number":2489,"context_line":""},{"line_number":2490,"context_line":"        # We can do a more efficient INNER JOIN because we don\u0027t have shared"},{"line_number":2491,"context_line":"        # resource providers to deal with"}],"source_content_type":"text/x-python","patch_set":2,"id":"3f4b6375_7fcb7a52","line":2488,"range":{"start_line":2488,"start_character":17,"end_line":2488,"end_character":46},"in_reply_to":"3f4b6375_052b2282","updated":"2017-11-01 21:58:44.000000000","message":"Done","commit_id":"20cac8c21f5c6c79fed13c07b7dfca79409c55dc"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"27b5f7ac64e4c827e18e510d8da5c93f3413878a","unresolved":false,"context_lines":[{"line_number":2428,"context_line":"def _get_provider_ids_matching_all(ctx, resources):"},{"line_number":2429,"context_line":"    \"\"\"Returns a list of resource provider internal IDs that have available"},{"line_number":2430,"context_line":"    inventory to satisfy all the supplied requests for resources."},{"line_number":2431,"context_line":""},{"line_number":2432,"context_line":"    :param ctx: Session context to use"},{"line_number":2433,"context_line":"    :param resources: A dict, keyed by resource class ID, of the amount"},{"line_number":2434,"context_line":"                      requested of that resource class."}],"source_content_type":"text/x-python","patch_set":3,"id":"3f4b6375_1feec6b3","line":2431,"updated":"2017-11-01 21:58:44.000000000","message":"Per PS1 comment, it wouldn\u0027t hurt to add some verbiage here explaining that this method can not be used for scenarios where requested resources can come from sharing RPs or from different RPs in a nested tree.","commit_id":"f59c9734fdd52298d34e7e6f729ce4a0bca0bc83"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"944d4682fa3314ad1cc1e5ea892bbb225f746d2f","unresolved":false,"context_lines":[{"line_number":2428,"context_line":"def _get_provider_ids_matching_all(ctx, resources):"},{"line_number":2429,"context_line":"    \"\"\"Returns a list of resource provider internal IDs that have available"},{"line_number":2430,"context_line":"    inventory to satisfy all the supplied requests for resources."},{"line_number":2431,"context_line":""},{"line_number":2432,"context_line":"    :param ctx: Session context to use"},{"line_number":2433,"context_line":"    :param resources: A dict, keyed by resource class ID, of the amount"},{"line_number":2434,"context_line":"                      requested of that resource class."}],"source_content_type":"text/x-python","patch_set":3,"id":"3f4b6375_66288096","line":2431,"in_reply_to":"3f4b6375_1feec6b3","updated":"2017-11-02 14:15:08.000000000","message":"Done","commit_id":"f59c9734fdd52298d34e7e6f729ce4a0bca0bc83"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"27b5f7ac64e4c827e18e510d8da5c93f3413878a","unresolved":false,"context_lines":[{"line_number":2448,"context_line":"    }"},{"line_number":2449,"context_line":""},{"line_number":2450,"context_line":"    # Dict, keyed by resource class ID, of a derived table (subquery in the"},{"line_number":2451,"context_line":"    # FROM clause or JOIN) against the allocations table  winnowed to only that"},{"line_number":2452,"context_line":"    # resource class, grouped by resource provider."},{"line_number":2453,"context_line":"    usage_tables \u003d {"},{"line_number":2454,"context_line":"        rc_id: sa.alias("}],"source_content_type":"text/x-python","patch_set":3,"id":"3f4b6375_ffdc0a19","line":2451,"range":{"start_line":2451,"start_character":56,"end_line":2451,"end_character":58},"updated":"2017-11-01 21:58:44.000000000","message":"extra space","commit_id":"f59c9734fdd52298d34e7e6f729ce4a0bca0bc83"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"944d4682fa3314ad1cc1e5ea892bbb225f746d2f","unresolved":false,"context_lines":[{"line_number":2448,"context_line":"    }"},{"line_number":2449,"context_line":""},{"line_number":2450,"context_line":"    # Dict, keyed by resource class ID, of a derived table (subquery in the"},{"line_number":2451,"context_line":"    # FROM clause or JOIN) against the allocations table  winnowed to only that"},{"line_number":2452,"context_line":"    # resource class, grouped by resource provider."},{"line_number":2453,"context_line":"    usage_tables \u003d {"},{"line_number":2454,"context_line":"        rc_id: sa.alias("}],"source_content_type":"text/x-python","patch_set":3,"id":"3f4b6375_89194f7b","line":2451,"range":{"start_line":2451,"start_character":56,"end_line":2451,"end_character":58},"in_reply_to":"3f4b6375_ffdc0a19","updated":"2017-11-02 14:15:08.000000000","message":"Done","commit_id":"f59c9734fdd52298d34e7e6f729ce4a0bca0bc83"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"27b5f7ac64e4c827e18e510d8da5c93f3413878a","unresolved":false,"context_lines":[{"line_number":2510,"context_line":""},{"line_number":2511,"context_line":"    sel \u003d sel.select_from(join_chain)"},{"line_number":2512,"context_line":"    sel \u003d sel.where(sa.and_(*where_conds))"},{"line_number":2513,"context_line":"    sel \u003d sel.group_by(rpt.c.id)"},{"line_number":2514,"context_line":""},{"line_number":2515,"context_line":"    return [r[0] for r in ctx.session.execute(sel)]"},{"line_number":2516,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"3f4b6375_bf6c5208","line":2513,"range":{"start_line":2513,"start_character":14,"end_line":2513,"end_character":22},"updated":"2017-11-01 21:58:44.000000000","message":"This isn\u0027t needed.","commit_id":"f59c9734fdd52298d34e7e6f729ce4a0bca0bc83"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"944d4682fa3314ad1cc1e5ea892bbb225f746d2f","unresolved":false,"context_lines":[{"line_number":2510,"context_line":""},{"line_number":2511,"context_line":"    sel \u003d sel.select_from(join_chain)"},{"line_number":2512,"context_line":"    sel \u003d sel.where(sa.and_(*where_conds))"},{"line_number":2513,"context_line":"    sel \u003d sel.group_by(rpt.c.id)"},{"line_number":2514,"context_line":""},{"line_number":2515,"context_line":"    return [r[0] for r in ctx.session.execute(sel)]"},{"line_number":2516,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"3f4b6375_292edb91","line":2513,"range":{"start_line":2513,"start_character":14,"end_line":2513,"end_character":22},"in_reply_to":"3f4b6375_bf6c5208","updated":"2017-11-02 14:15:08.000000000","message":"Done","commit_id":"f59c9734fdd52298d34e7e6f729ce4a0bca0bc83"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"27b5f7ac64e4c827e18e510d8da5c93f3413878a","unresolved":false,"context_lines":[{"line_number":2586,"context_line":"            rc_id: _get_providers_with_shared_capacity(context, rc_id, amount)"},{"line_number":2587,"context_line":"            for rc_id, amount in resources.items()"},{"line_number":2588,"context_line":"        }"},{"line_number":2589,"context_line":"        have_sharing \u003d any(sharing for sharing in sharing_providers.values())"},{"line_number":2590,"context_line":"        if not have_sharing:"},{"line_number":2591,"context_line":"            # We know there\u0027s no sharing providers, so we can more efficiently"},{"line_number":2592,"context_line":"            # get a list of resource provider IDs that have ALL the requested"}],"source_content_type":"text/x-python","patch_set":3,"id":"3f4b6375_ff4bea83","line":2589,"range":{"start_line":2589,"start_character":27,"end_line":2589,"end_character":76},"updated":"2017-11-01 21:58:44.000000000","message":"This could just be sharing_providers.values().\n\nAnd this could be inlined into the conditional, since have_sharing isn\u0027t actually used anywhere else.","commit_id":"f59c9734fdd52298d34e7e6f729ce4a0bca0bc83"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"3c718042b4125c5ffeb3fc16f9fafad3d16641eb","unresolved":false,"context_lines":[{"line_number":2586,"context_line":"            rc_id: _get_providers_with_shared_capacity(context, rc_id, amount)"},{"line_number":2587,"context_line":"            for rc_id, amount in resources.items()"},{"line_number":2588,"context_line":"        }"},{"line_number":2589,"context_line":"        have_sharing \u003d any(sharing for sharing in sharing_providers.values())"},{"line_number":2590,"context_line":"        if not have_sharing:"},{"line_number":2591,"context_line":"            # We know there\u0027s no sharing providers, so we can more efficiently"},{"line_number":2592,"context_line":"            # get a list of resource provider IDs that have ALL the requested"}],"source_content_type":"text/x-python","patch_set":3,"id":"3f4b6375_9da19e49","line":2589,"range":{"start_line":2589,"start_character":27,"end_line":2589,"end_character":76},"in_reply_to":"3f4b6375_82693dbf","updated":"2017-11-01 23:44:55.000000000","message":"Sorry, I wasn\u0027t clear.  The any() stays.\n\n have_sharing \u003d any(sharing_providers.values())\n\n In [4]: l \u003d [[], []]\n\n In [5]: any(l)\n Out[5]: False\n\n In [6]: any(x for x in l)\n Out[6]: False\n\n In [7]: l \u003d [[1], []]\n\n In [8]: any(l)\n Out[8]: True\n\n In [9]: any(x for x in l)\n Out[9]: True","commit_id":"f59c9734fdd52298d34e7e6f729ce4a0bca0bc83"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"944d4682fa3314ad1cc1e5ea892bbb225f746d2f","unresolved":false,"context_lines":[{"line_number":2586,"context_line":"            rc_id: _get_providers_with_shared_capacity(context, rc_id, amount)"},{"line_number":2587,"context_line":"            for rc_id, amount in resources.items()"},{"line_number":2588,"context_line":"        }"},{"line_number":2589,"context_line":"        have_sharing \u003d any(sharing for sharing in sharing_providers.values())"},{"line_number":2590,"context_line":"        if not have_sharing:"},{"line_number":2591,"context_line":"            # We know there\u0027s no sharing providers, so we can more efficiently"},{"line_number":2592,"context_line":"            # get a list of resource provider IDs that have ALL the requested"}],"source_content_type":"text/x-python","patch_set":3,"id":"3f4b6375_695df313","line":2589,"range":{"start_line":2589,"start_character":27,"end_line":2589,"end_character":76},"in_reply_to":"3f4b6375_9da19e49","updated":"2017-11-02 14:15:08.000000000","message":"Ah, gotcha. OK, fixed.","commit_id":"f59c9734fdd52298d34e7e6f729ce4a0bca0bc83"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"bd85fc0c0cf7da032ccaac37409b5de3bd2ba65f","unresolved":false,"context_lines":[{"line_number":2586,"context_line":"            rc_id: _get_providers_with_shared_capacity(context, rc_id, amount)"},{"line_number":2587,"context_line":"            for rc_id, amount in resources.items()"},{"line_number":2588,"context_line":"        }"},{"line_number":2589,"context_line":"        have_sharing \u003d any(sharing for sharing in sharing_providers.values())"},{"line_number":2590,"context_line":"        if not have_sharing:"},{"line_number":2591,"context_line":"            # We know there\u0027s no sharing providers, so we can more efficiently"},{"line_number":2592,"context_line":"            # get a list of resource provider IDs that have ALL the requested"}],"source_content_type":"text/x-python","patch_set":3,"id":"3f4b6375_82693dbf","line":2589,"range":{"start_line":2589,"start_character":27,"end_line":2589,"end_character":76},"in_reply_to":"3f4b6375_ff4bea83","updated":"2017-11-01 22:06:02.000000000","message":"No, because sharing_providers.values() results in the following:\n\n [[],[]]\n\nwhich evaluates to True.","commit_id":"f59c9734fdd52298d34e7e6f729ce4a0bca0bc83"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"27b5f7ac64e4c827e18e510d8da5c93f3413878a","unresolved":false,"context_lines":[{"line_number":2590,"context_line":"        if not have_sharing:"},{"line_number":2591,"context_line":"            # We know there\u0027s no sharing providers, so we can more efficiently"},{"line_number":2592,"context_line":"            # get a list of resource provider IDs that have ALL the requested"},{"line_number":2593,"context_line":"            # resources"},{"line_number":2594,"context_line":"            non_sharing_rp_ids \u003d _get_provider_ids_matching_all("},{"line_number":2595,"context_line":"                context, resources)"},{"line_number":2596,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":3,"id":"3f4b6375_7f249ac6","line":2593,"updated":"2017-11-01 21:58:44.000000000","message":"Add a note that n-r-p will require a third code path.  (Or be part of the one above.  But in any case, won\u0027t go through this one.)","commit_id":"f59c9734fdd52298d34e7e6f729ce4a0bca0bc83"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"944d4682fa3314ad1cc1e5ea892bbb225f746d2f","unresolved":false,"context_lines":[{"line_number":2590,"context_line":"        if not have_sharing:"},{"line_number":2591,"context_line":"            # We know there\u0027s no sharing providers, so we can more efficiently"},{"line_number":2592,"context_line":"            # get a list of resource provider IDs that have ALL the requested"},{"line_number":2593,"context_line":"            # resources"},{"line_number":2594,"context_line":"            non_sharing_rp_ids \u003d _get_provider_ids_matching_all("},{"line_number":2595,"context_line":"                context, resources)"},{"line_number":2596,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":3,"id":"3f4b6375_09a2fffc","line":2593,"in_reply_to":"3f4b6375_7f249ac6","updated":"2017-11-02 14:15:08.000000000","message":"n-r-p in and of itself doesn\u0027t *necessarily* require a separate code path, but rather, the returned value will be the root_provider_id\u0027s instead of the resource provider\u0027s id value. I\u0027ll add a little note.","commit_id":"f59c9734fdd52298d34e7e6f729ce4a0bca0bc83"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"27b5f7ac64e4c827e18e510d8da5c93f3413878a","unresolved":false,"context_lines":[{"line_number":2606,"context_line":"        # resources with it. In other words, this is the list of resource"},{"line_number":2607,"context_line":"        # provider IDs that are NOT sharing resources."},{"line_number":2608,"context_line":"        if not non_sharing_rp_ids:"},{"line_number":2609,"context_line":"            return [], []"},{"line_number":2610,"context_line":""},{"line_number":2611,"context_line":"        # We need to grab usage information for all the providers identified as"},{"line_number":2612,"context_line":"        # potentially fulfilling part of the resource request. This includes"}],"source_content_type":"text/x-python","patch_set":3,"id":"3f4b6375_3f2e22a5","line":2609,"range":{"start_line":2609,"start_character":12,"end_line":2609,"end_character":25},"updated":"2017-11-01 21:58:44.000000000","message":"Hum, do we really want to short out here without checking the sharing_providers?  Isn\u0027t it hypothetically legal for me to get *all* my resources from sharing providers associated with my aggregate?  IRL (for now, for computes) it\u0027s unlikely to happen, but in the general case?","commit_id":"f59c9734fdd52298d34e7e6f729ce4a0bca0bc83"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"944d4682fa3314ad1cc1e5ea892bbb225f746d2f","unresolved":false,"context_lines":[{"line_number":2606,"context_line":"        # resources with it. In other words, this is the list of resource"},{"line_number":2607,"context_line":"        # provider IDs that are NOT sharing resources."},{"line_number":2608,"context_line":"        if not non_sharing_rp_ids:"},{"line_number":2609,"context_line":"            return [], []"},{"line_number":2610,"context_line":""},{"line_number":2611,"context_line":"        # We need to grab usage information for all the providers identified as"},{"line_number":2612,"context_line":"        # potentially fulfilling part of the resource request. This includes"}],"source_content_type":"text/x-python","patch_set":3,"id":"3f4b6375_69fcd3b4","line":2609,"range":{"start_line":2609,"start_character":12,"end_line":2609,"end_character":25},"in_reply_to":"3f4b6375_3f2e22a5","updated":"2017-11-02 14:15:08.000000000","message":"AllocationCandidates is currently only called from the nova-scheduler and so this makes sense. I\u0027ll add a note that this might need to come out if other callers make use of the allocation candidates functionality.","commit_id":"f59c9734fdd52298d34e7e6f729ce4a0bca0bc83"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"fa5b15dfd107329006a5e2cd3f8ba87539628c23","unresolved":false,"context_lines":[{"line_number":2475,"context_line":"    # resources"},{"line_number":2476,"context_line":"    where_conds \u003d []"},{"line_number":2477,"context_line":""},{"line_number":2478,"context_line":"    # The chain of joins that we eventually pass to select_from()"},{"line_number":2479,"context_line":"    join_chain \u003d None"},{"line_number":2480,"context_line":"    # The last inventory join"},{"line_number":2481,"context_line":"    lastij \u003d None"},{"line_number":2482,"context_line":""},{"line_number":2483,"context_line":"    for rc_id, amount in resources.items():"},{"line_number":2484,"context_line":"        it \u003d inv_tables[rc_id]"},{"line_number":2485,"context_line":"        ut \u003d usage_tables[rc_id]"},{"line_number":2486,"context_line":""},{"line_number":2487,"context_line":"        if join_chain is None:"},{"line_number":2488,"context_line":"            rp_link \u003d rpt"},{"line_number":2489,"context_line":"            jc \u003d rpt.c.id \u003d\u003d it.c.resource_provider_id"},{"line_number":2490,"context_line":"        else:"},{"line_number":2491,"context_line":"            rp_link \u003d join_chain"},{"line_number":2492,"context_line":"            jc \u003d lastij.c.resource_provider_id \u003d\u003d it.c.resource_provider_id"},{"line_number":2493,"context_line":""},{"line_number":2494,"context_line":"        # We can do a more efficient INNER JOIN because we don\u0027t have shared"},{"line_number":2495,"context_line":"        # resource providers to deal with"},{"line_number":2496,"context_line":"        inv_join \u003d sa.join("},{"line_number":2497,"context_line":"            rp_link, it,"},{"line_number":2498,"context_line":"            sa.and_("},{"line_number":2499,"context_line":"                jc,"},{"line_number":2500,"context_line":"                # Add a join condition winnowing this copy of inventories table"},{"line_number":2501,"context_line":"                # to only the resource class being analyzed in this loop..."},{"line_number":2502,"context_line":"                it.c.resource_class_id \u003d\u003d rc_id,"},{"line_number":2503,"context_line":"            ),"},{"line_number":2504,"context_line":"        )"},{"line_number":2505,"context_line":"        lastij \u003d it"},{"line_number":2506,"context_line":"        usage_join \u003d sa.outerjoin("},{"line_number":2507,"context_line":"            inv_join, ut,"},{"line_number":2508,"context_line":"            it.c.resource_provider_id \u003d\u003d ut.c.resource_provider_id,"},{"line_number":2509,"context_line":"        )"},{"line_number":2510,"context_line":"        join_chain \u003d usage_join"},{"line_number":2511,"context_line":""},{"line_number":2512,"context_line":"        usage_cond \u003d sa.and_("},{"line_number":2513,"context_line":"            ("},{"line_number":2514,"context_line":"            (sql.func.coalesce(ut.c.used, 0) + amount) \u003c\u003d"},{"line_number":2515,"context_line":"            (it.c.total - it.c.reserved) * it.c.allocation_ratio"},{"line_number":2516,"context_line":"            ),"},{"line_number":2517,"context_line":"            it.c.min_unit \u003c\u003d amount,"},{"line_number":2518,"context_line":"            it.c.max_unit \u003e\u003d amount,"},{"line_number":2519,"context_line":"            amount % it.c.step_size \u003d\u003d 0,"},{"line_number":2520,"context_line":"        )"},{"line_number":2521,"context_line":"        where_conds.append(usage_cond)"},{"line_number":2522,"context_line":""},{"line_number":2523,"context_line":"    sel \u003d sel.select_from(join_chain)"}],"source_content_type":"text/x-python","patch_set":4,"id":"3f4b6375_d59a3460","line":2520,"range":{"start_line":2478,"start_character":0,"end_line":2520,"end_character":9},"updated":"2017-11-02 16:18:34.000000000","message":"argh, you overwrote my changes from PS3.","commit_id":"800d99dc7ca1f9799badb8f3cf878918a094c05a"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"87698837b9e33ef9b5c826e2df596d70b63bc126","unresolved":false,"context_lines":[{"line_number":2612,"context_line":"        # resources and are related to a provider that is sharing some"},{"line_number":2613,"context_line":"        # resources with it. In other words, this is the list of resource"},{"line_number":2614,"context_line":"        # provider IDs that are NOT sharing resources."},{"line_number":2615,"context_line":"        # NOTE(jaypipes): This assumes that callers of the GET"},{"line_number":2616,"context_line":"        # /allocation_candidates API call are only interested in getting back"},{"line_number":2617,"context_line":"        # results when there is at least one non-sharing provider of resources."},{"line_number":2618,"context_line":"        # This is the case for our only caller at the moment (nova-scheduler)."},{"line_number":2619,"context_line":"        # In the future, if another caller wants to use allocation candidates"},{"line_number":2620,"context_line":"        # for scheduling to sharing-only providers, we can remove this"}],"source_content_type":"text/x-python","patch_set":5,"id":"3f4b6375_5e241960","line":2617,"range":{"start_line":2615,"start_character":26,"end_line":2617,"end_character":79},"updated":"2017-11-03 00:50:12.000000000","message":"So....why this testcase can pass https://github.com/openstack/nova/blob/master/nova/tests/functional/db/test_resource_provider.py#L2865","commit_id":"d07b7a7adf8c8a367fad56e5d772c4b4cd0ad6a4"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"6c15f7378ae1f85688ac2240635bf846c3076006","unresolved":false,"context_lines":[{"line_number":2612,"context_line":"        # resources and are related to a provider that is sharing some"},{"line_number":2613,"context_line":"        # resources with it. In other words, this is the list of resource"},{"line_number":2614,"context_line":"        # provider IDs that are NOT sharing resources."},{"line_number":2615,"context_line":"        # NOTE(jaypipes): This assumes that callers of the GET"},{"line_number":2616,"context_line":"        # /allocation_candidates API call are only interested in getting back"},{"line_number":2617,"context_line":"        # results when there is at least one non-sharing provider of resources."},{"line_number":2618,"context_line":"        # This is the case for our only caller at the moment (nova-scheduler)."},{"line_number":2619,"context_line":"        # In the future, if another caller wants to use allocation candidates"},{"line_number":2620,"context_line":"        # for scheduling to sharing-only providers, we can remove this"}],"source_content_type":"text/x-python","patch_set":5,"id":"3f4b6375_bec2ed51","line":2617,"range":{"start_line":2615,"start_character":26,"end_line":2617,"end_character":79},"in_reply_to":"3f4b6375_5e241960","updated":"2017-11-03 00:52:22.000000000","message":"ok, acutally \u0027_get_all_with_shared\u0027 still can get the shared provider returned.","commit_id":"d07b7a7adf8c8a367fad56e5d772c4b4cd0ad6a4"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"1babcf0df227a48027b9574eac4d1e82eeea1883","unresolved":false,"context_lines":[{"line_number":2612,"context_line":"        # resources and are related to a provider that is sharing some"},{"line_number":2613,"context_line":"        # resources with it. In other words, this is the list of resource"},{"line_number":2614,"context_line":"        # provider IDs that are NOT sharing resources."},{"line_number":2615,"context_line":"        # NOTE(jaypipes): This assumes that callers of the GET"},{"line_number":2616,"context_line":"        # /allocation_candidates API call are only interested in getting back"},{"line_number":2617,"context_line":"        # results when there is at least one non-sharing provider of resources."},{"line_number":2618,"context_line":"        # This is the case for our only caller at the moment (nova-scheduler)."},{"line_number":2619,"context_line":"        # In the future, if another caller wants to use allocation candidates"},{"line_number":2620,"context_line":"        # for scheduling to sharing-only providers, we can remove this"}],"source_content_type":"text/x-python","patch_set":5,"id":"3f4b6375_30605acf","line":2617,"range":{"start_line":2615,"start_character":26,"end_line":2617,"end_character":79},"in_reply_to":"3f4b6375_bec2ed51","updated":"2017-11-03 14:41:03.000000000","message":"right.","commit_id":"d07b7a7adf8c8a367fad56e5d772c4b4cd0ad6a4"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"e4fed929cd0fede9c688b68fa9725a6d4124ff7a","unresolved":false,"context_lines":[{"line_number":2437,"context_line":"    :param resources: A dict, keyed by resource class ID, of the amount"},{"line_number":2438,"context_line":"                      requested of that resource class."},{"line_number":2439,"context_line":"    \"\"\""},{"line_number":2440,"context_line":"    rpt \u003d sa.alias(_RP_TBL, name\u003d\"rp\")"},{"line_number":2441,"context_line":""},{"line_number":2442,"context_line":"    rc_name_map \u003d {"},{"line_number":2443,"context_line":"        rc_id: _RC_CACHE.string_from_id(rc_id).lower()"},{"line_number":2444,"context_line":"        for rc_id in resources.keys()"},{"line_number":2445,"context_line":"    }"},{"line_number":2446,"context_line":""},{"line_number":2447,"context_line":"    # Dict, keyed by resource class ID, of an aliased table object for the"},{"line_number":2448,"context_line":"    # inventories table winnowed to only that resource class."},{"line_number":2449,"context_line":"    inv_tables \u003d {"},{"line_number":2450,"context_line":"        rc_id: sa.alias(_INV_TBL, name\u003d\u0027inv_%s\u0027 % rc_name_map[rc_id])"},{"line_number":2451,"context_line":"        for rc_id in resources.keys()"},{"line_number":2452,"context_line":"    }"},{"line_number":2453,"context_line":""},{"line_number":2454,"context_line":"    # Dict, keyed by resource class ID, of a derived table (subquery in the"},{"line_number":2455,"context_line":"    # FROM clause or JOIN) against the allocations table winnowed to only that"},{"line_number":2456,"context_line":"    # resource class, grouped by resource provider."},{"line_number":2457,"context_line":"    usage_tables \u003d {"},{"line_number":2458,"context_line":"        rc_id: sa.alias("},{"line_number":2459,"context_line":"            sa.select(["},{"line_number":2460,"context_line":"                _ALLOC_TBL.c.resource_provider_id,"},{"line_number":2461,"context_line":"                sql.func.sum(_ALLOC_TBL.c.used).label(\u0027used\u0027),"},{"line_number":2462,"context_line":"            ]).where("},{"line_number":2463,"context_line":"                _ALLOC_TBL.c.resource_class_id \u003d\u003d rc_id"},{"line_number":2464,"context_line":"            ).group_by("},{"line_number":2465,"context_line":"                _ALLOC_TBL.c.resource_provider_id"},{"line_number":2466,"context_line":"            ),"},{"line_number":2467,"context_line":"            name\u003d\u0027usage_%s\u0027 % rc_name_map[rc_id],"},{"line_number":2468,"context_line":"        )"},{"line_number":2469,"context_line":"        for rc_id in resources.keys()"},{"line_number":2470,"context_line":"    }"},{"line_number":2471,"context_line":""},{"line_number":2472,"context_line":"    sel \u003d sa.select([rpt.c.id])"},{"line_number":2473,"context_line":""},{"line_number":2474,"context_line":"    # List of the WHERE conditions we build up by iterating over the requested"},{"line_number":2475,"context_line":"    # resources"},{"line_number":2476,"context_line":"    where_conds \u003d []"},{"line_number":2477,"context_line":""},{"line_number":2478,"context_line":"    # The chain of joins that we eventually pass to select_from()"},{"line_number":2479,"context_line":"    join_chain \u003d rpt"},{"line_number":2480,"context_line":""},{"line_number":2481,"context_line":"    for rc_id, amount in resources.items():"},{"line_number":2482,"context_line":"        inv_by_rc \u003d inv_tables[rc_id]"},{"line_number":2483,"context_line":"        usage_by_rc \u003d usage_tables[rc_id]"},{"line_number":2484,"context_line":""},{"line_number":2485,"context_line":"        # We can do a more efficient INNER JOIN because we don\u0027t have shared"},{"line_number":2486,"context_line":"        # resource providers to deal with"},{"line_number":2487,"context_line":"        rp_inv_join \u003d sa.join("},{"line_number":2488,"context_line":"            join_chain, inv_by_rc,"},{"line_number":2489,"context_line":"            sa.and_("},{"line_number":2490,"context_line":"                inv_by_rc.c.resource_provider_id \u003d\u003d rpt.c.id,"},{"line_number":2491,"context_line":"                # Add a join condition winnowing this copy of inventories table"},{"line_number":2492,"context_line":"                # to only the resource class being analyzed in this loop..."},{"line_number":2493,"context_line":"                inv_by_rc.c.resource_class_id \u003d\u003d rc_id,"},{"line_number":2494,"context_line":"            ),"},{"line_number":2495,"context_line":"        )"},{"line_number":2496,"context_line":"        rp_inv_usage_join \u003d sa.outerjoin("},{"line_number":2497,"context_line":"            rp_inv_join, usage_by_rc,"},{"line_number":2498,"context_line":"            inv_by_rc.c.resource_provider_id \u003d\u003d"},{"line_number":2499,"context_line":"                usage_by_rc.c.resource_provider_id,"},{"line_number":2500,"context_line":"        )"},{"line_number":2501,"context_line":"        join_chain \u003d rp_inv_usage_join"},{"line_number":2502,"context_line":""},{"line_number":2503,"context_line":"        usage_cond \u003d sa.and_("},{"line_number":2504,"context_line":"            ("},{"line_number":2505,"context_line":"            (sql.func.coalesce(usage_by_rc.c.used, 0) + amount) \u003c\u003d"},{"line_number":2506,"context_line":"            (inv_by_rc.c.total - inv_by_rc.c.reserved) *"},{"line_number":2507,"context_line":"                inv_by_rc.c.allocation_ratio"},{"line_number":2508,"context_line":"            ),"},{"line_number":2509,"context_line":"            inv_by_rc.c.min_unit \u003c\u003d amount,"},{"line_number":2510,"context_line":"            inv_by_rc.c.max_unit \u003e\u003d amount,"},{"line_number":2511,"context_line":"            amount % inv_by_rc.c.step_size \u003d\u003d 0,"},{"line_number":2512,"context_line":"        )"},{"line_number":2513,"context_line":"        where_conds.append(usage_cond)"},{"line_number":2514,"context_line":""},{"line_number":2515,"context_line":"    sel \u003d sel.select_from(join_chain)"},{"line_number":2516,"context_line":"    sel \u003d sel.where(sa.and_(*where_conds))"},{"line_number":2517,"context_line":""},{"line_number":2518,"context_line":"    return [r[0] for r in ctx.session.execute(sel)]"},{"line_number":2519,"context_line":""},{"line_number":2520,"context_line":""},{"line_number":2521,"context_line":"@base.NovaObjectRegistry.register_if(False)"}],"source_content_type":"text/x-python","patch_set":6,"id":"1f485f77_a6ef28e8","line":2518,"range":{"start_line":2440,"start_character":0,"end_line":2518,"end_character":51},"updated":"2017-11-13 03:08:19.000000000","message":"I found a better performance SQL for this, we needn\u0027t join the times same as the number of requested resources.\n\nI tested it in the 1w nodes, and 17 VMs per nodes, probably 5w records in the DB.\n\nThe multiple joins version SQL spends 7.2 seconds.\nThe version I tried spends 6.3 seconds.\n\nThe SQL as below:\n\nselect rp.id, sum(invs.resource_class_id) as res_count\nfrom resource_providers as rp\njoin inventories as invs\non rp.id \u003d invs.resource_provider_id\njoin (\n\tselect alloc.resource_provider_id, alloc.resource_class_id, sum(used) as used\n\tfrom allocations as alloc\n\tgroup by alloc.resource_provider_id, alloc.resource_class_id\n) as usages\non invs.resource_provider_id \u003d usages.resource_provider_id and usages.resource_class_id \u003d invs.resource_class_id\nwhere (\n\tinvs.resource_class_id \u003d 0 and\n\tCOALESCE(usages.used, 0) + 16 \u003c\u003d (invs.total - invs.reserved) * invs.allocation_ratio and 16 % invs.step_size \u003d 0 and 16 \u003e invs.min_unit and 16 \u003c invs.max_unit\n)\nor\n(\n\tinvs.resource_class_id \u003d 1 and\n\tCOALESCE(usages.used, 0) + 2048 \u003c\u003d (invs.total - invs.reserved) * invs.allocation_ratio and 2048 % invs.step_size \u003d 0 and 2048 \u003e invs.min_unit and 2048 \u003c invs.max_unit\n)\nor (\n\tinvs.resource_class_id \u003d 2 and\n\tCOALESCE(usages.used, 0) + 16 \u003c\u003d (invs.total - invs.reserved) * invs.allocation_ratio and 16 % invs.step_size \u003d 0 and 16 \u003e invs.min_unit and 16 \u003c invs.max_unit\n)\ngroup by rp.id\nhaving res_count \u003d 3","commit_id":"a4697032f11433b5105ba72764936179db9447dd"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"71e5c0b654f3df55615d076e4f14739c84ceeffa","unresolved":false,"context_lines":[{"line_number":2437,"context_line":"    :param resources: A dict, keyed by resource class ID, of the amount"},{"line_number":2438,"context_line":"                      requested of that resource class."},{"line_number":2439,"context_line":"    \"\"\""},{"line_number":2440,"context_line":"    rpt \u003d sa.alias(_RP_TBL, name\u003d\"rp\")"},{"line_number":2441,"context_line":""},{"line_number":2442,"context_line":"    rc_name_map \u003d {"},{"line_number":2443,"context_line":"        rc_id: _RC_CACHE.string_from_id(rc_id).lower()"},{"line_number":2444,"context_line":"        for rc_id in resources.keys()"},{"line_number":2445,"context_line":"    }"},{"line_number":2446,"context_line":""},{"line_number":2447,"context_line":"    # Dict, keyed by resource class ID, of an aliased table object for the"},{"line_number":2448,"context_line":"    # inventories table winnowed to only that resource class."},{"line_number":2449,"context_line":"    inv_tables \u003d {"},{"line_number":2450,"context_line":"        rc_id: sa.alias(_INV_TBL, name\u003d\u0027inv_%s\u0027 % rc_name_map[rc_id])"},{"line_number":2451,"context_line":"        for rc_id in resources.keys()"},{"line_number":2452,"context_line":"    }"},{"line_number":2453,"context_line":""},{"line_number":2454,"context_line":"    # Dict, keyed by resource class ID, of a derived table (subquery in the"},{"line_number":2455,"context_line":"    # FROM clause or JOIN) against the allocations table winnowed to only that"},{"line_number":2456,"context_line":"    # resource class, grouped by resource provider."},{"line_number":2457,"context_line":"    usage_tables \u003d {"},{"line_number":2458,"context_line":"        rc_id: sa.alias("},{"line_number":2459,"context_line":"            sa.select(["},{"line_number":2460,"context_line":"                _ALLOC_TBL.c.resource_provider_id,"},{"line_number":2461,"context_line":"                sql.func.sum(_ALLOC_TBL.c.used).label(\u0027used\u0027),"},{"line_number":2462,"context_line":"            ]).where("},{"line_number":2463,"context_line":"                _ALLOC_TBL.c.resource_class_id \u003d\u003d rc_id"},{"line_number":2464,"context_line":"            ).group_by("},{"line_number":2465,"context_line":"                _ALLOC_TBL.c.resource_provider_id"},{"line_number":2466,"context_line":"            ),"},{"line_number":2467,"context_line":"            name\u003d\u0027usage_%s\u0027 % rc_name_map[rc_id],"},{"line_number":2468,"context_line":"        )"},{"line_number":2469,"context_line":"        for rc_id in resources.keys()"},{"line_number":2470,"context_line":"    }"},{"line_number":2471,"context_line":""},{"line_number":2472,"context_line":"    sel \u003d sa.select([rpt.c.id])"},{"line_number":2473,"context_line":""},{"line_number":2474,"context_line":"    # List of the WHERE conditions we build up by iterating over the requested"},{"line_number":2475,"context_line":"    # resources"},{"line_number":2476,"context_line":"    where_conds \u003d []"},{"line_number":2477,"context_line":""},{"line_number":2478,"context_line":"    # The chain of joins that we eventually pass to select_from()"},{"line_number":2479,"context_line":"    join_chain \u003d rpt"},{"line_number":2480,"context_line":""},{"line_number":2481,"context_line":"    for rc_id, amount in resources.items():"},{"line_number":2482,"context_line":"        inv_by_rc \u003d inv_tables[rc_id]"},{"line_number":2483,"context_line":"        usage_by_rc \u003d usage_tables[rc_id]"},{"line_number":2484,"context_line":""},{"line_number":2485,"context_line":"        # We can do a more efficient INNER JOIN because we don\u0027t have shared"},{"line_number":2486,"context_line":"        # resource providers to deal with"},{"line_number":2487,"context_line":"        rp_inv_join \u003d sa.join("},{"line_number":2488,"context_line":"            join_chain, inv_by_rc,"},{"line_number":2489,"context_line":"            sa.and_("},{"line_number":2490,"context_line":"                inv_by_rc.c.resource_provider_id \u003d\u003d rpt.c.id,"},{"line_number":2491,"context_line":"                # Add a join condition winnowing this copy of inventories table"},{"line_number":2492,"context_line":"                # to only the resource class being analyzed in this loop..."},{"line_number":2493,"context_line":"                inv_by_rc.c.resource_class_id \u003d\u003d rc_id,"},{"line_number":2494,"context_line":"            ),"},{"line_number":2495,"context_line":"        )"},{"line_number":2496,"context_line":"        rp_inv_usage_join \u003d sa.outerjoin("},{"line_number":2497,"context_line":"            rp_inv_join, usage_by_rc,"},{"line_number":2498,"context_line":"            inv_by_rc.c.resource_provider_id \u003d\u003d"},{"line_number":2499,"context_line":"                usage_by_rc.c.resource_provider_id,"},{"line_number":2500,"context_line":"        )"},{"line_number":2501,"context_line":"        join_chain \u003d rp_inv_usage_join"},{"line_number":2502,"context_line":""},{"line_number":2503,"context_line":"        usage_cond \u003d sa.and_("},{"line_number":2504,"context_line":"            ("},{"line_number":2505,"context_line":"            (sql.func.coalesce(usage_by_rc.c.used, 0) + amount) \u003c\u003d"},{"line_number":2506,"context_line":"            (inv_by_rc.c.total - inv_by_rc.c.reserved) *"},{"line_number":2507,"context_line":"                inv_by_rc.c.allocation_ratio"},{"line_number":2508,"context_line":"            ),"},{"line_number":2509,"context_line":"            inv_by_rc.c.min_unit \u003c\u003d amount,"},{"line_number":2510,"context_line":"            inv_by_rc.c.max_unit \u003e\u003d amount,"},{"line_number":2511,"context_line":"            amount % inv_by_rc.c.step_size \u003d\u003d 0,"},{"line_number":2512,"context_line":"        )"},{"line_number":2513,"context_line":"        where_conds.append(usage_cond)"},{"line_number":2514,"context_line":""},{"line_number":2515,"context_line":"    sel \u003d sel.select_from(join_chain)"},{"line_number":2516,"context_line":"    sel \u003d sel.where(sa.and_(*where_conds))"},{"line_number":2517,"context_line":""},{"line_number":2518,"context_line":"    return [r[0] for r in ctx.session.execute(sel)]"},{"line_number":2519,"context_line":""},{"line_number":2520,"context_line":""},{"line_number":2521,"context_line":"@base.NovaObjectRegistry.register_if(False)"}],"source_content_type":"text/x-python","patch_set":6,"id":"1f485f77_9bf53a86","line":2518,"range":{"start_line":2440,"start_character":0,"end_line":2518,"end_character":51},"in_reply_to":"1f485f77_a6ef28e8","updated":"2017-11-14 21:01:54.000000000","message":"Suggest proposing this as a separate patch on top of this series.","commit_id":"a4697032f11433b5105ba72764936179db9447dd"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"9c970fbdfa825ce5cef32a7735ef7090521040de","unresolved":false,"context_lines":[{"line_number":2612,"context_line":"        # resources and are related to a provider that is sharing some"},{"line_number":2613,"context_line":"        # resources with it. In other words, this is the list of resource"},{"line_number":2614,"context_line":"        # provider IDs that are NOT sharing resources."},{"line_number":2615,"context_line":"        # NOTE(jaypipes): This assumes that callers of the GET"},{"line_number":2616,"context_line":"        # /allocation_candidates API call are only interested in getting back"},{"line_number":2617,"context_line":"        # results when there is at least one non-sharing provider of resources."},{"line_number":2618,"context_line":"        # This is the case for our only caller at the moment (nova-scheduler)."},{"line_number":2619,"context_line":"        # In the future, if another caller wants to use allocation candidates"},{"line_number":2620,"context_line":"        # for scheduling to sharing-only providers, we can remove this"},{"line_number":2621,"context_line":"        # short-circuit."},{"line_number":2622,"context_line":"        if not non_sharing_rp_ids:"},{"line_number":2623,"context_line":"            return [], []"},{"line_number":2624,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"3f4b6375_088a8ebd","line":2621,"range":{"start_line":2615,"start_character":26,"end_line":2621,"end_character":24},"updated":"2017-11-08 06:04:27.000000000","message":"I referred to this comment. This comment said if we want to enable the case \"request sharing-only providers\", we can remove the check in the line 2622. But actually that case is supported by the current implement, it isn\u0027t blocked by the check at line 2622. So the comment doesn\u0027t say something true?","commit_id":"a4697032f11433b5105ba72764936179db9447dd"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"f5ce61b8a98962b6cfb57b01c190dc3553c882a9","unresolved":false,"context_lines":[{"line_number":2612,"context_line":"        # resources and are related to a provider that is sharing some"},{"line_number":2613,"context_line":"        # resources with it. In other words, this is the list of resource"},{"line_number":2614,"context_line":"        # provider IDs that are NOT sharing resources."},{"line_number":2615,"context_line":"        # NOTE(jaypipes): This assumes that callers of the GET"},{"line_number":2616,"context_line":"        # /allocation_candidates API call are only interested in getting back"},{"line_number":2617,"context_line":"        # results when there is at least one non-sharing provider of resources."},{"line_number":2618,"context_line":"        # This is the case for our only caller at the moment (nova-scheduler)."},{"line_number":2619,"context_line":"        # In the future, if another caller wants to use allocation candidates"},{"line_number":2620,"context_line":"        # for scheduling to sharing-only providers, we can remove this"},{"line_number":2621,"context_line":"        # short-circuit."},{"line_number":2622,"context_line":"        if not non_sharing_rp_ids:"},{"line_number":2623,"context_line":"            return [], []"},{"line_number":2624,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"3f4b6375_35ec6f8e","line":2621,"range":{"start_line":2615,"start_character":26,"end_line":2621,"end_character":24},"in_reply_to":"3f4b6375_088a8ebd","updated":"2017-11-08 22:44:30.000000000","message":"No, the above comment is true. If we want AllocationCandidates.get_by_filters() to return allocation requests that only contain sharing providers and do not contain any non-sharing providers, then we would need to remove line 2622-2623.","commit_id":"a4697032f11433b5105ba72764936179db9447dd"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"5ec69c21f2c73dc449f849ca3549ddb412c42032","unresolved":false,"context_lines":[{"line_number":2612,"context_line":"        # resources and are related to a provider that is sharing some"},{"line_number":2613,"context_line":"        # resources with it. In other words, this is the list of resource"},{"line_number":2614,"context_line":"        # provider IDs that are NOT sharing resources."},{"line_number":2615,"context_line":"        # NOTE(jaypipes): This assumes that callers of the GET"},{"line_number":2616,"context_line":"        # /allocation_candidates API call are only interested in getting back"},{"line_number":2617,"context_line":"        # results when there is at least one non-sharing provider of resources."},{"line_number":2618,"context_line":"        # This is the case for our only caller at the moment (nova-scheduler)."},{"line_number":2619,"context_line":"        # In the future, if another caller wants to use allocation candidates"},{"line_number":2620,"context_line":"        # for scheduling to sharing-only providers, we can remove this"},{"line_number":2621,"context_line":"        # short-circuit."},{"line_number":2622,"context_line":"        if not non_sharing_rp_ids:"},{"line_number":2623,"context_line":"            return [], []"},{"line_number":2624,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"3f4b6375_76af8e7d","line":2621,"range":{"start_line":2615,"start_character":26,"end_line":2621,"end_character":24},"in_reply_to":"3f4b6375_35ec6f8e","updated":"2017-11-09 01:47:40.000000000","message":"No, we pass this testcase https://github.com/openstack/nova/blob/master/nova/tests/functional/db/test_resource_provider.py#L2861","commit_id":"a4697032f11433b5105ba72764936179db9447dd"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"6b04bebe8123b014ebd67bfc5723e1a84286d4a6","unresolved":false,"context_lines":[{"line_number":2612,"context_line":"        # resources and are related to a provider that is sharing some"},{"line_number":2613,"context_line":"        # resources with it. In other words, this is the list of resource"},{"line_number":2614,"context_line":"        # provider IDs that are NOT sharing resources."},{"line_number":2615,"context_line":"        # NOTE(jaypipes): This assumes that callers of the GET"},{"line_number":2616,"context_line":"        # /allocation_candidates API call are only interested in getting back"},{"line_number":2617,"context_line":"        # results when there is at least one non-sharing provider of resources."},{"line_number":2618,"context_line":"        # This is the case for our only caller at the moment (nova-scheduler)."},{"line_number":2619,"context_line":"        # In the future, if another caller wants to use allocation candidates"},{"line_number":2620,"context_line":"        # for scheduling to sharing-only providers, we can remove this"},{"line_number":2621,"context_line":"        # short-circuit."},{"line_number":2622,"context_line":"        if not non_sharing_rp_ids:"},{"line_number":2623,"context_line":"            return [], []"},{"line_number":2624,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"3f4b6375_9908fd91","line":2621,"range":{"start_line":2615,"start_character":26,"end_line":2621,"end_character":24},"in_reply_to":"3f4b6375_76af8e7d","updated":"2017-11-09 03:14:52.000000000","message":":( Hmm. I see. That\u0027s not good. I\u0027ll have a look into this in the morning.","commit_id":"a4697032f11433b5105ba72764936179db9447dd"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"71e5c0b654f3df55615d076e4f14739c84ceeffa","unresolved":false,"context_lines":[{"line_number":2612,"context_line":"        # resources and are related to a provider that is sharing some"},{"line_number":2613,"context_line":"        # resources with it. In other words, this is the list of resource"},{"line_number":2614,"context_line":"        # provider IDs that are NOT sharing resources."},{"line_number":2615,"context_line":"        # NOTE(jaypipes): This assumes that callers of the GET"},{"line_number":2616,"context_line":"        # /allocation_candidates API call are only interested in getting back"},{"line_number":2617,"context_line":"        # results when there is at least one non-sharing provider of resources."},{"line_number":2618,"context_line":"        # This is the case for our only caller at the moment (nova-scheduler)."},{"line_number":2619,"context_line":"        # In the future, if another caller wants to use allocation candidates"},{"line_number":2620,"context_line":"        # for scheduling to sharing-only providers, we can remove this"},{"line_number":2621,"context_line":"        # short-circuit."},{"line_number":2622,"context_line":"        if not non_sharing_rp_ids:"},{"line_number":2623,"context_line":"            return [], []"},{"line_number":2624,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"1f485f77_bbd116fe","line":2621,"range":{"start_line":2615,"start_character":26,"end_line":2621,"end_character":24},"in_reply_to":"3f4b6375_9908fd91","updated":"2017-11-14 21:01:54.000000000","message":"I removed the check (and the comment) and all existing tests still pass.  Since we decided this is ultimately the desired behavior anyway, I\u0027m okay letting the mystery lie.","commit_id":"a4697032f11433b5105ba72764936179db9447dd"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"1366c7d581a8ab61118d1dee4c0e98e255e25655","unresolved":false,"context_lines":[{"line_number":2612,"context_line":"        # non_sharing_rp_ids contains a list of resource provider IDs that"},{"line_number":2613,"context_line":"        # EITHER have all the requested resources themselves OR have some"},{"line_number":2614,"context_line":"        # resources and are related to a provider that is sharing some"},{"line_number":2615,"context_line":"        # resources with it. In other words, this is the list of resource"},{"line_number":2616,"context_line":"        # provider IDs that are NOT sharing resources."},{"line_number":2617,"context_line":""},{"line_number":2618,"context_line":"        # We need to grab usage information for all the providers identified as"},{"line_number":2619,"context_line":"        # potentially fulfilling part of the resource request. This includes"}],"source_content_type":"text/x-python","patch_set":9,"id":"1f485f77_5911f351","line":2616,"range":{"start_line":2615,"start_character":45,"end_line":2616,"end_character":54},"updated":"2017-11-15 13:34:33.000000000","message":"This isn\u0027t true also. When we only request shared resource, non_sharing_rp_ids include the RPs which have the shared resource. That is why we can pass that test.\n\nThat also means that the naming of \"non_sharing_rp_ids\" doesn\u0027t correct also.","commit_id":"dc2d66f4e3bd26f2656a47b154d638dd9d8e024b"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"8b3cabf2463c6b46b1d95cfd26c0cc61e88b378c","unresolved":false,"context_lines":[{"line_number":2612,"context_line":"        # non_sharing_rp_ids contains a list of resource provider IDs that"},{"line_number":2613,"context_line":"        # EITHER have all the requested resources themselves OR have some"},{"line_number":2614,"context_line":"        # resources and are related to a provider that is sharing some"},{"line_number":2615,"context_line":"        # resources with it. In other words, this is the list of resource"},{"line_number":2616,"context_line":"        # provider IDs that are NOT sharing resources."},{"line_number":2617,"context_line":""},{"line_number":2618,"context_line":"        # We need to grab usage information for all the providers identified as"},{"line_number":2619,"context_line":"        # potentially fulfilling part of the resource request. This includes"}],"source_content_type":"text/x-python","patch_set":9,"id":"1f485f77_67688ab8","line":2616,"range":{"start_line":2615,"start_character":45,"end_line":2616,"end_character":54},"in_reply_to":"1f485f77_5911f351","updated":"2017-11-15 14:53:43.000000000","message":"Based on the (updated) test cases and the logic above, it *should* contain only non-sharing RP IDs.  Seems like there\u0027s still a \"bug\" somewhere (quotes because it\u0027s nevertheless behaving the way we want it to), but I don\u0027t think it\u0027s here.","commit_id":"dc2d66f4e3bd26f2656a47b154d638dd9d8e024b"}],"nova/tests/functional/db/test_allocation_candidates.py":[{"author":{"_account_id":25625,"name":"Tetsuro Nakamura","email":"tetsuro.nakamura.bc@hco.ntt.co.jp","username":"tetsuro0907"},"change_message_id":"aa6f2d232f6d1c2ef6549115791045ae3baafd29","unresolved":false,"context_lines":[{"line_number":216,"context_line":"                                fields.ResourceClass.MEMORY_MB, 1040)"},{"line_number":217,"context_line":"        # Allocation ratio math"},{"line_number":218,"context_line":"        _add_inventory(excl_extra_avail, fields.ResourceClass.DISK_GB, 2000,"},{"line_number":219,"context_line":"                       allocation_ration\u003d0.5)"},{"line_number":220,"context_line":"        _add_inventory(excl_extra_avail, fields.ResourceClass.IPV4_ADDRESS, 48)"},{"line_number":221,"context_line":"        custom_special \u003d rp_obj.ResourceClass(self.ctx, name\u003d\u0027CUSTOM_SPECIAL\u0027)"},{"line_number":222,"context_line":"        custom_special.create()"}],"source_content_type":"text/x-python","patch_set":7,"id":"1f485f77_f56e8994","line":219,"range":{"start_line":219,"start_character":34,"end_line":219,"end_character":40},"updated":"2017-11-14 12:54:38.000000000","message":"ratio","commit_id":"e65057c95e0cb198c2a158c59305632fdfc0f687"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"71e5c0b654f3df55615d076e4f14739c84ceeffa","unresolved":false,"context_lines":[{"line_number":216,"context_line":"                                fields.ResourceClass.MEMORY_MB, 1040)"},{"line_number":217,"context_line":"        # Allocation ratio math"},{"line_number":218,"context_line":"        _add_inventory(excl_extra_avail, fields.ResourceClass.DISK_GB, 2000,"},{"line_number":219,"context_line":"                       allocation_ration\u003d0.5)"},{"line_number":220,"context_line":"        _add_inventory(excl_extra_avail, fields.ResourceClass.IPV4_ADDRESS, 48)"},{"line_number":221,"context_line":"        custom_special \u003d rp_obj.ResourceClass(self.ctx, name\u003d\u0027CUSTOM_SPECIAL\u0027)"},{"line_number":222,"context_line":"        custom_special.create()"}],"source_content_type":"text/x-python","patch_set":7,"id":"1f485f77_fb578e01","line":219,"range":{"start_line":219,"start_character":34,"end_line":219,"end_character":40},"in_reply_to":"1f485f77_f56e8994","updated":"2017-11-14 21:01:54.000000000","message":"Good catch; done.","commit_id":"e65057c95e0cb198c2a158c59305632fdfc0f687"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"abe91d27a37af244d1a4da95c6f71f6d680926d5","unresolved":false,"context_lines":[{"line_number":83,"context_line":"        self.useFixture(fixtures.Database())"},{"line_number":84,"context_line":"        self.api_db \u003d self.useFixture(fixtures.Database(database\u003d\u0027api\u0027))"},{"line_number":85,"context_line":"        self.ctx \u003d context.RequestContext(\u0027fake-user\u0027, \u0027fake-project\u0027)"},{"line_number":86,"context_line":"        self.requested_resources \u003d {"},{"line_number":87,"context_line":"            fields.ResourceClass.VCPU: 1,"},{"line_number":88,"context_line":"            fields.ResourceClass.MEMORY_MB: 64,"},{"line_number":89,"context_line":"            fields.ResourceClass.DISK_GB: 1500,"}],"source_content_type":"text/x-python","patch_set":10,"id":"1f485f77_f2b2c348","line":86,"updated":"2017-11-17 00:18:55.000000000","message":"This isn\u0027t used in test_get_provider_ids_matching_all but when I was reading the test, until I got to the end, I was expecting it to be. Should you remove it from this base class and leave it in the child class where it is used?","commit_id":"039c94a6b98546573f34e0dc9c0a7cd6d84caa5f"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"895fab67ec64d342ac2fbd0f8f738a1a684bd62a","unresolved":false,"context_lines":[{"line_number":83,"context_line":"        self.useFixture(fixtures.Database())"},{"line_number":84,"context_line":"        self.api_db \u003d self.useFixture(fixtures.Database(database\u003d\u0027api\u0027))"},{"line_number":85,"context_line":"        self.ctx \u003d context.RequestContext(\u0027fake-user\u0027, \u0027fake-project\u0027)"},{"line_number":86,"context_line":"        self.requested_resources \u003d {"},{"line_number":87,"context_line":"            fields.ResourceClass.VCPU: 1,"},{"line_number":88,"context_line":"            fields.ResourceClass.MEMORY_MB: 64,"},{"line_number":89,"context_line":"            fields.ResourceClass.DISK_GB: 1500,"}],"source_content_type":"text/x-python","patch_set":10,"id":"1f485f77_72dff339","line":86,"in_reply_to":"1f485f77_f2b2c348","updated":"2017-11-17 00:36:02.000000000","message":"You\u0027re right.  See below.","commit_id":"039c94a6b98546573f34e0dc9c0a7cd6d84caa5f"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"abe91d27a37af244d1a4da95c6f71f6d680926d5","unresolved":false,"context_lines":[{"line_number":109,"context_line":"        self._create_provider(\u0027no_inventory\u0027)"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"        # Inventory of adequate CPU and memory, no allocations against it."},{"line_number":112,"context_line":"        excl_big_cm_noalloc \u003d self._create_provider(\u0027big_cm_noalloc\u0027)"},{"line_number":113,"context_line":"        _add_inventory(excl_big_cm_noalloc, fields.ResourceClass.VCPU, 15)"},{"line_number":114,"context_line":"        _add_inventory(excl_big_cm_noalloc, fields.ResourceClass.MEMORY_MB,"},{"line_number":115,"context_line":"                       4096, max_unit\u003d2048)"}],"source_content_type":"text/x-python","patch_set":10,"id":"1f485f77_5242b73f","line":112,"range":{"start_line":112,"start_character":8,"end_line":112,"end_character":27},"updated":"2017-11-17 00:18:55.000000000","message":"Why is this excl but the next one is incl? Because no DISK_GB inventory?","commit_id":"039c94a6b98546573f34e0dc9c0a7cd6d84caa5f"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"895fab67ec64d342ac2fbd0f8f738a1a684bd62a","unresolved":false,"context_lines":[{"line_number":109,"context_line":"        self._create_provider(\u0027no_inventory\u0027)"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"        # Inventory of adequate CPU and memory, no allocations against it."},{"line_number":112,"context_line":"        excl_big_cm_noalloc \u003d self._create_provider(\u0027big_cm_noalloc\u0027)"},{"line_number":113,"context_line":"        _add_inventory(excl_big_cm_noalloc, fields.ResourceClass.VCPU, 15)"},{"line_number":114,"context_line":"        _add_inventory(excl_big_cm_noalloc, fields.ResourceClass.MEMORY_MB,"},{"line_number":115,"context_line":"                       4096, max_unit\u003d2048)"}],"source_content_type":"text/x-python","patch_set":10,"id":"1f485f77_12ee7fec","line":112,"range":{"start_line":112,"start_character":8,"end_line":112,"end_character":27},"in_reply_to":"1f485f77_5242b73f","updated":"2017-11-17 00:36:02.000000000","message":"Correct.","commit_id":"039c94a6b98546573f34e0dc9c0a7cd6d84caa5f"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"abe91d27a37af244d1a4da95c6f71f6d680926d5","unresolved":false,"context_lines":[{"line_number":123,"context_line":""},{"line_number":124,"context_line":"        # No allocations, but inventory unusable.  Try to hit all the possible"},{"line_number":125,"context_line":"        # reasons for exclusion."},{"line_number":126,"context_line":"        # VCPU min_unit too high"},{"line_number":127,"context_line":"        excl_badinv_min_unit \u003d self._create_provider(\u0027badinv_min_unit\u0027)"},{"line_number":128,"context_line":"        _add_inventory(excl_badinv_min_unit, fields.ResourceClass.VCPU, 12,"},{"line_number":129,"context_line":"                       min_unit\u003d6)"}],"source_content_type":"text/x-python","patch_set":10,"id":"1f485f77_f2440349","line":126,"updated":"2017-11-17 00:18:55.000000000","message":"This is helpful.","commit_id":"039c94a6b98546573f34e0dc9c0a7cd6d84caa5f"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"abe91d27a37af244d1a4da95c6f71f6d680926d5","unresolved":false,"context_lines":[{"line_number":249,"context_line":"    resources against providers."},{"line_number":250,"context_line":"    \"\"\""},{"line_number":251,"context_line":""},{"line_number":252,"context_line":"    def setUp(self):"},{"line_number":253,"context_line":"        super(AllocationCandidatesTestCase, self).setUp()"},{"line_number":254,"context_line":"        self.requested_resources \u003d {"},{"line_number":255,"context_line":"            fields.ResourceClass.VCPU: 1,"},{"line_number":256,"context_line":"            fields.ResourceClass.MEMORY_MB: 64,"},{"line_number":257,"context_line":"            fields.ResourceClass.DISK_GB: 1500,"},{"line_number":258,"context_line":"        }"},{"line_number":259,"context_line":"        # For debugging purposes, populated by _create_provider and used by"},{"line_number":260,"context_line":"        # _validate_allocation_requests to make failure results more readable."},{"line_number":261,"context_line":"        self.rp_uuid_to_name \u003d {}"},{"line_number":262,"context_line":""},{"line_number":263,"context_line":"    def _get_allocation_candidates(self, requests\u003dNone):"},{"line_number":264,"context_line":"        if requests is None:"}],"source_content_type":"text/x-python","patch_set":10,"id":"1f485f77_323a9bcb","line":261,"range":{"start_line":252,"start_character":4,"end_line":261,"end_character":33},"updated":"2017-11-17 00:18:55.000000000","message":"This is all in the parent class now, why not remove it?","commit_id":"039c94a6b98546573f34e0dc9c0a7cd6d84caa5f"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"895fab67ec64d342ac2fbd0f8f738a1a684bd62a","unresolved":false,"context_lines":[{"line_number":249,"context_line":"    resources against providers."},{"line_number":250,"context_line":"    \"\"\""},{"line_number":251,"context_line":""},{"line_number":252,"context_line":"    def setUp(self):"},{"line_number":253,"context_line":"        super(AllocationCandidatesTestCase, self).setUp()"},{"line_number":254,"context_line":"        self.requested_resources \u003d {"},{"line_number":255,"context_line":"            fields.ResourceClass.VCPU: 1,"},{"line_number":256,"context_line":"            fields.ResourceClass.MEMORY_MB: 64,"},{"line_number":257,"context_line":"            fields.ResourceClass.DISK_GB: 1500,"},{"line_number":258,"context_line":"        }"},{"line_number":259,"context_line":"        # For debugging purposes, populated by _create_provider and used by"},{"line_number":260,"context_line":"        # _validate_allocation_requests to make failure results more readable."},{"line_number":261,"context_line":"        self.rp_uuid_to_name \u003d {}"},{"line_number":262,"context_line":""},{"line_number":263,"context_line":"    def _get_allocation_candidates(self, requests\u003dNone):"},{"line_number":264,"context_line":"        if requests is None:"}],"source_content_type":"text/x-python","patch_set":10,"id":"1f485f77_f271a345","line":261,"range":{"start_line":252,"start_character":4,"end_line":261,"end_character":33},"in_reply_to":"1f485f77_323a9bcb","updated":"2017-11-17 00:36:02.000000000","message":"Yup, looked at the top of the series and it\u0027s still duplicated there.  I can remove it; but would you mind if I saved a 12-patch rebase and threw it in a new patch top?","commit_id":"039c94a6b98546573f34e0dc9c0a7cd6d84caa5f"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"4f30389527226c2cc115fbd098d707683a77f980","unresolved":false,"context_lines":[{"line_number":249,"context_line":"    resources against providers."},{"line_number":250,"context_line":"    \"\"\""},{"line_number":251,"context_line":""},{"line_number":252,"context_line":"    def setUp(self):"},{"line_number":253,"context_line":"        super(AllocationCandidatesTestCase, self).setUp()"},{"line_number":254,"context_line":"        self.requested_resources \u003d {"},{"line_number":255,"context_line":"            fields.ResourceClass.VCPU: 1,"},{"line_number":256,"context_line":"            fields.ResourceClass.MEMORY_MB: 64,"},{"line_number":257,"context_line":"            fields.ResourceClass.DISK_GB: 1500,"},{"line_number":258,"context_line":"        }"},{"line_number":259,"context_line":"        # For debugging purposes, populated by _create_provider and used by"},{"line_number":260,"context_line":"        # _validate_allocation_requests to make failure results more readable."},{"line_number":261,"context_line":"        self.rp_uuid_to_name \u003d {}"},{"line_number":262,"context_line":""},{"line_number":263,"context_line":"    def _get_allocation_candidates(self, requests\u003dNone):"},{"line_number":264,"context_line":"        if requests is None:"}],"source_content_type":"text/x-python","patch_set":10,"id":"1f485f77_70959486","line":261,"range":{"start_line":252,"start_character":4,"end_line":261,"end_character":33},"in_reply_to":"1f485f77_b2be8bb1","updated":"2017-11-17 21:04:01.000000000","message":"https://review.openstack.org/#/c/521189/","commit_id":"039c94a6b98546573f34e0dc9c0a7cd6d84caa5f"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"39febf1b21f6b8e75767cc0acf1320bc0dec2068","unresolved":false,"context_lines":[{"line_number":249,"context_line":"    resources against providers."},{"line_number":250,"context_line":"    \"\"\""},{"line_number":251,"context_line":""},{"line_number":252,"context_line":"    def setUp(self):"},{"line_number":253,"context_line":"        super(AllocationCandidatesTestCase, self).setUp()"},{"line_number":254,"context_line":"        self.requested_resources \u003d {"},{"line_number":255,"context_line":"            fields.ResourceClass.VCPU: 1,"},{"line_number":256,"context_line":"            fields.ResourceClass.MEMORY_MB: 64,"},{"line_number":257,"context_line":"            fields.ResourceClass.DISK_GB: 1500,"},{"line_number":258,"context_line":"        }"},{"line_number":259,"context_line":"        # For debugging purposes, populated by _create_provider and used by"},{"line_number":260,"context_line":"        # _validate_allocation_requests to make failure results more readable."},{"line_number":261,"context_line":"        self.rp_uuid_to_name \u003d {}"},{"line_number":262,"context_line":""},{"line_number":263,"context_line":"    def _get_allocation_candidates(self, requests\u003dNone):"},{"line_number":264,"context_line":"        if requests is None:"}],"source_content_type":"text/x-python","patch_set":10,"id":"1f485f77_b2be8bb1","line":261,"range":{"start_line":252,"start_character":4,"end_line":261,"end_character":33},"in_reply_to":"1f485f77_f271a345","updated":"2017-11-17 00:38:25.000000000","message":"Sure.","commit_id":"039c94a6b98546573f34e0dc9c0a7cd6d84caa5f"}]}
