-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcloud_foundation.py
199 lines (171 loc) · 7.25 KB
/
cloud_foundation.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
#!/usr/bin/env python3
# from console_IO import OutputCommand
from typing import Tuple, Dict, Set
class ServerType():
type_dict: Dict[str, 'ServerType'] = {} # model -> ServerType
def __init__(self, model: str, core: int, memory: int, price: int, cost_each_day: int) -> None:
# init
self.model = model
self.core = core
self.memory = memory
self.price = price
self.cost_each_day = cost_each_day
# resource limitation
self.core_lmt = self.core // 2
self.mem_lmt = self.memory // 2
# add type to class member variable
self.__class__.type_dict[model] = self
@classmethod
def get_type_by_model(cls, model: str) -> 'ServerType':
return cls.type_dict[model]
class VM_Type():
type_dict: Dict[str, 'VM_Type'] = {} # model -> VM_Type
def __init__(self, model: str, core: int, memory: int, double: bool) -> None:
# init
self.model = model
self.core = core
self.memory = memory
self.double = double
# node requirement
if self.double:
self.node_core = self.core // 2
self.node_mem = self.memory // 2
else:
self.node_core = self.core
self.node_mem = self.memory
# add type to class member variable
self.__class__.type_dict[model] = self
@classmethod
def get_type_by_model(cls, model: str) -> 'VM_Type':
return cls.type_dict[model]
class VM():
vm_dict: Dict[int, 'VM'] = {}
vm_dispach_dict: Dict[int, 'Server'] = {} # id -> Server instance
def __init__(self, model_type: VM_Type, id: int) -> None:
self.id = id
self.__class__.vm_dict[id] = self
self._type = model_type
self.node_core = self._type.node_core
self.node_mem = self._type.node_mem
self.double = self._type.double
@property
def memory(self) -> int:
return self._type.memory
@property
def core(self) -> int:
return self._type.core
@classmethod
def get_vm_by_id(cls, id: int) -> 'VM':
return cls.vm_dict[id]
def del_vm(self):
svr = self.__class__.vm_dispach_dict[self.id]
svr.del_vm_by_instance(self)
class Server():
server_dict: Dict[int, 'Server'] = {}
server_num = 0
def __init__(self, server_type: ServerType) -> None:
# type init
self._type = server_type
self.core_lmt = self._type.core_lmt
self.mem_lmt = self._type.mem_lmt
# core & mem init
self.left_core = self.right_core = 0
self.left_mem = self.right_mem = 0
# vm list only store vm.id
self.left_vm_id_set: Set[int] = set()
self.right_vm_id_set: Set[int] = set()
self.double_vm_id_set: Set[int] = set()
# core & mem remain
self.left_remain_core = self.right_remain_core = self.core_lmt
self.left_remain_mem = self.right_remain_mem = self.mem_lmt
##### we must create server before dispatch it, so comment it temporary #####
self.id: int
# add instance into cls.server_dict
# id = self.__class__.server_num
# self.id = id
# self.__class__.server_dict[id] = self
# self.__class__.server_num += 1
def add_vm_by_type(self, id: int, vm_type: 'VM_Type', side: int, output: 'OutputCommand'): # -1: left 0: double 1: right
vm = VM(vm_type, id)
self.add_vm_by_instance(vm, side)
def add_vm_by_instance(self, vm: 'VM', side: int): # -1: left 0: double 1: right
VM.vm_dispach_dict[vm.id] = self
id = vm.id
if side == -1: # check core and memory >=0
self.occupy_left_resource(vm)
self.left_vm_id_set.add(id)
# output.add_new_vm_dispatch(self.id, 'A')
elif side == 0:
self.occupy_left_resource(vm)
self.occupy_right_resource(vm)
self.double_vm_id_set.add(id)
# output.add_new_vm_dispatch(self.id, '')
elif side == 1:
self.occupy_right_resource(vm)
self.right_vm_id_set.add(id)
# output.add_new_vm_dispatch(self.id, 'B')
else:
raise ValueError
def del_vm_by_instance(self, vm: 'VM'):
self.del_vm_by_id(vm.id)
def del_vm_by_id(self, id: int):
del VM.vm_dispach_dict[id]
vm = VM.get_vm_by_id(id)
if id in self.left_vm_id_set:
self.release_left_resource(vm)
self.left_vm_id_set.remove(id)
elif id in self.double_vm_id_set:
self.release_left_resource(vm)
self.release_right_resource(vm)
self.double_vm_id_set.remove(id)
elif id in self.right_vm_id_set:
self.release_right_resource(vm)
self.right_vm_id_set.remove(id)
else:
raise ValueError
def can_put_vm_left(self, vm: 'VM'):
return vm.node_core <= self.left_remain_core and vm.node_mem <= self.left_remain_mem
def can_put_vm_right(self, vm: 'VM'):
return vm.node_core <= self.right_remain_core and vm.node_mem <= self.right_remain_mem
def occupy_left_resource(self, vm: 'VM') -> Tuple[int, int]: # remain_core, remain_mem
self.left_core += vm.node_core # resource usage
self.left_mem += vm.node_mem
self.left_remain_core -= vm.node_core # resource remain
self.left_remain_mem -= vm.node_mem
if self.left_remain_core < 0 or self.left_remain_mem < 0:
raise ValueError
return self.left_remain_core, self.left_remain_mem
def release_left_resource(self, vm: 'VM') -> Tuple[int, int]: # remain_core, remain_mem
self.left_core -= vm.node_core # resource usage
self.left_mem -= vm.node_mem
self.left_remain_core += vm.node_core # resource remain
self.left_remain_mem += vm.node_mem
return self.left_remain_core, self.left_remain_mem
def occupy_right_resource(self, vm: 'VM') -> Tuple[int, int]: # remain_core, remain_mem
self.right_core += vm.node_core # resource usage
self.right_mem += vm.node_mem
self.right_remain_core -= vm.node_core # resource remain
self.right_remain_mem -= vm.node_mem
if self.right_remain_core < 0 or self.right_remain_mem < 0:
raise ValueError
return self.right_remain_core, self.right_remain_mem
def release_right_resource(self, vm: 'VM') -> Tuple[int, int]: # remain_core, remain_mem
self.right_core -= vm.node_core # resource usage
self.right_mem -= vm.node_mem
self.right_remain_core += vm.node_core # resource remain
self.right_remain_mem += vm.node_mem
return self.right_remain_core, self.right_remain_mem
@classmethod
def get_server_by_id(cls, id: int) -> 'Server':
return cls.server_dict[id]
@property
def model(self) -> str:
return self._type.model
def activate_server(self):
if id in self.server_dict.keys():
raise ValueError
else:
# output.add_server(self._type)
self.id = self.__class__.server_num
self.server_dict[self.__class__.server_num] = self
self.__class__.server_num += 1