예제 #1
0
def init(e: Environment, **kwargs) -> None:
    global All_Capable_Server_Type_List
    All_Capable_Server_Type_List = list(e.get_server_config_dict().keys())

    for vm_type, vm_config in e.get_vm_config_dict().items():
        for server_type in All_Capable_Server_Type_List:
            if server_type not in vm_config.get_capable_server_type_dict(
            ).keys():
                All_Capable_Server_Type_List.remove(server_type)
def read_vm_config(r: Reader, e: Environment) -> None:
    n = int(next(r.get_next_line))
    for _ in range(n):
        vm_config_list = next(r.get_next_line).strip('(').strip(')').split(', ')
        vm_type, cpu, memory, is_double = vm_config_list
        vm_config = VMConfig(
            vm_type=vm_type.strip(' '),
            cpu=int(cpu),
            memory=int(memory),
            is_double=is_double == '1'
        )
        e.add_vm_config(vm_config=vm_config)
def read_server_config(r: Reader, e: Environment) -> None:
    n = int(next(r.get_next_line))
    for _ in range(n):
        server_config_list = next(r.get_next_line).strip('(').strip(')').split(',')
        server_type, cpu, memory, cost_purchase, cost_everyday = server_config_list
        server_config = ServerConfig(
            server_type=server_type.strip(' '),
            cpu=int(cpu),
            memory=int(memory),
            cost_purchase=int(cost_purchase),
            cost_everyday=int(cost_everyday)
        )
        e.add_server_config(server_config=server_config)
예제 #4
0
def simulate_current_day(e: Environment, **kwargs) -> None:
    deploy_operations_list = []

    for op in e.get_current_day_info().get_request_operation_list():
        if isinstance(op, RemoveSingleVMOperation) or isinstance(
                op, RemoveDoubleVMOperation):
            simulate_current_stage(
                e=e, deploy_operations_list=deploy_operations_list)
            deploy_operations_list.clear()
            e.op_remove_vm(op=op)
        else:
            deploy_operations_list.append(op)

    simulate_current_stage(e=e, deploy_operations_list=deploy_operations_list)
예제 #5
0
def migrate_current_day(e: Environment, **kwargs) -> None:
    server_dict_dict = {
        server: {
            'server': server,
            'num_del_op': 0,
            'num_vm': server.get_num_vm_of_node_a() + server.get_num_vm_of_node_b(),
            'key': server.get_used_cpu_of_node_a() + server.get_used_cpu_of_node_b() + \
                   server.get_used_memory_of_node_a() + server.get_used_memory_of_node_b(),
        }
        for server in e.get_deployed_server_dict().values()
    }

    for remove_op in e.get_current_day_info().get_del_vm_operation_list():
        server_dict_dict[remove_op.get_vm().get_server()]['num_del_op'] += 1

    for server, server_dict in server_dict_dict.items():
        server_dict_dict[server]['key'] += server.get_num_vm_of_node_a() + server.get_num_vm_of_node_b() + \
                                           -server_dict_dict[server]['num_del_op']

    server_dict_list = list(server_dict_dict.values())
    server_dict_list.sort(key=lambda sd: sd['key'], reverse=False)

    num_total_vm = sum([sd['num_vm'] for sd in server_dict_list])
    num_migrations = 0
    max_migrations = num_total_vm * 3 // 100
    available_server_list = [sd['server'] for sd in server_dict_list]
    available_server_list.reverse()

    for server_dict in server_dict_list:
        server = server_dict['server']
        available_server_list.remove(server)

        for vm in server.get_vm_dict_of_node_a().copy().values():
            num_migrations += migrate_vm(
                e=e,
                vm=vm,
                current_server=server,
                available_server_list=available_server_list)
            if num_migrations == max_migrations:
                return

        for vm in server.get_vm_dict_of_node_b().copy().values():
            num_migrations += migrate_vm(
                e=e,
                vm=vm,
                current_server=server,
                available_server_list=available_server_list)
            if num_migrations == max_migrations:
                return
