Memory Pool
MediumOnline Assessment
Simulate a memory allocator that hands out contiguous blocks from a fixed pool using the first-fit rule.
The pool has size cells with addresses 0 to size - 1, all free at the start. Each block has a positive integer id, a start address, and a length, and occupies cells start to start + length - 1. Blocks never overlap. A gap is a maximal run of consecutive free cells (including the run at the very end of the pool). Process commands in order; each command returns one integer. A command that cannot be carried out returns -1 and changes nothing.
["alloc", id, n]: allocate a block ofncells foridin the first-fit position: the lowest address at whichnfree cells in a row begin (equivalently, the first gap, scanning from address 0, with at leastncells; the block goes at the start of that gap). Return its start address. Return-1ifidis already allocated, ifn < 1, or if no gap is large enough.["free", id]: release the block. Return its length, or-1ifidis not allocated.["realloc", id, n]: resize the block toncells. Return-1ifidis not allocated orn < 1. Otherwise:
- If
nis at most the current length, shrink in place (the firstncells are kept) and return the unchanged start address. (nequal to the current length changes nothing.) - Otherwise, if the cells directly after the block are free for long enough (the block can reach
ncells before it runs into the next block or the end of the pool), grow in place and return the unchanged start address. - Otherwise try to move the block: imagine the block lifted out of the pool (its old cells now count as free, and merge with neighbouring free cells), and look for the first-fit position for
ncells as inalloc. If one exists, move the block there and return the new start address (which may overlap its old cells or be lower than its old address). If none exists, return-1and the block stays exactly as it was.
["compact"]: slide every block toward address 0, keeping their relative order, with no gaps between them. Return the number of blocks whose start address changed.["owner", a]: return the id of the block that occupies cella, or-1if the cell is free orais outside0..size-1.- Any other command (an unknown name, or the wrong number of items) returns
-1.
The pool can be very large (up to 10^9 cells), so do not model it cell by cell.
Input: size, an integer, and commands, a list of commands as described.
Output: a list of integers, one per command.
Example 1
- Input:
- [20,[["alloc",1,5],["alloc",2,4],["alloc",3,6],["free",2],["alloc",4,3],["alloc",5,5],["owner",6],["owner",13],["owner",19],["compact"],["alloc",5,5],["owner",18]]]
- Output:
- [0,5,9,4,5,15,4,3,5,2,-1,5]
- Explanation
alloc 1 5takes cells 0-4,alloc 2 4cells 5-8,alloc 3 6cells 9-14. Freeing block 2 releases 4 cells.alloc 4 3goes first-fit into that hole at 5 (the gap 8 stays).alloc 5 5finds no gap of 5 before the end, so it goes to 15. Cell 6 belongs to block 4, 13 to block 3, 19 to block 5.compactslides blocks 4 (stays at 5), 3 (9 to 8) and 5 (15 to 14) down: 2 blocks moved. Allocating id 5 again fails because it is already allocated, and cell 18 still belongs to 5.
Example 2
- Input:
- [12,[["alloc",1,3],["alloc",2,2],["alloc",3,4],["alloc",4,2],["free",1],["realloc",2,5],["realloc",3,6],["realloc",3,3],["owner",8],["alloc",5,3],["compact"],["alloc",5,2]]]
- Output:
- [0,3,5,9,3,0,-1,5,-1,-1,1,10]
- Explanation
- After the first four allocations the blocks are 1 at 0-2, 2 at 3-4, 3 at 5-8, 4 at 9-10, and freeing 1 returns 3.
realloc 2 5cannot grow in place (block 3 starts at 5, so only 2 cells are available), so the block is lifted out and placed first-fit: its old cells and the freed cells 0-2 form one gap of 5 at address 0, so it moves to 0.realloc 3 6can neither grow in place (block 4 is in the way) nor relocate (the biggest gap, its own cells 5-8, has 4 cells), so it returns -1 and nothing changes.realloc 3 3shrinks in place and keeps address 5, so cell 8 is free.alloc 5 3finds no gap of 3 (the free cells are 8 and 11), andcompactmoves only block 4 (from 9 to 8).alloc 5 2then finds cells 10-11.
Example 3
- Input:
- [10,[["alloc",1,4],["alloc",1,2],["alloc",2,0],["alloc",3,7],["free",9],["free",1],["alloc",3,7],["alloc",4,3],["realloc",4,2],["realloc",5,1],["owner",-1],["owner",10],["compact"],["fly"]]]
- Output:
- [0,-1,-1,-1,-1,4,0,7,7,-1,-1,-1,0,-1]
- Explanation
- The duplicate id, the zero length,
free 9(never allocated), the 7-cell request that does not fit around block 1 (only 6 free cells),realloc 5 1(unknown id), the owner queries outside the pool, andflyall return -1 without changing anything. After block 1 is freed (4 cells)alloc 3 7fits at 0 andalloc 4 3at 7. Shrinking block 4 to 2 keeps address 7, andcompactmoves nothing, so it returns 0.
Constraints
- 1 ≤ size ≤ 109
- 0 ≤ commands.length ≤ 200
- Block ids are integers from 1 to 1000; lengths and addresses in commands are integers from -5 to 109