Level 1 Servers on a ring
A storage cluster spreads data over its servers using a ring of positions 0 .. 10^9 - 1. Servers sit at points on the ring, and a key at position p belongs to the first server point at or after p going clockwise (upwards). Past the highest point it wraps around to the lowest one.
Build ServerRing:
add_server(server, position) -> bool: put a new server on the ring atposition.False(changing nothing) if a server with that name is already on the ring, or that position is already taken.remove_server(server) -> bool: take the server off the ring.Falseif it isn't on the ring. Its name may be added again later.owner(position) -> str | None: the server a key atpositionbelongs to, orNoneif the ring is empty.
ring = ServerRing()
ring.add_server("red", 100) # True
ring.add_server("blue", 500) # True
ring.add_server("green", 500) # False: position 500 is taken
ring.add_server("red", 900) # False: red is already on the ring
ring.owner(100) # "red" a point exactly at p counts
ring.owner(101) # "blue"
ring.owner(700) # "red" wraps around past 500
ring.remove_server("red") # True
ring.owner(50) # "blue"
At this level there are at most a few hundred servers, so checking every point on a lookup is fine.
Show hint
Keep a map from position to server. For a lookup, the answer is the smallest position that is >= p, or the smallest position overall if there is none.