Query Batching - Problem
In modern web applications, making multiple small database queries can be inefficient due to network latency. Query batching is an optimization technique that combines multiple small queries into a single large query, reducing network overhead and improving performance.
Your task is to implement a QueryBatcher class that intelligently batches queries using a throttling mechanism.
Class Constructor:
queryMultiple: An asynchronous function that accepts an array of string keys and returns a Promise that resolves to an array of values (same length, where each index corresponds to the value forinput[i])t: Throttle time in milliseconds
Method to Implement:
async getValue(key): Accepts a single string key and returns a Promise that resolves to the corresponding value
Batching Rules:
- The first call to
getValueshould immediately triggerqueryMultiplewith that single key - Subsequent calls within the throttle period
tshould be batched together - After
tmilliseconds, all accumulated keys should be sent toqueryMultiple queryMultipleshould never be called consecutively withintmilliseconds- All keys are guaranteed to be unique
Example Timeline: If throttle time is 400ms, calls at 0ms, 150ms, 300ms would be batched together and sent at 400ms.
Input & Output
example_1.js โ Basic Batching
$
Input:
const batcher = new QueryBatcher(mockQuery, 400);
const result1 = await batcher.getValue('user123');
const result2 = await batcher.getValue('user456');
โบ
Output:
First call: immediate query(['user123'])
Second call: batched after 400ms with any other pending keys
๐ก Note:
The first getValue call triggers an immediate query. The second call waits for the throttle period to batch with other potential calls.
example_2.js โ Concurrent Calls
$
Input:
const [r1, r2, r3] = await Promise.all([
batcher.getValue('A'),
batcher.getValue('B'),
batcher.getValue('C')
]);
โบ
Output:
Single batched query: queryMultiple(['A', 'B', 'C'])
All three promises resolve with their respective values
๐ก Note:
When multiple getValue calls happen simultaneously (within the same event loop tick), they all get batched into a single query call.
example_3.js โ Throttling Edge Case
$
Input:
await batcher.getValue('first');
// Wait 500ms
setTimeout(() => batcher.getValue('second'), 500);
โบ
Output:
Immediate query(['first']) at t=0
Immediate query(['second']) at t=500
๐ก Note:
Since the second call comes after the throttle period has passed, it triggers immediately rather than being batched.
Visualization
Tap to expand
Understanding the Visualization
1
First Order Arrives
Kitchen immediately starts preparing the first customer's order - no waiting
2
More Orders Come In
Similar orders within the next few minutes get added to a preparation batch
3
Batch Preparation
Chef prepares all batched orders together efficiently, then serves each customer
4
Next Cycle
After completion, the next order again triggers immediate preparation
Key Takeaway
๐ฏ Key Insight: Throttled batching optimizes network usage while maintaining responsiveness by treating the first request specially and batching subsequent requests within a time window.
Time & Space Complexity
Time Complexity
O(1)
Each getValue call is constant time, batching amortizes cost
โ Linear Growth
Space Complexity
O(k)
Space for k pending promises in current batch
โ Linear Space
Constraints
- 1 โค throttle time โค 104 milliseconds
- 1 โค number of getValue calls โค 1000
- All keys are unique strings with length 1 โค key.length โค 100
- queryMultiple always resolves (never rejects)
- The throttling must be precise - no calls within t milliseconds of each other
๐ก
Explanation
AI Ready
๐ก Suggestion
Tab
to accept
Esc
to dismiss
// Output will appear here after running code