tieredAlloc :: AllocMethod
tieredAlloc nl il limit newinst allocnodes ixes cstats =
  case iterateAlloc nl il limit newinst allocnodes ixes cstats of
    Bad s -> Bad s
    Ok (errs, nl', il', ixes', cstats') ->
      let newsol = Ok (errs, nl', il', ixes', cstats')
          ixes_cnt = length ixes'
          (stop, newlimit) = case limit of
                               Nothing -> (False, Nothing)
                               Just n -> (n <= ixes_cnt,
                                            Just (n - ixes_cnt))
          sortedErrs = map fst $ sortBy (comparing snd) errs
          suffShrink = sufficesShrinking (fromMaybe emptyAllocSolution
                                          . flip (tryAlloc nl' il') allocnodes)
                       newinst
          bigSteps = filter isJust . map suffShrink . reverse $ sortedErrs
      in if stop then newsol else
          case bigSteps of
            Just newinst':_ -> tieredAlloc nl' il' newlimit
                               newinst' allocnodes ixes' cstats'
            _ -> case Instance.shrinkByType newinst . last $ sortedErrs of
                   Bad _ -> newsol
                   Ok newinst' -> tieredAlloc nl' il' newlimit
                                  newinst' allocnodes ixes' cstats'

-- * Formatting functions

-- | Given the original and final nodes, computes the relocation description.
tieredAlloc :: AllocMethod
tieredAlloc nl il limit newinst allocnodes ixes cstats =
  case iterateAlloc nl il limit newinst allocnodes ixes cstats of
    Bad s -> Bad s
    Ok (errs, nl', il', ixes', cstats') ->
      let newsol = Ok (errs, nl', il', ixes', cstats')
          ixes_cnt = length ixes'
          (stop, newlimit) = case limit of
                               Nothing -> (False, Nothing)
                               Just n -> (n <= ixes_cnt,
                                            Just (n - ixes_cnt))
          sortedErrs = map fst $ sortBy (comparing snd) errs
          suffShrink = sufficesShrinking (fromMaybe emptyAllocSolution
                                          . flip (tryAlloc nl' il') allocnodes)
                       newinst
          bigSteps = filter isJust . map suffShrink . reverse $ sortedErrs
      in if stop then newsol else
          case bigSteps of
            Just newinst':_ -> tieredAlloc nl' il' newlimit
                               newinst' allocnodes ixes' cstats'
            _ -> case Instance.shrinkByType newinst . last $ sortedErrs of
                   Bad _ -> newsol
                   Ok newinst' -> tieredAlloc nl' il' newlimit
                                  newinst' allocnodes ixes' cstats'

-- * Formatting functions

-- | Given the original and final nodes, computes the relocation description.
tieredAlloc nl il limit newinst allocnodes ixes cstats =
  case iterateAlloc nl il limit newinst allocnodes ixes cstats of
    Bad s -> Bad s
    Ok (errs, nl', il', ixes', cstats') ->
      let newsol = Ok (errs, nl', il', ixes', cstats')
          ixes_cnt = length ixes'
          (stop, newlimit) = case limit of
                               Nothing -> (False, Nothing)
                               Just n -> (n <= ixes_cnt,
                                            Just (n - ixes_cnt))
          sortedErrs = map fst $ sortBy (comparing snd) errs
          suffShrink = sufficesShrinking (fromMaybe emptyAllocSolution
                                          . flip (tryAlloc nl' il') allocnodes)
                       newinst
          bigSteps = filter isJust . map suffShrink . reverse $ sortedErrs
      in if stop then newsol else
          case bigSteps of
            Just newinst':_ -> tieredAlloc nl' il' newlimit
                               newinst' allocnodes ixes' cstats'
            _ -> case Instance.shrinkByType newinst . last $ sortedErrs of
                   Bad _ -> newsol
                   Ok newinst' -> tieredAlloc nl' il' newlimit
                                  newinst' allocnodes ixes' cstats'

-- * Formatting functions

-- | Given the original and final nodes, computes the relocation description.