<s> import random , string , sys <EOL> GROWTH_RATE = <NUM_LIT:2> <EOL> CHIP_RATE = <NUM_LIT> <EOL> MAX_SERVERS = <NUM_LIT:10> <EOL> MAX_LOCATIONS = <NUM_LIT:10> <EOL> MAX_REPOS = <NUM_LIT:10> <EOL> __test__ = False <EOL> class GeoLoc : <EOL> def __init__ ( self , coords = ( "<STR_LIT>" , "<STR_LIT>" ) ) : <EOL> self . coords = coords <EOL> class Server : <EOL> def __init__ ( self , ip , port , user , geoloc = GeoLoc ( ) ) : <EOL> self . port = port <EOL> self . user = user <EOL> self . geoloc = geoloc <EOL> self . locations = [ ] <EOL> def __str__ ( self ) : <EOL> return repr ( self ) <EOL> def __repr__ ( self ) : <EOL> s = '<STR_LIT>' . format ( ip = self . ip , port = self . port ) <EOL> for loc in self . locations : <EOL> s += '<STR_LIT>' . format ( loc = loc ) <EOL> for repo in loc . repos : <EOL> s += '<STR_LIT>' . format ( repo = repo ) <EOL> return s <EOL> class Repo : <EOL> def __init__ ( self , name , safe_mode , local_size , min_locations , locations , base_location = None ) : <EOL> self . name = name <EOL> self . safe_mode = safe_mode <EOL> self . local_size = local_size <EOL> self . min_locations = min_locations <EOL> self . locations = locations <EOL> self . base_location = base_location <EOL> def __str__ ( self ) : <EOL> return repr ( self ) <EOL> def __repr__ ( self ) : <EOL> return '<STR_LIT>' . format ( self . name , self . commit_size ( ) , self . min_locations , self . base_location ) <EOL> def commit_size ( self ) : <EOL> return GROWTH_RATE * self . local_size <EOL> class Location : <EOL> def __init__ ( self , max_up , max_down , max_size , path , server ) : <EOL> self . max_up = max_up <EOL> self . max_down = max_down <EOL> self . max_size = max_size <EOL> self . path = path <EOL> self . server = server <EOL> self . server . locations . append ( self ) <EOL> self . repos = [ ] <EOL> def __str__ ( self ) : <EOL> return repr ( self ) <EOL> def __repr__ ( self ) : <EOL> return '<STR_LIT>' . format ( path = self . path , ip = self . server . ip , size_left = self . max_size - self . committed_size ( ) , max_size = self . max_size ) <EOL> def committed_size ( self ) : <EOL> return sum ( [ r . commit_size ( ) for r in self . repos ] ) <EOL> def main ( ) : <EOL> ( servers , repos , locations ) = init_test_data ( ) <EOL> run = <NUM_LIT:0> <EOL> while distribute ( servers , repos , locations , run ) : <EOL> print_state ( servers ) <EOL> run += <NUM_LIT:1> <EOL> def distribute ( servers , repos , locations , run = <NUM_LIT:0> ) : <EOL> placed = False <EOL> for repo in repos : <EOL> if repo not in repo . base_location . repos : <EOL> repo . base_location . repos . append ( repo ) <EOL> if repo . base_location not in repo . locations : <EOL> repo . locations . append ( repo . base_location ) <EOL> repos = sorted ( repos , key = lambda r : r . local_size , reverse = True ) <EOL> locations = sorted ( locations , key = lambda l : l . max_size - l . committed_size ( ) , reverse = True ) <EOL> for repo in repos : <EOL> possible_locations = find_possible_locations ( repo , locations ) <EOL> print ( "<STR_LIT>" . format ( repo = repo , min_loc = repo . min_locations - len ( repo . locations ) if run == <NUM_LIT:0> else <NUM_LIT:1> , pos = possible_locations ) ) <EOL> for placing in ( range ( repo . min_locations - <NUM_LIT:1> ) if run == <NUM_LIT:0> else [ <NUM_LIT:0> ] ) : <EOL> if len ( possible_locations ) > <NUM_LIT:0> : <EOL> print ( "<STR_LIT>" . format ( repo = repo , loc = possible_locations [ - <NUM_LIT:1> ] ) ) <EOL> placed = True <EOL> repo . locations . append ( possible_locations [ - <NUM_LIT:1> ] ) <EOL> possible_locations [ - <NUM_LIT:1> ] . repos . append ( repo ) <EOL> possible_locations = possible_locations [ : - <NUM_LIT:1> ] <EOL> elif run == <NUM_LIT:0> : <EOL> print ( '<STR_LIT>' ) <EOL> break <EOL> return placed <EOL> def init_test_data ( ) : <EOL> servers = [ ] <EOL> for i in range ( MAX_SERVERS ) : <EOL> s = Server ( ip = '<STR_LIT>' + str ( i ) , port = random . randint ( <NUM_LIT> , <NUM_LIT> ) , user = random_str ( <NUM_LIT:5> ) ) <EOL> servers . append ( s ) <EOL> locations = [ ] <EOL> for i in range ( MAX_LOCATIONS ) : <EOL> locations . append ( Location ( max_up = random . randint ( <NUM_LIT:0> , <NUM_LIT> ) , max_down = random . randint ( <NUM_LIT:0> , <NUM_LIT> ) , max_size = random . randint ( <NUM_LIT:1000> , <NUM_LIT> ) , path = "<STR_LIT:/>" + random_str ( <NUM_LIT:4> ) , server = random . choice ( servers ) ) ) <EOL> repos = [ ] <EOL> for i in range ( MAX_REPOS ) : <EOL> repos . append ( Repo ( name = '<STR_LIT>' + str ( i ) , safe_mode = i % <NUM_LIT:3> == <NUM_LIT:0> , local_size = int ( <NUM_LIT> ** random . randint ( <NUM_LIT:100> , <NUM_LIT> ) ) , min_locations = i % <NUM_LIT:3> + <NUM_LIT:1> , locations = [ ] ) ) <EOL> for repo in repos : <EOL> locs = find_possible_locations ( repo , locations ) <EOL> if len ( locs ) > <NUM_LIT:0> : <EOL> loc = random . choice ( locs ) <EOL> repo . base_location = loc <EOL> repo . locations . append ( repo . base_location ) <EOL> loc . repos . append ( repo ) <EOL> else : <EOL> print ( "<STR_LIT>" ) <EOL> sys . exit ( - <NUM_LIT:1> ) <EOL> print_state ( servers ) <EOL> return ( servers , repos , locations ) <EOL> def random_str ( number ) : <EOL> return '<STR_LIT>' . join ( random . choice ( string . ascii_letters + string . digits ) for x in range ( number ) ) <EOL> def find_possible_locations ( repo , locations ) : <EOL> result = [ ] <EOL> for loc in locations : <EOL> serv_repos = [ ] <EOL> for l in loc . server . locations : <EOL> serv_repos += l . repos <EOL> if repo not in serv_repos and ( loc . max_size - loc . committed_size ( ) ) > repo . commit_size ( ) : <EOL> result . append ( loc ) <EOL> return result <EOL> def print_state ( s ) : <EOL> print ( '<STR_LIT>' ) <EOL> if type ( s ) == list : <EOL> for serv in s : <EOL> print ( serv ) <EOL> else : <EOL> print ( s ) <EOL> print ( "<STR_LIT:*>" * <NUM_LIT:200> ) <EOL> if __name__ == '<STR_LIT:__main__>' : <EOL> main ( ) </s>
