.. in a given set. This is similar to FindFirst function in our Python
code-base, but this one automatically picks the element after the end of
the set, if the set has no holes.

Signed-off-by: Petr Pudlak <[email protected]>
---
 src/Ganeti/Utils.hs | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/src/Ganeti/Utils.hs b/src/Ganeti/Utils.hs
index 7e403ec..91d8148 100644
--- a/src/Ganeti/Utils.hs
+++ b/src/Ganeti/Utils.hs
@@ -28,6 +28,7 @@ module Ganeti.Utils
   , debugFn
   , debugXy
   , sepSplit
+  , findFirst
   , stdDev
   , if'
   , select
@@ -91,6 +92,8 @@ import Data.Function (on)
 import Data.IORef
 import Data.List
 import qualified Data.Map as M
+import Data.Maybe (fromMaybe)
+import qualified Data.Set as S
 import Foreign.C.Types (CTime(..))
 import Numeric (showOct)
 import System.Directory (renameFile, createDirectoryIfMissing)
@@ -147,6 +150,15 @@ sepSplit sep s
   where (x, xs) = break (== sep) s
         ys = drop 1 xs
 
+-- | Finds the first unused element in a set starting from a given base.
+findFirst :: (Ord a, Enum a) => a -> S.Set a -> a
+findFirst base xs =
+  case S.splitMember base xs of
+    (_, False, _) -> base
+    (_, True, ys) -> fromMaybe (succ base) $
+      (fmap fst . find (uncurry (<)) . zip [succ base..] . S.toAscList $ ys)
+      `mplus` fmap (succ . fst) (S.maxView ys)
+
 -- | Simple pluralize helper
 plural :: Int -> String -> String -> String
 plural 1 s _ = s
-- 
1.9.1.423.g4596e3a

Reply via email to