def do_timepast(self, time_gap): """ Simulate two jobs: 1. reduce time slice for those already in use, check if they run out of time slice 2. reduce time slice for those cool downing, check if they run out of time slice :param time_gap: The time just past, the smaller time_gap is, the more precise the simulation is. :return: """ for port_inuse in self.pool_inuse: if (port_inuse.using(time_gap)): # Return true indicates this port runs of time slice. # Hence move it to PoolCoolDown self.pool_inuse.remove(port_inuse) if port_inuse.status == 2: self.pool_cooldown.append(port_inuse) else: write_error( "Error! port removed from PoolInuse but not moved to PoolCooldown." ) for port_cooldown in self.pool_cooldown: if (port_cooldown.cool_down(time_gap)): # Return true indicates this port already cool down. # Hence move it to PoolFree self.pool_cooldown.remove(port_cooldown) # port_cooldown.job = None if port_cooldown.status == 0: self.pool_free.append(port_cooldown) else: write_error( "Error! port removed from PoolCoolDown but not moved to PoolFree." )
def alg1_random_choose(self): """ Randomly choose a port number :return: the chosen port """ rand = random.choice(self.port_pool.pool_free) # print(rand) if rand == None: write_error("Error, no available port in PoolFree.") return rand
def using(self, time_past): if (self.status == 1): self.using_left -= time_past if (self.using_left <= 0): self.status = 2 self.using_left = 0 self.job.status = 2 write_runtimeInfo("Port %d Just Cool Down." % self.port_num) return True return False else: write_error("Unable to Using, current status is %d." % self.status)
def find_port(self, port_num_target): """ Find the Port Object based on the port number :param port_num_target: port number :return: Port object if found, else None """ try: ret_port = self.total_port_dict[port_num_target] return ret_port except KeyError: write_error("Port Number %d Not Found in Total Port Pool." % port_num_target) return None
def assign(self, job): if (self.status == 0): self.status = 1 self.job = job self.job.status = 1 self.job.realPort = self.port_num self.using_left = job.duration if "RST" in self.job.endStatus: self.cooldown_left = RST_COOLDOWN_TIME else: self.cooldown_left = DEFAULT_COOLDOWN_TIME write_output("%f\t%d" % (self.job.ts, self.port_num)) return True else: write_error("Unable to Assign, current status is %d." % self.status) return False
def cool_down(self, time_past): """ Method for simulates the cool down process of a port Only if status==2 where cool down is legal If no timeslice left, the cooldown process ends and the status will be set as free. :param time_past: :return: """ if (self.status == 2): self.cooldown_left -= time_past if (self.cooldown_left <= 0): self.status = 0 self.cooldown_left = DEFAULT_COOLDOWN_TIME write_runtimeInfo("Port %d Just Set Free." % self.port_num) return True return False else: write_error("Unable to Cool Down, current status is %d." % self.status)
def __init__(self, port_start, port_end): """ Identify the start and the end of the useful ports in a NAT. Start is included and end is excluded :param port_start: :param port_end: """ if (port_start < 0 or port_end > 65536): write_error("Illegal Port Num Setting") if (port_start > port_end): write_error("PortStart larger than PortEnd") port_start, port_end = port_end, port_start self.total_port = [] self.total_port_dict = {} self.pool_free = [] self.pool_inuse = [] self.pool_cooldown = [] for i in range(port_start, port_end): port_tmp = Port(i) self.total_port.append(port_tmp) self.total_port_dict[i] = port_tmp self.init_nat()