func()

in freelist.go [298:379]


func (f *freelist) RemoveRegion(removed region) {
	i := sort.Search(len(f.regions), func(i int) bool {
		_, end := f.regions[i].Range()
		return removed.id <= end
	})
	if i < 0 || i >= len(f.regions) {
		return
	}

	current := &f.regions[i]
	if current.id == removed.id && current.count == removed.count {
		// fast path: entry can be completely removed
		f.regions = append(f.regions[:i], f.regions[i+1:]...)
		f.avail -= uint(removed.count)
		return
	}

	var total uint
	removedStart, removedEnd := removed.Range()
	for removedStart < removedEnd && i < len(f.regions) {
		current := &f.regions[i]

		if removedStart < current.id {
			// Gap: advance removedStart, so to deal with holes when removing the all regions
			//      matching the input region
			removedStart = current.id
			continue
		}

		count := uint32(removedEnd - removedStart)
		if removedStart == current.id {
			if current.count < count {
				count = current.count
			}

			// remove entry:
			current.id = current.id + PageID(count)
			current.count -= count
			if current.count == 0 {
				// remove region from freelist -> i will point to next region if
				// `removed` overlaps 2 non-merged regions
				f.regions = append(f.regions[:i], f.regions[i+1:]...)
			} else {
				// overlapping region, but old region must be preserved:
				i++
			}

			removedStart += PageID(count)
			total += uint(count)
		} else {
			// split current region in removedStart
			keep := uint32(removedStart - current.id)
			leftover := region{
				id:    removedStart,
				count: current.count - keep,
			}
			current.count = keep

			// remove sub-region from leftover
			if leftover.count < count {
				count = leftover.count
			}
			leftover.id += PageID(count)
			leftover.count -= count

			total += uint(count)
			removedStart += PageID(count)
			i++ // advance to next region

			// insert new entry into regionList if removed did remove region in
			// middle of old region
			if leftover.count > 0 {
				f.regions = append(f.regions, region{})
				copy(f.regions[i+1:], f.regions[i:])
				f.regions[i] = leftover
				break // no more region to split from
			}
		}
	}

	f.avail -= total
}