def write_day_operation(w: Writer, e: Environment) -> None:
    content_list = []

    server_dict = {}
    for purchase_server_operation in e.get_current_day_info().get_purchase_server_operation_list():
        server_id = purchase_server_operation.get_server().get_server_id()
        server_type = purchase_server_operation.get_server().get_server_type()
        if server_type in server_dict.keys():
            server_dict[server_type].append(server_id)
        else:
            server_dict[server_type] = [server_id]

    # w.write(content=f'(purchase, {len(server_dict)})')
    content_list.append(f'(purchase, {len(server_dict)})')
    for server_type, server_id_list in server_dict.items():
        # w.write(content=f'({server_type}, {len(server_id_list)})')
        content_list.append(f'({server_type}, {len(server_id_list)})')
        for server_id in server_id_list:
            w.set_mapped_server_id(server_id=server_id)

    # w.write(content=f'(migration, {len(e.get_current_day_info().get_migrate_vm_operation_list())})')
    content_list.append(f'(migration, {len(e.get_current_day_info().get_migrate_vm_operation_list())})')
    for op in e.get_current_day_info().get_migrate_vm_operation_list():
        vm_id = op.get_vm().get_vm_id()
        server_id = op.get_server().get_server_id()
        if op.get_vm().is_double():
            # w.write(content=f'({vm_id}, {server_id})')
            content_list.append(f'({vm_id}, {server_id})')
        else:
            node = op.get_node()
            # w.write(content=f'({vm_id}, {server_id}, {node})')
            content_list.append(f'({vm_id}, {server_id}, {node})')

    for op in e.get_current_day_info().get_request_operation_list():
        if isinstance(op, DeploySingleVMOperation):
            mapped_server_id = w.get_mapped_server_id(server_id=op.get_server().get_server_id())
            # w.write(content=f'({mapped_server_id}, {op.get_node()})')
            content_list.append(f'({mapped_server_id}, {op.get_node()})')
        elif isinstance(op, DeployDoubleVMOperation):
            mapped_server_id = w.get_mapped_server_id(server_id=op.get_server().get_server_id())
            # w.write(content=f'({mapped_server_id})')
            content_list.append(f'({mapped_server_id})')

    content = '\n'.join(content_list)
    w.write(content=content)
    w.flush()
예제 #7
0
def purchase_the_best_server(e: Environment, vm: Union[SingleVM,
                                                       DoubleVM]) -> Server:
    target_server_config = None

    for server_config in e.get_server_config_dict().values():
        if server_config not in vm.get_vm_config(
        ).get_capable_server_type_dict().values():
            continue
        if target_server_config is None:
            target_server_config = server_config
            continue
        if server_config_cost(e=e, server_config=server_config) < \
                server_config_cost(e=e, server_config=target_server_config):
            target_server_config = server_config

    server = e.op_purchase_server(server_config=target_server_config)
    return server
예제 #8
0
def migrate_current_day(e: Environment, **kwargs) -> None:
    server_id_num_vm_list = [
        (server.get_server_id(), server.get_num_vm_of_both_nodes())
        for server in e.get_deployed_server_dict().values()
    ]

    server_id_num_vm_list.sort(key=lambda t: t[1])

    num_total_vm = sum([t[1] for t in server_id_num_vm_list])
    num_migrations = 0
    max_migrations = num_total_vm * 3 // 100

    for server_id, num_vm in server_id_num_vm_list:
        server = e.get_server_by_id(server_id=server_id)
        for vm in server.get_vm_dict_of_node_a().copy().values():
            num_migrations += migrate_vm(e=e, vm=vm, current_server=server)
            if num_migrations == max_migrations:
                break
        if num_migrations == max_migrations:
            break
