~/problems / Binary search / Sorted containers (bisect)

OA: Spreading keys over a ring of servers

medium 3 levels ~75 min

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 at position. 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. False if it isn't on the ring. Its name may be added again later.
  • owner(position) -> str | None: the server a key at position belongs to, or None if 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.

Level 2 unlocks when level 1 passes.

Level 3 unlocks when level 2 passes.

Topic: Sorted containers (bisect). Ordered-set operations in Python: bisect.insort, floor/ceiling lookups.

Read the visual guide
0:00
Ctrl ' run · Ctrl ↵ submit
esc