code: func (e *TopNExec) doCompaction() error {
  	newRowChunks := chunk.NewList(e.retTypes(), e.initCap, e.maxChunkSize)
  	newRowPtrs := make([]chunk.RowPtr, 0, e.rowChunks.Len())
  	for _, rowPtr := range e.rowPtrs {
  		newRowPtr := newRowChunks.AppendRow(e.rowChunks.GetRow(rowPtr))
  		newRowPtrs = append(newRowPtrs, newRowPtr)
  	}
  	newRowChunks.GetMemTracker().SetLabel(rowChunksLabel)
  	e.memTracker.ReplaceChild(e.rowChunks.GetMemTracker(), newRowChunks.GetMemTracker())
  	e.rowChunks = newRowChunks
  
  	e.memTracker.Consume(int64(-8 * len(e.rowPtrs)))
  	e.memTracker.Consume(int64(8 * len(newRowPtrs)))
  	e.rowPtrs = newRowPtrs
  	return nil
  }
docs: // doCompaction rebuild the chunks and row pointers to release memory.
  // If we don't do compaction, in a extreme case like the child data is already ascending sorted
  // but we want descending top N, then we will keep all data in memory.
  // But if data is distributed randomly, this function will be called log(n) times.