예제 #9
0
def select_idle_server_for_double_vm(e: Environment,
                                     vm: DoubleVM) -> Optional[Server]:
    target_server = None

    for server in e.get_non_deployed_server_dict().values():
        if server.has_capacity_for_double_vm(vm=vm):
            if target_server is None or server_cost_d(
                    vm, server) < server_cost_d(vm, target_server):
                target_server = server

    return target_server
예제 #10
0
def select_idle_server_for_single_vm(
        e: Environment,
        vm: SingleVM) -> Tuple[Optional[Server], Optional[str]]:
    target_server = None
    target_node = None

    for server in e.get_non_deployed_server_dict().values():
        if server.has_capacity_for_single_vm(vm=vm, node='A'):
            if target_server is None or server_cost_s(
                    vm, server, 'A') < server_cost_s(vm, target_server, 'A'):
                target_server, target_node = server, 'A'

    return target_server, target_node
예제 #11
0
def migrate_vm(e: Environment, vm: Union[SingleVM, DoubleVM],
               current_server: Server) -> int:
    if isinstance(vm, SingleVM):
        for server in e.get_deployed_server_dict().values():
            if server == current_server:
                continue
            if server.has_capacity_for_single_vm(vm=vm, node='A'):
                e.op_migrate_single_vm(vm=vm, new_server=server, node='A')
                return 1
            if server.has_capacity_for_single_vm(vm=vm, node='B'):
                e.op_migrate_single_vm(vm=vm, new_server=server, node='B')
                return 1

    if isinstance(vm, DoubleVM):
        for server in e.get_deployed_server_dict().values():
            if server == current_server:
                continue
            if server.has_capacity_for_double_vm(vm=vm):
                e.op_migrate_double_vm(vm=vm, new_server=server)
                return 1

    return 0
def read_day_request(r: Reader, e: Environment, day: int) -> None:
    n = int(next(r.get_next_line))
    for _ in range(n):
        request_list = next(r.get_next_line).strip('(').strip(')').split(', ')
        if request_list[0] == 'add':
            vm_type = request_list[1]
            vm_id = request_list[2]
            vm_config = e.get_vm_config_by_type(vm_type=vm_type)
            if vm_config.is_double():
                vm = DoubleVM(vm_id=vm_id, vm_config=vm_config)
                op = DeployDoubleVMOperation(day=day, vm=vm)
            else:
                vm = SingleVM(vm_id=vm_id, vm_config=vm_config)
                op = DeploySingleVMOperation(day=day, vm=vm)
            e.add_non_deployed_vm(vm=vm)
            e.add_request_operation(day=day, op=op)
        elif request_list[0] == 'del':
            vm_id = request_list[1]
            vm = e.get_vm_by_id(vm_id=vm_id)
            if vm.is_double():
                op = RemoveDoubleVMOperation(day=day, vm=vm)
            else:
                op = RemoveSingleVMOperation(day=day, vm=vm)
            e.add_request_operation(day=day, op=op)
예제 #13
0
def migrate_vm(e: Environment, vm: Union[SingleVM,
                                         DoubleVM], current_server: Server,
               available_server_list: List[Server]) -> int:
    if isinstance(vm, SingleVM):
        for server in available_server_list:
            if server == current_server:
                continue
            if server.has_capacity_for_single_vm(vm=vm, node='A'):
                e.op_migrate_single_vm(vm=vm, new_server=server, node='A')
                return 1
            if server.has_capacity_for_single_vm(vm=vm, node='B'):
                e.op_migrate_single_vm(vm=vm, new_server=server, node='B')
                return 1

    if isinstance(vm, DoubleVM):
        for server in available_server_list:
            if server == current_server:
                continue
            if server.has_capacity_for_double_vm(vm=vm):
                e.op_migrate_double_vm(vm=vm, new_server=server)
                return 1

    return 0
