class TaskJuggler::Allocation

The Allocation is key object in TaskJuggler. It contains a description how Resources are assigned to a Task. Each allocation holds a non-empty list of candidate resources. For each time slot one candidate will be assigned if any are available. A selectionMode controls the order in which the resources are checked for availability. The first available one is selected.

Attributes

atomic[RW]
lockedResource[RW]
mandatory[RW]
persistent[RW]
selectionMode[R]
shifts[RW]

Public Class Methods

new(candidates, selectionMode = 1, persistent = false, mandatory = false, atomic = false) click to toggle source

Create an Allocation object. The candidates list must at least contain one Resource reference.

# File lib/taskjuggler/Allocation.rb, line 31
def initialize(candidates, selectionMode = 1, persistent = false,
               mandatory = false, atomic = false)
  @candidates = candidates
  # The selection mode determines how the candidate is selected from the
  # list of candidates.
  # 0 : 'order'        : select by order of list
  # 1 : 'minallocated' : select candidate with lowest allocation
  #                      probability
  # 2 : 'minloaded'    : select candidate with lowest allocated overall
  #                      load
  # 3 : 'maxloaded'    : select candidate with highest allocated overall
  #                      load
  # 4 : 'random'       : select a random candidate
  @selectionMode = selectionMode
  @atomic = atomic
  @persistent = persistent
  @mandatory = mandatory
  @shifts = nil
  @staticCandidates = nil
end

Public Instance Methods

addCandidate(candidate) click to toggle source

Append another candidate to the candidates list.

# File lib/taskjuggler/Allocation.rb, line 61
def addCandidate(candidate)
  @candidates << candidate
end
candidates(scenarioIdx = nil) click to toggle source

Return the candidate list sorted according to the selectionMode.

# File lib/taskjuggler/Allocation.rb, line 74
def candidates(scenarioIdx = nil)
  # In case we have selection criteria that results in a static list, we
  # can use the previously determined list.
  return @staticCandidates if @staticCandidates

  if scenarioIdx.nil? || @selectionMode == 0 # declaration order
    return @candidates
  end

  if @selectionMode == 4 # random
    # For a random sorting we put the candidates in a hash with a random
    # number as key. Then we sort the hash according to the random keys an
    # use the resuling sequence of the values.
    hash = {}
    @candidates.each { |c| hash[rand] = c }
    twinList = hash.sort { |x, y| x[0] <=> y[0] }
    list = []
    twinList.each { |k, v| list << v }
    return list
  end

  list = @candidates.sort do |x, y|
    case @selectionMode
    when 1 # lowest alloc probability
      if @persistent
        # For persistent resources we use a more sophisticated heuristic
        # than just the criticalness of the resource. Instead, we
        # look at the already allocated slots of the resource. This will
        # reduce the probability to pick a persistent resource that was
        # already allocated for a higher priority or more critical task.
        if (cmp = x.bookedEffort(scenarioIdx) <=>
                  y.bookedEffort(scenarioIdx)) == 0
          x['criticalness', scenarioIdx] <=> y['criticalness', scenarioIdx]
        else
          cmp
        end
      else
        x['criticalness', scenarioIdx] <=> y['criticalness', scenarioIdx]
      end
    when 2 # lowest allocated load
      x.bookedEffort(scenarioIdx) <=> y.bookedEffort(scenarioIdx)
    when 3 # hightes allocated load
      y.bookedEffort(scenarioIdx) <=> x.bookedEffort(scenarioIdx)
    else
      raise "Unknown selection mode #{@selectionMode}"
    end
  end

  @staticCandidates = list if @selectionMode == 1 && !@persistent

  list
end
onShift?(sbIdx) click to toggle source

Returns true if we either have no shifts defined or the defined shifts are active at date specified by global scoreboard index sbIdx.

# File lib/taskjuggler/Allocation.rb, line 67
def onShift?(sbIdx)
  return @shifts.onShift?(sbIdx) if @shifts

  true
end
setSelectionMode(str) click to toggle source

Set the selection mode identified by name specified in str. For efficiency reasons, we turn the name into an Integer value.

# File lib/taskjuggler/Allocation.rb, line 54
def setSelectionMode(str)
  modes = %w( order minallocated minloaded maxloaded random )
  @selectionMode = modes.index(str)
  raise "Unknown selection mode #{str}" if @selectionMode.nil?
end