def plotTrafgenThroughputComparisonDirs(dir2props_dict):

    units = 'Gb/s' if FOR_PAPER else 'Mb/s'
    div = 1000.0 if FOR_PAPER else 1

    fn_get_datapoint = lambda directory: getServerAvgTxRate(directory) / div
    yLabel = 'UDP throughput (%s)' % units
    title = '' if FOR_PAPER else 'Average UDP throughput'

    # Turn each directory's set of prop=val strings into a dictionary to
    # easily look up the value of a particular property for the directory
    dir2prop2val_dict = getDir2Prop2ValDict(dir2props_dict)

    # Make sure that all the experiments had the same number of client/server
    # machines and number of tenants.
    mctenants_vals = set()
    trafgentenants_vals = set()
    for directory in dir2props_dict.iterkeys():
        mctenants_vals.add(dir2prop2val_dict[directory]['mctenants'])
        trafgentenants_vals.add(dir2prop2val_dict[directory]['trafgentenants'])
    assert (len(mctenants_vals) == 1)
    assert (len(trafgentenants_vals) == 1)
    mctenants = int(mctenants_vals.pop())

    # Make sure that all the experiments had the same number of client and
    # server machines
    numclients_vals = set()
    numservers_vals = set()
    for directory in dir2props_dict.iterkeys():
        servers, clients = getServersAndClients(directory)
        numclients_vals.add(len(clients))
        numservers_vals.add(len(servers))
    assert (len(numclients_vals) == 1)
    assert (len(numservers_vals) == 1)
    numclients = numclients_vals.pop()

    # Function to convert mcrate value to total server load
    # fn_get_xgroup_value = functools.partial(serverLoadFromMcrate,
    #                                         mctenants = mctenants,
    #                                         numclients = numclients)
    # Load per tenant per client
    fn_get_xgroup_value = (
        lambda mcrate_val_set: int(getUniqueProp(mcrate_val_set)))

    return plotLineComparisonDirs(
        dir2props_dict,
        xgroup_props=['mcrate'],
        line_props=['rl'],
        fn_sort_lines=lambda lines: sortLineValSets(lines),
        fn_get_line_label=(
            lambda line_val_set: RL_LABEL[getUniqueProp(line_val_set)]),
        fn_get_xgroup_value=fn_get_xgroup_value,
        fn_get_datapoint=fn_get_datapoint,
        xLabel='Load per tenant per client (reqs/sec)',
        yLabel=yLabel,
        title=title,
        xLimits=LOAD_LIMITS,
        yLimits=THROUGHPUT_LIMITS,
        for_paper=FOR_PAPER)
def plotMcperfLatencyComparisonDirsWrapper(dir2props_dict, stat='avg'):

    units = 'msec' if FOR_PAPER else 'usec'
    div = 1000.0 if FOR_PAPER else 1

    # Available stat functions: 'avg', 'pc99', 'pc999'
    if stat == 'avg':
        fn_get_datapoint = lambda directory: getAvgLatency(directory) / div
        yLabel = 'Average latency (%s)' % units
        title = 'Memcached response latency (average)'
    elif stat == 'pc99':
        fn_get_datapoint = lambda directory: getpc99Latency(directory) / div
        yLabel = '99th perc. latency (%s)' % units
        title = 'Memcached response latency (99th percentile)'
    elif stat == 'pc999':
        fn_get_datapoint = lambda directory: getpc999Latency(directory) / div
        yLabel = '99.9th perc. latency (%s)' % units
        title = 'Memcached response latency (99.9th percentile)'

    if FOR_PAPER:
        title = ''

    # Turn each directory's set of prop=val strings into a dictionary to
    # easily look up the value of a particular property for the directory
    dir2prop2val_dict = getDir2Prop2ValDict(dir2props_dict)

    # Make sure that all the experiments had the same number of client/server
    # machines and number of tenants.
    mctenants_vals = set()
    trafgentenants_vals = set()
    for directory in dir2props_dict.iterkeys():
        mctenants_vals.add(dir2prop2val_dict[directory]['mctenants'])
        trafgentenants_vals.add(dir2prop2val_dict[directory]['trafgentenants'])
    assert(len(mctenants_vals) == 1)
    assert(len(trafgentenants_vals) == 1)
    mctenants = int(mctenants_vals.pop())

    # Make sure that all the experiments had the same number of client and
    # server machines
    numclients_vals = set()
    numservers_vals = set()
    for directory in dir2props_dict.iterkeys():
        servers, clients = getServersAndClients(directory)
        numclients_vals.add(len(clients))
        numservers_vals.add(len(servers))
    assert(len(numclients_vals) == 1)
    assert(len(numservers_vals) == 1)
    numclients = numclients_vals.pop()

    # Function to convert mcrate value to total server load
    # fn_get_xgroup_value = functools.partial(serverLoadFromMcrate,
    #                                         mctenants = mctenants,
    #                                         numclients = numclients)
    # Load per tenant per client
    fn_get_xgroup_value = (lambda mcrate_val_set:
        int(getUniqueProp(mcrate_val_set)))

    return plotLineComparisonDirs(
            dir2props_dict,

            xgroup_props = ['mcrate'],
            line_props = ['rl'],

            fn_sort_lines = lambda lines: sortLineValSets(lines),

            fn_get_line_label = (lambda line_val_set:
                RL_LABEL[getUniqueProp(line_val_set)]),

            fn_get_xgroup_value = fn_get_xgroup_value,

            fn_get_datapoint = fn_get_datapoint,

            xLabel = 'Load per tenant per client (reqs/sec)',
            yLabel = yLabel,
            title = title,
            xLimits = LOAD_LIMITS,
            yLimits = LATENCY_LIMITS,
            for_paper = FOR_PAPER)