def main(is_debug: bool = False,
         read_mode: str = 'console',
         read_filename: str = '',
         write_mode: str = 'console',
         write_filename: str = '',
         is_write_day_info: bool = False,
         is_write_day_operation: bool = True) -> int:
    # initialize
    r = Reader(mode=read_mode, filename=read_filename)
    w = Writer(is_console=True,
               is_file=(write_mode == 'file'),
               filename=write_filename)
    e = Environment()
    e.set_debug(is_debug=is_debug)

    # initial read
    DataIO.read_server_config(r=r, e=e)
    DataIO.read_vm_config(r=r, e=e)
    num_total_days, num_next_days = map(int, next(r.get_next_line).split(' '))
    e.set_total_days(total_days=num_total_days)

    day_data_id = 0
    for day_data_id in range(1, num_next_days + 1):
        DataIO.read_day_request(r=r, e=e, day=day_data_id)

    # previous actions
    Simulation.init(e=e)
    if is_write_day_info:
        DataIO.write_day_info_header(w=w)

    # main actions
    for day_id in range(1, num_total_days + 1):
        # simulate
        e.start_next_day()
        Simulation.migrate_current_day(e=e)
        Simulation.simulate_current_day(e=e)
        e.finish_current_day()

        # write
        if is_write_day_info:
            DataIO.write_day_info(w=w, e=e)
        if is_write_day_operation:
            DataIO.write_day_operation(w=w, e=e)

        # read
        day_data_id += 1
        if day_data_id <= num_total_days:
            DataIO.read_day_request(r=r, e=e, day=day_data_id)

    # post actions
    return e.eval_get_accumulated_total_cost()
예제 #15
0
def simulate_current_stage(e: Environment, deploy_operations_list: List[Union[
    DeploySingleVMOperation, DeployDoubleVMOperation]], **kwargs) -> None:
    deploy_operations_list.sort(key=lambda op: op.get_vm().get_cpu_of_one_node(
    ) + op.get_vm().get_memory_of_one_node(),
                                reverse=True)

    for op in deploy_operations_list:
        vm = op.get_vm()

        if isinstance(op, DeploySingleVMOperation):
            server, node = select_running_server_for_single_vm(e=e, vm=vm)
            if server:
                e.op_deploy_single_vm(op=op, server=server, node=node)
                continue

            server, node = select_idle_server_for_single_vm(e=e, vm=vm)
            if server:
                e.op_deploy_single_vm(op=op, server=server, node=node)
                continue

            server = purchase_the_best_server(e=e, vm=vm)
            e.op_deploy_single_vm(op=op, server=server, node='A')

        elif isinstance(op, DeployDoubleVMOperation):
            server = select_running_server_for_double_vm(e=e, vm=vm)
            if server:
                e.op_deploy_double_vm(op=op, server=server)
                continue

            server = select_idle_server_for_double_vm(e=e, vm=vm)
            if server:
                e.op_deploy_double_vm(op=op, server=server)
                continue

            server = purchase_the_best_server(e=e, vm=vm)
            e.op_deploy_double_vm(op=op, server=server)
예제 #16
0
def server_config_cost(e: Environment, server_config: ServerConfig) -> float:
    return server_config.get_cost_purchase() + \
           server_config.get_cost_everyday() * (e.get_total_days() - e.get_current_day())
예제 #17
0
def simulate_current_day(e: Environment, **kwargs) -> None:
    for op in e.get_current_day_info().get_request_operation_list():
        vm = op.get_vm()

        if isinstance(op, DeploySingleVMOperation):
            server_config_dict = vm.get_vm_config(
            ).get_capable_server_type_dict()
            server_config = list(server_config_dict.values())[0]
            server = e.op_purchase_server(server_config=server_config)
            e.op_deploy_single_vm(op=op, server=server, node='A')

        elif isinstance(op, DeployDoubleVMOperation):
            server_config_dict = vm.get_vm_config(
            ).get_capable_server_type_dict()
            server_config = list(server_config_dict.values())[0]
            server = e.op_purchase_server(server_config=server_config)
            e.op_deploy_double_vm(op=op, server=server)

        elif isinstance(op, RemoveSingleVMOperation):
            e.op_remove_vm(op=op)

        elif isinstance(op, RemoveDoubleVMOperation):
            e.op_remove_vm(op=op)
