call(back)
Algorithms & Data Structuresmedium

Design Adjustable ID Allocator

Manage the fixed ID space [0, 999] — 1000 IDs — divided into named buckets that occupy contiguous, non-overlapping ranges. Implement two operations.

pack(requests)

Given (name, size) pairs in order, pack the buckets contiguously from ID 0 upward, preserving order, and return the layout as [name, start, end] triples.

  • A zero-size bucket appears as [name, -1, -1] and does not advance the cursor.
  • A negative size is an error.
  • If the sizes sum past 1000, fail without allocating anything.
pack([["a", 100], ["b", 200], ["c", 50]])
=> [["a", 0, 99], ["b", 100, 299], ["c", 300, 349]]

resize(buckets, name, newSize)

Given a packed layout, resize one bucket to own exactly newSize IDs:

  • Feasibility first: if total − currentSize + newSize > 1000, fail without mutating the layout.
  • The target keeps its start. Growth extends its end and shifts every later bucket right by the delta; shrinking pulls its end in and later buckets close the gap.
  • An unknown name or a negative size is an error.
resize([["a", 0, 99], ["b", 100, 299], ["c", 300, 349]], "a", 150)
=> [["a", 0, 149], ["b", 150, 349], ["c", 350, 399]]

resize([["a", 0, 99], ["b", 100, 299], ["c", 300, 349]], "a", 50)
=> [["a", 0, 49], ["b", 50, 249], ["c", 250, 299]]

Follow-ups

  • A validation variant: accept caller-proposed [start, end] ranges (gaps allowed), reject overlap or out-of-bounds, return them sorted by start.
  • How would concurrent resizes be kept safe — a lock over the whole space, or optimistic versioning with retry?

Asked at