def plotTrafgenThroughputComparisonDirs(dir2props_dict):

    units = 'Gb/s' if FOR_PAPER else 'Mb/s'
    div = 1000.0 if FOR_PAPER else 1

    fn_get_datapoint = lambda directory: getServerAvgTxRate(directory) / div
    yLabel = 'UDP throughput (%s)' % units
    title = '' if FOR_PAPER else 'Average UDP throughput'

    # Turn each directory's set of prop=val strings into a dictionary to
    # easily look up the value of a particular property for the directory
    dir2prop2val_dict = getDir2Prop2ValDict(dir2props_dict)

    # Make sure that all the experiments had the same number of client/server
    # machines and number of tenants.
    mctenants_vals = set()
    trafgentenants_vals = set()
    for directory in dir2props_dict.iterkeys():
        mctenants_vals.add(dir2prop2val_dict[directory]['mctenants'])
        trafgentenants_vals.add(dir2prop2val_dict[directory]['trafgentenants'])
    assert(len(mctenants_vals) == 1)
    assert(len(trafgentenants_vals) == 1)
    mctenants = int(mctenants_vals.pop())

    # Make sure that all the experiments had the same number of client and
    # server machines
    numclients_vals = set()
    numservers_vals = set()
    for directory in dir2props_dict.iterkeys():
        servers, clients = getServersAndClients(directory)
        numclients_vals.add(len(clients))
        numservers_vals.add(len(servers))
    assert(len(numclients_vals) == 1)
    assert(len(numservers_vals) == 1)
    numclients = numclients_vals.pop()

    # Function to convert mcrate value to total server load
    # fn_get_xgroup_value = functools.partial(serverLoadFromMcrate,
    #                                         mctenants = mctenants,
    #                                         numclients = numclients)
    # Load per tenant per client
    fn_get_xgroup_value = (lambda mcrate_val_set:
        int(getUniqueProp(mcrate_val_set)))

    return plotLineComparisonDirs(
            dir2props_dict,

            xgroup_props = ['mcrate'],
            line_props = ['rl'],

            fn_sort_lines = lambda lines: sortLineValSets(lines),

            fn_get_line_label = (lambda line_val_set:
                RL_LABEL[getUniqueProp(line_val_set)]),

            fn_get_xgroup_value = fn_get_xgroup_value,

            fn_get_datapoint = fn_get_datapoint,

            xLabel = 'Load per tenant per client (reqs/sec)',
            yLabel = yLabel,
            title = title,
            xLimits = LOAD_LIMITS,
            yLimits = THROUGHPUT_LIMITS,
            for_paper = FOR_PAPER)