예제 #18
0
def purchase_server(e: Environment) -> Server:
    server_type = random.choice(All_Capable_Server_Type_List)
    server_config = e.get_server_config_by_type(server_type=server_type)
    server = e.op_purchase_server(server_config=server_config)
    return server
def write_day_info(w: Writer, e: Environment) -> None:
    content_list = [
        e.get_current_day(),
        '|',

        e.eval_get_accumulated_total_cost(),
        e.eval_get_accumulated_purchase_cost(),
        e.eval_get_accumulated_running_cost(),
        '|',

        e.get_current_day_info().eval_get_total_cost(),
        e.get_current_day_info().eval_get_purchase_cost(),
        e.get_current_day_info().eval_get_running_cost(),
        '|',

        len(e.get_deployed_vm_dict()) + len(e.get_non_deployed_vm_dict()),
        len(e.get_deployed_vm_dict()),
        len(e.get_non_deployed_vm_dict()),
        '|',

        len(e.get_deployed_server_dict()) + len(e.get_non_deployed_server_dict()),
        len(e.get_deployed_server_dict()),
        len(e.get_non_deployed_server_dict()),
        len(e.get_current_day_info().get_purchase_server_operation_list()),
        '|',

        e.get_current_day_info().get_num_add_vm_operation(),
        e.get_current_day_info().get_num_del_vm_operation(),
        '|',

        len(e.get_current_day_info().get_migrate_vm_operation_list()),
        '|',
    ]
    content_list = map(str, content_list)
    content = ','.join(content_list)
    w.write(content=content)
예제 #20
0
def simulate_current_day(e: Environment, **kwargs) -> None:
    for op in e.get_current_day_info().get_request_operation_list():
        vm = op.get_vm()

        if isinstance(op, DeploySingleVMOperation):
            for server in e.get_deployed_server_dict().values():
                if server.has_capacity_for_single_vm(vm=vm, node='A'):
                    e.op_deploy_single_vm(op=op, server=server, node='A')
                    break
                if server.has_capacity_for_single_vm(vm=vm, node='B'):
                    e.op_deploy_single_vm(op=op, server=server, node='B')
                    break

            if op.get_server() is None:
                for server in e.get_non_deployed_server_dict().values():
                    if server.has_capacity_for_single_vm(vm=vm, node='A'):
                        e.op_deploy_single_vm(op=op, server=server, node='A')
                        break
                    if server.has_capacity_for_single_vm(vm=vm, node='B'):
                        e.op_deploy_single_vm(op=op, server=server, node='B')
                        break

            if op.get_server() is None:
                server = purchase_server(e=e)
                e.op_deploy_single_vm(op=op, server=server, node='A')

        elif isinstance(op, DeployDoubleVMOperation):
            for server in e.get_deployed_server_dict().values():
                if server.has_capacity_for_double_vm(vm=vm):
                    e.op_deploy_double_vm(op=op, server=server)
                    break

            if op.get_server() is None:
                for server in e.get_non_deployed_server_dict().values():
                    if server.has_capacity_for_double_vm(vm=vm):
                        e.op_deploy_double_vm(op=op, server=server)
                        break
                    if server.has_capacity_for_double_vm(vm=vm):
                        e.op_deploy_double_vm(op=op, server=server)
                        break

            if op.get_server() is None:
                server = purchase_server(e=e)
                e.op_deploy_double_vm(op=op, server=server)

        elif isinstance(op, RemoveSingleVMOperation):
            e.op_remove_vm(op=op)

        elif isinstance(op, RemoveDoubleVMOperation):
            e.op_remove_vm(op=op)