Commit 8f48f67d authored by Iustin Pop's avatar Iustin Pop
Browse files

htools: add optional limit to allocation count



Currently, the tieredAlloc/iterateAlloc functions will not return
until the allocation fails; this means unit-testing their
functionality (e.g. that an instance can be allocated) is slow, since
they will allocate all possible instances.

This patch adds an optional limit that allows allocation to return
early; this makes the cluster unittests twice as fast.
Signed-off-by: default avatarIustin Pop <iustin@google.com>
Reviewed-by: default avatarGuido Trotter <ultrotter@google.com>
parent db56cfc4
......@@ -1036,45 +1036,58 @@ tryNodeEvac _ ini_nl ini_il mode idxs =
-- | Recursively place instances on the cluster until we're out of space.
iterateAlloc :: Node.List
-> Instance.List
-> Maybe Int
-> Instance.Instance
-> AllocNodes
-> [Instance.Instance]
-> [CStats]
-> Result AllocResult
iterateAlloc nl il newinst allocnodes ixes cstats =
iterateAlloc nl il limit newinst allocnodes ixes cstats =
let depth = length ixes
newname = printf "new-%d" depth::String
newidx = length (Container.elems il) + depth
newi2 = Instance.setIdx (Instance.setName newinst newname) newidx
newlimit = fmap (flip (-) 1) limit
in case tryAlloc nl il newi2 allocnodes of
Bad s -> Bad s
Ok (AllocSolution { asFailures = errs, asSolutions = sols3 }) ->
let newsol = Ok (collapseFailures errs, nl, il, ixes, cstats) in
case sols3 of
[] -> Ok (collapseFailures errs, nl, il, ixes, cstats)
[] -> newsol
(xnl, xi, _, _):[] ->
iterateAlloc xnl (Container.add newidx xi il)
newinst allocnodes (xi:ixes)
(totalResources xnl:cstats)
if limit == Just 0
then newsol
else iterateAlloc xnl (Container.add newidx xi il)
newlimit newinst allocnodes (xi:ixes)
(totalResources xnl:cstats)
_ -> Bad "Internal error: multiple solutions for single\
\ allocation"
-- | The core of the tiered allocation mode.
tieredAlloc :: Node.List
-> Instance.List
-> Maybe Int
-> Instance.Instance
-> AllocNodes
-> [Instance.Instance]
-> [CStats]
-> Result AllocResult
tieredAlloc nl il newinst allocnodes ixes cstats =
case iterateAlloc nl il newinst allocnodes ixes cstats of
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)) in
if stop then newsol else
case Instance.shrinkByType newinst . fst . last $
sortBy (comparing snd) errs of
Bad _ -> Ok (errs, nl', il', ixes', cstats')
Ok newinst' ->
tieredAlloc nl' il' newinst' allocnodes ixes' cstats'
Bad _ -> newsol
Ok newinst' -> tieredAlloc nl' il' newlimit
newinst' allocnodes ixes' cstats'
-- | Compute the tiered spec string description from a list of
-- allocated instances.
......
......@@ -866,7 +866,7 @@ prop_ClusterCanTieredAlloc node inst =
il = Container.empty
allocnodes = Cluster.genAllocNodes defGroupList nl rqnodes True
in case allocnodes >>= \allocnodes' ->
Cluster.tieredAlloc nl il inst allocnodes' [] [] of
Cluster.tieredAlloc nl il (Just 1) inst allocnodes' [] [] of
Types.Bad _ -> False
Types.Ok (_, _, il', ixes, cstats) -> not (null ixes) &&
IntMap.size il' == length ixes &&
......@@ -909,7 +909,7 @@ prop_ClusterAllocBalance =
allocnodes = Cluster.genAllocNodes defGroupList nl' 2 True
i_templ = createInstance Types.unitMem Types.unitDsk Types.unitCpu
in case allocnodes >>= \allocnodes' ->
Cluster.iterateAlloc nl' il i_templ allocnodes' [] [] of
Cluster.iterateAlloc nl' il (Just 5) i_templ allocnodes' [] [] of
Types.Bad _ -> False
Types.Ok (_, xnl, il', _, _) ->
let ynl = Container.add (Node.idx hnode) hnode xnl
......
......@@ -302,7 +302,7 @@ main = do
(_, trl_nl, trl_il, trl_ixes, _) <-
if stop_allocation
then return result_noalloc
else exitifbad (Cluster.tieredAlloc nl il (iofspec tspec)
else exitifbad (Cluster.tieredAlloc nl il Nothing (iofspec tspec)
allocnodes [] [])
let spec_map' = Cluster.tieredSpecMap trl_ixes
......@@ -324,7 +324,8 @@ main = do
(ereason, fin_nl, fin_il, ixes, _) <-
if stop_allocation
then return result_noalloc
else exitifbad (Cluster.iterateAlloc nl il reqinst allocnodes [] [])
else exitifbad (Cluster.iterateAlloc nl il Nothing
reqinst allocnodes [] [])
let allocs = length ixes
sreason = reverse $ sortBy (comparing snd) ereason
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment