One free list means every allocation scans blocks of every size. Segregated free lists fix that by bucketing free blocks into bins by size class. Today you build the bins and file each freed block into the right one.
Bucket free blocks into size-class bins, filing a freed block into the bin for its size.
A single free list forces every search to wade through free blocks of all sizes. Segregated free lists speed this up by keeping several lists, one per size class: small blocks in one bin, larger ones in another. A freed block is filed into the bin matching its size, so a later request can jump straight to blocks of roughly the right size instead of scanning everything.
Today is the refactor from one list to an array of bins. Pick a simple class
function - here, block sizes 24, 32, 40, and 48 get their own bins and everything
56 and up shares the last bin - and change insert and unlink to work on
bins[classOf(size)] instead of a single head. This changes how free blocks are
organized, so allocation (next lesson) and coalescing (the one after) both have to
learn the new structure. The address-order Blocks walk and the boundary tags are
untouched.
const nbins = 5func classOf(size int) int {c := (size - minBlock) / 8 // 24->0, 32->1, 40->2, 48->3if c >= nbins { c = nbins - 1 } // 56+ share the last binreturn c}// replace the single freeHead with bins [nbins]int; insert a freed// block into bins[classOf(size)]; unlink from whichever bin holds it