func (lbs *LoadBasedAlg) initJobClassesMap(jobsByRequestor map[string][]*jobState) {
	classNameWithLeastWorkers := lbs.classByDescLoadPct[len(lbs.classByDescLoadPct)-1]
	for requestor, jobs := range jobsByRequestor {
		var jc *jobClass
		var ok bool
		className := GetRequestorClass(requestor, lbs.requestorReToClassMap)
		jc, ok = lbs.jobClasses[className]
		if !ok {
			lbs.config.stat.Counter(stats.SchedLBSUnknownJobCounter).Inc(1)
			jc = lbs.jobClasses[classNameWithLeastWorkers]
			log.Errorf("%s is not a recognized job class assigning to class (%s)", className, classNameWithLeastWorkers)
		}
		if jc.origTargetLoadPct == 0 {
			log.Errorf("%s worker allocation (load %% is 0), ignoring %d jobs", requestor, len(jobs))
			lbs.config.stat.Counter(stats.SchedLBSIgnoredJobCounter).Inc(1)
			continue
		}
		for _, job := range jobs {
			_, ok := jc.jobsByNumRunningTasks[job.TasksRunning]
			if !ok {
				jc.jobsByNumRunningTasks[job.TasksRunning] = []jobWaitingTasks{}
			}
			waitingTasks := []*taskState{}
			for _, taskState := range job.Tasks {
				if taskState.Status == domain.NotStarted {
					waitingTasks = append(waitingTasks, taskState)
					jc.origNumWaitingTasks++
				}
			}
			jc.jobsByNumRunningTasks[job.TasksRunning] = append(jc.jobsByNumRunningTasks[job.TasksRunning], jobWaitingTasks{jobState: job, waitingTasks: waitingTasks})
			if job.TasksRunning > jc.maxTaskRunningMapIndex {
				jc.maxTaskRunningMapIndex = job.TasksRunning
			}
			jc.origNumRunningTasks += job.TasksRunning
		}
		jc.numWaitingTasks = jc.origNumWaitingTasks
	}
}
initJobClassesMap builds the map of waiting jobs' requestors to jobClass objects
if we see a job whose class % not defined, assign the job to the class with the
smallest class load %
package server
import (
	"fmt"
	"math"
	"regexp"
	"sort"
	"sync"
	"time"
	log "github.com/sirupsen/logrus"
	"github.com/twitter/scoot/common/stats"
	"github.com/twitter/scoot/scheduler/domain"
)
const (
	under int = iota
	over
)
var (
	DefaultLoadBasedSchedulerClassPercents = map[string]int32{
		"land":       40,
		"diff":       25,
		"sandbox":    10,
		"regression": 17,
		"ktf":        3,
		"coverage":   2,
		"tryout":     2,
		"unknown":    1,
	}
	DefaultRequestorToClassMap = map[string]string{
		"land.*":       "land",
		"diff.*":       "diff",
		"sandbox.*":    "sandbox",
		"regression.*": "regression",
		"CI.*":         "regression",
		"jenkins.*":    "ktf",
		"ktf.*":        "ktf",
		"coverage.*":   "coverage",
		"tryout.*":     "tryout",
	}
	DefaultMinRebalanceTime = time.Duration(4 * time.Minute)
	MaxTaskDuration         = time.Duration(4 * time.Hour)
)
type LoadBasedAlgConfig struct {
	classLoadPercents       map[string]int
	classLoadPercentsMu     sync.RWMutex
	requestorReToClassMap   map[string]string
	requestorReToClassMapMU sync.RWMutex
	rebalanceThreshold     int
	rebalanceThresholdMu   sync.RWMutex
	rebalanceMinDuration   time.Duration
	rebalanceMinDurationMu sync.RWMutex
	classByDescLoadPct []string
	stat stats.StatsReceiver
}
type LoadBasedAlg struct {
	config     *LoadBasedAlgConfig
	jobClasses map[string]*jobClass
	totalUnusedEntitlement          int
	exceededRebalanceThresholdStart time.Time
	classLoadPercents     map[string]int
	requestorReToClassMap map[string]string
	classByDescLoadPct             []string
	tasksByJobClassAndStartTimeSec map[taskClassAndStartKey]taskStateByJobIDTaskID
	nopAllocationsCnt int  
}
func NewLoadBasedAlg(config *LoadBasedAlgConfig, tasksByJobClassAndStartTimeSec map[taskClassAndStartKey]taskStateByJobIDTaskID) *LoadBasedAlg {
	lbs := &LoadBasedAlg{
		config:                          config,
		jobClasses:                      map[string]*jobClass{},
		exceededRebalanceThresholdStart: time.Time{},
		tasksByJobClassAndStartTimeSec:  tasksByJobClassAndStartTimeSec,
	}
	return lbs
}
type jobWaitingTasks struct {
	jobState     *jobState
	waitingTasks []*taskState
}
type jobClass struct {
	className string
	jobsByNumRunningTasks map[int][]jobWaitingTasks
	maxTaskRunningMapIndex int
	origNumWaitingTasks int
	origNumRunningTasks int
	origTargetLoadPct int
	origNumTargetedWorkers int
	numTasksToStart int
	numWaitingTasks int
	tempEntitlement int
	tempNormalizedPct int
}
func (jc *jobClass) String() string {
	return fmt.Sprintf("%s:TargetLoadPct:%d, origTasksWaiting:%d, origTasksRunning:%d, origTargetWorkers:%d, TasksToStart:%d, remainingWaitingTasks:%d, tempEntitlement:%d, tempNormalizedPct:%d",
		jc.className,
		jc.origTargetLoadPct,
		jc.origNumWaitingTasks,
		jc.origNumRunningTasks,
		jc.origNumTargetedWorkers,
		jc.numTasksToStart,
		jc.numWaitingTasks,
		jc.tempEntitlement,
		jc.tempNormalizedPct)
}
func (lbs *LoadBasedAlg) GetTasksToBeAssigned(jobsNotUsed []*jobState, stat stats.StatsReceiver, cs *clusterState,
	jobsByRequestor map[string][]*jobState) ([]*taskState, []*taskState) {
	lbs.classLoadPercents = lbs.LocalCopyClassLoadPercents()
	lbs.requestorReToClassMap = lbs.getRequestorToClassMap()
	lbs.classByDescLoadPct = lbs.getClassByDescLoadPct()
	numWorkers := len(cs.nodes)
	lbs.initOrigNumTargetedWorkers(numWorkers)
	lbs.initJobClassesMap(jobsByRequestor)
	rebalanced := false
	var tasksToStop []*taskState
	if lbs.getRebalanceMinimumDuration() > 0 && lbs.getRebalanceThreshold() > 0 {
		currentPctSpread := lbs.getCurrentPercentsSpread(numWorkers)
		if currentPctSpread > lbs.getRebalanceThreshold() {
			nilTime := time.Time{}
			if lbs.exceededRebalanceThresholdStart == nilTime {
				lbs.exceededRebalanceThresholdStart = time.Now()
			} else if time.Now().Sub(lbs.exceededRebalanceThresholdStart) > lbs.config.rebalanceMinDuration {
				tasksToStop = lbs.rebalanceClassTasks(jobsByRequestor, numWorkers)
				lbs.exceededRebalanceThresholdStart = time.Time{}
				rebalanced = true
			}
		}
	}
	if !rebalanced {
		lbs.computeNumTasksToStart(cs.numFree())
	}
	tasksToStart := lbs.buildTaskStartList()
	for _, jc := range lbs.jobClasses {
		stat.Gauge(fmt.Sprintf("%s_%s", stats.SchedJobClassTasksStarting, jc.className)).Update(int64(jc.numTasksToStart))
		stat.Gauge(fmt.Sprintf("%s_%s", stats.SchedJobClassTasksWaiting, jc.className)).Update(int64(jc.origNumWaitingTasks - jc.numTasksToStart))
		stat.Gauge(fmt.Sprintf("%s_%s", stats.SchedJobClassTasksRunning, jc.className)).Update(int64(jc.origNumRunningTasks))
		stat.Gauge(fmt.Sprintf("%s_%s", stats.SchedJobClassDefinedPct, jc.className)).Update(int64(jc.origTargetLoadPct))
		finalPct := int(math.Round(float64(jc.origNumRunningTasks+jc.numTasksToStart) / float64(int64(numWorkers)*100.0)))
		stat.Gauge(fmt.Sprintf("%s_%s", stats.SchedJobClassActualPct, jc.className)).Update(int64(finalPct))
	}
	if len(tasksToStart) > 0 || len(tasksToStop) > 0 {
		log.Debugf("Returning %d start tasks, %d stop tasks, for %d free nodes out of %d total nodes.\n"+
			"(%d calls to GetTasksToBeAssigned() with no tasks assigned)\n",
			len(tasksToStart), len(tasksToStop), cs.numFree(), len(cs.nodes), lbs.nopAllocationsCnt)
		lbs.nopAllocationsCnt = 0
	} else {
		lbs.nopAllocationsCnt++
	}
	return tasksToStart, tasksToStop
}
func (lbs *LoadBasedAlg) initOrigNumTargetedWorkers(numWorkers int) {
	lbs.jobClasses = map[string]*jobClass{}
	totalWorkers := 0
	firstClass := true
	for _, className := range lbs.classByDescLoadPct {
		jc := &jobClass{className: className, origTargetLoadPct: lbs.classLoadPercents[className], jobsByNumRunningTasks: map[int][]jobWaitingTasks{}}
		lbs.jobClasses[className] = jc
		if firstClass {
			firstClass = false
			continue
		}
		targetNumWorkers := int(math.Floor(float64(numWorkers) * float64(jc.origTargetLoadPct) / 100.0))
		jc.origNumTargetedWorkers = targetNumWorkers
		totalWorkers += targetNumWorkers
	}
	lbs.jobClasses[lbs.classByDescLoadPct[0]].origNumTargetedWorkers = numWorkers - totalWorkers
}