You are asked to design an in-memory billing service for a food-delivery platform. The focus is on data structures and API behavior; you may ignore persistence, distribution, and thread-safety.
Context
-
There are tens of thousands of drivers.
-
Each driver can have hundreds of deliveries per week.
-
Delivery details are sent to the service immediately after completion.
-
Each driver has an hourly rate (can differ by driver and is given in USD/hour).
-
Drivers may take multiple deliveries simultaneously. Each delivery is paid independently, so overlapping deliveries earn the
sum
of their individual payouts.
-
Time is represented as Unix epoch seconds, using a 64-bit integer type (e.g.,
long
).
-
Each delivery satisfies:
0 < (endTime - startTime) ≤ 3 * 3600
seconds (i.e., at most 3 hours).
-
You should choose efficient in-memory data structures; the focus is on correctness and efficiency of the APIs.
Payment Rule
For a single delivery, the payout is:
payout=driverHourlyRate×3600endTime−startTime
Example: for a driver with rate $10.00/hour, a delivery from time t to t + 5400 (1.5 hours) yields:
10.00×36005400=15.00
You may store money internally as integer cents to avoid floating point error, but the public API should return double.
Required Core APIs
Design the data structures and in-memory logic to implement the following methods:
-
addDriver(driverId: int, usdHourlyRate: double) -> void
-
Registers a
new driver
with the given
driverId
and hourly rate.
-
You may assume
driverId
is unique and the driver does not already exist.
-
recordDelivery(driverId: int, startTime: long, endTime: long) -> void
-
Records a
completed delivery
for an existing driver.
-
Inputs are valid, with
0 < endTime - startTime ≤ 3 * 3600
.
-
Multiple deliveries can overlap in time, even for the same driver; each delivery is paid independently according to the payment rule.
-
getTotalCost() -> double
-
Returns the
total payout amount
across all recorded deliveries for all drivers.
-
This value is used for a live dashboard and may be called very frequently.
-
The requirement is to make this API very fast, ideally
amortized O(1)
per call.
Task
Describe how you would design this in-memory service:
-
Specify the main data structures you would use to store drivers and deliveries.
-
Explain how each of the three methods operates on these data structures.
-
Show how you ensure that
getTotalCost()
can run in amortized O(1) time, even as the number of deliveries grows large.
-
State any reasonable assumptions you make about constraints (e.g., maximum number of drivers, maximum number of deliveries).
You do not need to provide code; focus on the design, data structures, time/space complexity, and how the core APIs would behave.