updateCPULoad :: (Node.List, Instance.List)
              -> Container.Container AllReports
              -> Set.Set String
              -> [ String ]
              -> Result (Node.List, Instance.List)
updateCPULoad (nl, il) reports xeninsts evacuated = do
  il' <- Traversable.mapM (updateCPUInstance nl reports xeninsts evacuated) il
  let addNodeUtil n delta = n { Node.utilLoad = addUtil (Node.utilLoad n) delta
                              , Node.utilLoadForth =
                                  addUtil (Node.utilLoadForth n) delta
                              }
  let updateNodeUtil nnl inst_old inst_new =
        let delta = subUtil (Instance.util inst_new) $ Instance.util inst_old
            nidx = Instance.pNode inst_old
            n = Container.find nidx nnl
            n' = addNodeUtil n delta
        in Container.add nidx n' nnl
  let nl' = foldl (\nnl i -> updateNodeUtil nnl (Container.find i il)
                               $ Container.find i il') nl $ Container.keys il
  return (nl', il')

-- | For an instance, given by name, verify if an individual load report is
-- available again.
updateCPULoad :: (Node.List, Instance.List)
              -> Container.Container AllReports
              -> Set.Set String
              -> [ String ]
              -> Result (Node.List, Instance.List)
updateCPULoad (nl, il) reports xeninsts evacuated = do
  il' <- Traversable.mapM (updateCPUInstance nl reports xeninsts evacuated) il
  let addNodeUtil n delta = n { Node.utilLoad = addUtil (Node.utilLoad n) delta
                              , Node.utilLoadForth =
                                  addUtil (Node.utilLoadForth n) delta
                              }
  let updateNodeUtil nnl inst_old inst_new =
        let delta = subUtil (Instance.util inst_new) $ Instance.util inst_old
            nidx = Instance.pNode inst_old
            n = Container.find nidx nnl
            n' = addNodeUtil n delta
        in Container.add nidx n' nnl
  let nl' = foldl (\nnl i -> updateNodeUtil nnl (Container.find i il)
                               $ Container.find i il') nl $ Container.keys il
  return (nl', il')

-- | For an instance, given by name, verify if an individual load report is
-- available again.
updateCPULoad (nl, il) reports xeninsts evacuated = do
  il' <- Traversable.mapM (updateCPUInstance nl reports xeninsts evacuated) il
  let addNodeUtil n delta = n { Node.utilLoad = addUtil (Node.utilLoad n) delta
                              , Node.utilLoadForth =
                                  addUtil (Node.utilLoadForth n) delta
                              }
  let updateNodeUtil nnl inst_old inst_new =
        let delta = subUtil (Instance.util inst_new) $ Instance.util inst_old
            nidx = Instance.pNode inst_old
            n = Container.find nidx nnl
            n' = addNodeUtil n delta
        in Container.add nidx n' nnl
  let nl' = foldl (\nnl i -> updateNodeUtil nnl (Container.find i il)
                               $ Container.find i il') nl $ Container.keys il
  return (nl', il')

-- | For an instance, given by name, verify if an individual load report is
-- available again.