code: func (cm *ClientManager) updateRecharge(now mclock.AbsTime) {
  	lastUpdate := cm.rcLastUpdate
  	cm.rcLastUpdate = now
  	// updating is done in multiple steps if node buffers are filled and sumRecharge
  	// is decreased before the given target time
  	for cm.sumRecharge > 0 {
  		bonusRatio := cm.curve.ValueAt(cm.sumRecharge) / float64(cm.sumRecharge)
  		if bonusRatio < 1 {
  			bonusRatio = 1
  		}
  		dt := now - lastUpdate
  		// fetch the client that finishes first
  		rcqNode := cm.rcQueue.PopItem().(*ClientNode) // if sumRecharge > 0 then the queue cannot be empty
  		// check whether it has already finished
  		dtNext := mclock.AbsTime(float64(rcqNode.rcFullIntValue-cm.rcLastIntValue) / bonusRatio)
  		if dt < dtNext {
  			// not finished yet, put it back, update integrator according
  			// to current bonusRatio and return
  			cm.rcQueue.Push(rcqNode, -rcqNode.rcFullIntValue)
  			cm.rcLastIntValue += int64(bonusRatio * float64(dt))
  			return
  		}
  		lastUpdate += dtNext
  		// finished recharging, update corrBufValue and sumRecharge if necessary and do next step
  		if rcqNode.corrBufValue < int64(rcqNode.params.BufLimit) {
  			rcqNode.corrBufValue = int64(rcqNode.params.BufLimit)
  			cm.updateCapFactor(lastUpdate, true)
  			cm.sumRecharge -= rcqNode.params.MinRecharge
  		}
  		cm.rcLastIntValue = rcqNode.rcFullIntValue
  	}
  }
docs: // updateRecharge updates the recharge integrator and checks the recharge queue
  // for nodes with recently filled buffers