const MaxID, MaxDur
MaxID and MaxDur are what the packed digits hold.
Package blocks encodes a radio rotation, an ordered list of slots (an id and a duration), as strings the caller store...
Package blocks encodes a radio rotation, an ordered list of slots (an id and a duration), as strings the caller stores under its own keys: a header (slot count, total, one total per group), one group string per Size² slots (one sum per block) and one block string per Size slots. Appending is O(1), changing a slot rewrites one block, one group and the header, and finding the slot at a position in the loop scans the group totals, one group's sums and a single block: O(n/Size² + Size), flat up to about two million slots. Inside a block, ids and durations are packed as fixed-width base-64 digits (4 per id, 2 per duration): 6 bytes of deposit per slot.
MaxID and MaxDur are what the packed digits hold.
MaxSlots is the longest rotation a header counts.
Size is the number of slots per block.
Append adds a slot at the end. grp and blk are those of slot Len(h) (Where), "" when it starts a new one. It returns the three strings and the new slot's index.
FindBlock returns the block of group g playing at rest, and the position inside it.
Find is done in three steps, loading the group then the block between them: FindGroup, FindBlock, FindSlot. FindGroup returns the group playing at pos (0 <= pos < Total) and the position inside it; ok is false when pos is out of range.
FindSlot returns the slot of block b playing at rest, its id and the offset into it. Slots of duration 0 are never returned.
Len is the number of slots of a rotation ("" is empty).
PrefixBefore returns the total duration of slots 0..i-1 (0 <= i <= Len).
Set replaces slot i's id and duration (0 takes it out of the loop).
Slot returns the id and duration of slot i, from its block.
Total is the sum of all durations.
Where returns the group and block (counted from the start of the rotation) that hold slot i.