Document Indexer Scheduling Metrics
Reported by candidates from Glean's online assessment. Pattern, common pitfall, and the honest play if you blank under the timer.
Glean reported this one in October 2026, and it looks like a messy scheduling story but it's a simulation with one real problem: finding the first free indexer fast. If you've got an OA invite for Glean, expect to write the assignment loop, then a ranking step, then pack the output array in the exact layout. Miss the layout and every test fails. The statement is long, but the logic is short once you strip it down. StealthCoder sits invisibly on your screen as a safety net if you blank mid-assessment, but read the plan below first.
The problem
You manage indexerCount document indexers numbered from 0 through indexerCount - 1. Document i arrives at time queueTimes[i] and occupies one indexer for processingTimes[i] time units. Document i prefers indexer i % indexerCount. Starting there, scan indexers in increasing numeric order and wrap from the last indexer to indexer 0. Assign the document to the first indexer whose previous job finishes at or before its arrival time. If every indexer is busy, drop the document. After all arrivals, rank every indexer by documents processed in descending order, breaking ties by smaller indexer number. Let topCount = min(k, indexerCount). Return an integer array with this exact layout: the total number of successfully processed documents; the busiest indexer, using the ranking rule above; the number of successful documents processed by the first topCount ranked indexers; the total number of successfully processed documents again, as the denominator of the exact top-indexer share; and the topCount ranked indexer numbers. The third and fourth values represent the exact share. For example, 3 and 4 mean 3/4 = 75%. When no document is processed, both share values are 0; indexer 0 is busiest by the tie rule. Function summarizeIndexerLoad(indexerCount: int, queueTimes: int[], processingTimes: int[], k: int) → int[] Examples Example 1 indexerCount = 3 queueTimes = [1,2,3,7] processingTimes = [5,4,3,2] k = 2 return = [4,0,3,4,0,1] The four documents go to indexers 0, 1, 2, 0. Counts are [2,1,1], so indexer 0 is busiest and the deterministic top two are [0,1]. They processed 3/4 = 75% of all successful documents. Example 2 indexerCount = 2 queueTimes = [1,2,3,6] processingTimes = [5,5,1,1] k = 5 return = [3,0,3,3,0,1] The third document is dropped because both indexers are busy. At time 6, indexer 0 is free, so the last document wraps from preferred indexer 1 to indexer 0. Because k exceeds the indexer count, both indexers are returned. Example 3 indexerCount = 3 queueTimes = [1,2,3,4] processingTimes = [10,10,1,1] k = 2 return = [4,2,3,4,2,0] The fourth document prefers indexer 0, finds indexers 0 and 1 busy, and reaches indexer 2 after wrapping. Counts are [1,1,2], so the top two are [2,0] and their share is 3/4. Constraints 1 <= indexerCount <= 10^5. 0 <= queueTimes.length = processingTimes.length <= 2 * 10^5. 0 <= k <= 2 * 10^5. 0 <= queueTimes[i] <= 10^9. queueTimes is strictly increasing. 1 <= processingTimes[i] <= 10^9.
Reported by candidates. Source: FastPrep
Pattern and pitfall
What it really reduces to: for each document, find the first indexer at or after i % n, with wraparound, whose free time is <= arrival time. Naive scanning is O(n) per document, up to 2*10^5 times 10^5, which is too slow. The trick is a data structure for the first free indexer at or after a position. Keep a sorted set of free indexers plus a min-heap of (finishTime, indexer) for busy ones. Before each arrival, pop every finished job and put its indexer back in the free set. Then lower-bound search from the preferred index, wrap to the smallest if nothing is found, and drop the document if the set is empty. A segment tree works too. Common pitfalls: forgetting wraparound, using strict instead of non-strict finish comparison, and botching the output when nothing is processed or k exceeds indexerCount. Sort by count descending, then index ascending. If you freeze live, StealthCoder is the hedge.
The honest play: practice the pattern, and have StealthCoder ready for the one you didn't see coming.
You can drill Document Indexer Scheduling Metrics cold, or you can hedge it. StealthCoder runs invisibly during screen share and surfaces a working solution in under 2 seconds. The proctor sees the IDE. They don't see what's behind it. Built for the candidate who saw this exact problem leak two days before his OA and wondered if anyone had a play.
Get StealthCoderThis OA pattern shows up on LeetCode as find servers that handled most number of requests. If you have time before the OA, drill that.
You've seen the question.
Make sure you actually pass Glean's OA.
Glean reuses patterns across OAs. Built for the candidate who saw this exact problem leak two days before his OA and wondered if anyone had a play. Works on HackerRank, CodeSignal, CoderPad, and Karat.
Document Indexer Scheduling Metrics FAQ
What's the trick in the Glean document indexer problem?+
Find the first free indexer at or after the preferred one, with wraparound, quickly. Keep a sorted set of free indexers and a min-heap of busy ones by finish time. Release finished jobs before each arrival, then do a lower-bound lookup. Brute force scanning is too slow at these constraints.
How hard is this really?+
Medium to hard. The rules are easy to simulate, but constraints force an ordered-set or segment-tree approach. The ranking and output formatting add edge cases. Most of the difficulty is reading carefully and not losing points on details.
What edge cases break solutions?+
No documents at all, where the output is zeros with indexer 0 busiest. k greater than indexerCount, so topCount is capped. k equal to 0, giving an empty ranked list. A job finishing exactly at the arrival time, which counts as free. Wraparound when nothing is free after the preferred index.
How should the output array be built?+
Order is total processed, busiest indexer, top-group processed count, total again, then the topCount ranked indexers. Sort indexers by count descending and index ascending. Busiest is the first ranked one. Sum the counts of the first topCount. If total is 0, both share values are 0.
How do I prepare in 48 hours?+
Practice one ordered-set lower-bound problem and one heap-based scheduling simulation. Write the release-then-assign loop from memory. Then test your code against all three examples by hand, especially the wraparound case in example 2. Don't spend time on unrelated topics.