ppm_model.go
func (c *context) shrinkStates(states []state, size int) []state {
	i1 := units2Index[(len(states)+1)>>1]
	i2 := units2Index[(size+1)>>1]

	if size == 1 {
		// store state in context, and free states block
		n := c.statesIndex()
		c.s[1] = states[0]
		states = c.s[1:]
		c.a.addFreeBlock(n, i1)
	} else if i1 != i2 {
		if n := c.a.removeFreeBlock(i2); n > 0 {
			// allocate new block and copy
			copy(c.a.states[n:], states[:size])
			states = c.a.states[n:]
			// free old block
			c.a.addFreeBlock(c.statesIndex(), i1)
			c.setStatesIndex(n)
		} else {
			// split current block, and free units not needed
			n = c.statesIndex() + index2Units[i2]<<1
			u := index2Units[i1] - index2Units[i2]
			c.a.freeUnits(n, u)
		}
	}
	c.setNumStates(size)
	return states[:size]
}
func (c *context) shrinkStates(states []state, size int) []state {
	i1 := units2Index[(len(states)+1)>>1]
	i2 := units2Index[(size+1)>>1]

	if size == 1 {
		// store state in context, and free states block
		n := c.statesIndex()
		c.s[1] = states[0]
		states = c.s[1:]
		c.a.addFreeBlock(n, i1)
	} else if i1 != i2 {
		if n := c.a.removeFreeBlock(i2); n > 0 {
			// allocate new block and copy
			copy(c.a.states[n:], states[:size])
			states = c.a.states[n:]
			// free old block
			c.a.addFreeBlock(c.statesIndex(), i1)
			c.setStatesIndex(n)
		} else {
			// split current block, and free units not needed
			n = c.statesIndex() + index2Units[i2]<<1
			u := index2Units[i1] - index2Units[i2]
			c.a.freeUnits(n, u)
		}
	}
	c.setNumStates(size)
	return states[:size]
}
// shrinkStates shrinks the state list down to size states