Statistics
| Branch: | Tag: | Revision:

root / Ganeti / HTools / Container.hs @ 71e13e48

History | View | Annotate | Download (2.8 kB)

1 e4f08c46 Iustin Pop
{-| Module abstracting the node and instance container implementation.
2 e4f08c46 Iustin Pop
3 e4f08c46 Iustin Pop
This is currently implemented on top of an 'IntMap', which seems to
4 e4f08c46 Iustin Pop
give the best performance for our workload.
5 e4f08c46 Iustin Pop
6 e4f08c46 Iustin Pop
-}
7 e4f08c46 Iustin Pop
8 669d7e3d Iustin Pop
module Ganeti.HTools.Container
9 e4f08c46 Iustin Pop
    (
10 e4f08c46 Iustin Pop
     -- * Types
11 e4f08c46 Iustin Pop
     Container
12 4333a887 Iustin Pop
    , Key
13 e4f08c46 Iustin Pop
     -- * Creation
14 e4f08c46 Iustin Pop
    , empty
15 e4f08c46 Iustin Pop
    , fromAssocList
16 e4f08c46 Iustin Pop
     -- * Query
17 e4f08c46 Iustin Pop
    , size
18 e4f08c46 Iustin Pop
    , find
19 e4f08c46 Iustin Pop
     -- * Update
20 e4f08c46 Iustin Pop
    , add
21 e4f08c46 Iustin Pop
    , addTwo
22 e4f08c46 Iustin Pop
    , remove
23 ec18dca9 Iustin Pop
    , IntMap.map
24 5d1baf63 Iustin Pop
    , IntMap.mapAccum
25 e4f08c46 Iustin Pop
    -- * Conversion
26 e4f08c46 Iustin Pop
    , elems
27 1fd47ca2 Iustin Pop
    , keys
28 262a08a2 Iustin Pop
    -- * Element functions
29 262a08a2 Iustin Pop
    , nameOf
30 262a08a2 Iustin Pop
    , maxNameLen
31 262a08a2 Iustin Pop
    , findByName
32 e4f08c46 Iustin Pop
    ) where
33 e4f08c46 Iustin Pop
34 e4f08c46 Iustin Pop
import qualified Data.IntMap as IntMap
35 e4f08c46 Iustin Pop
36 262a08a2 Iustin Pop
import qualified Ganeti.HTools.Types as T
37 262a08a2 Iustin Pop
38 e4f08c46 Iustin Pop
type Key = IntMap.Key
39 e4f08c46 Iustin Pop
type Container = IntMap.IntMap
40 e4f08c46 Iustin Pop
41 e4f08c46 Iustin Pop
-- | Create an empty container.
42 e4f08c46 Iustin Pop
empty :: Container a
43 e4f08c46 Iustin Pop
empty = IntMap.empty
44 e4f08c46 Iustin Pop
45 e4f08c46 Iustin Pop
-- | Returns the number of elements in the map.
46 e4f08c46 Iustin Pop
size :: Container a -> Int
47 e4f08c46 Iustin Pop
size = IntMap.size
48 e4f08c46 Iustin Pop
49 e4f08c46 Iustin Pop
-- | Locate a key in the map (must exist).
50 e4f08c46 Iustin Pop
find :: Key -> Container a -> a
51 e4f08c46 Iustin Pop
find k c = c IntMap.! k
52 e4f08c46 Iustin Pop
53 e4f08c46 Iustin Pop
-- | Locate a keyin the map returning a default value if not existing.
54 e4f08c46 Iustin Pop
findWithDefault :: a -> Key -> Container a -> a
55 e4f08c46 Iustin Pop
findWithDefault = IntMap.findWithDefault
56 e4f08c46 Iustin Pop
57 e4f08c46 Iustin Pop
-- | Add or update one element to the map.
58 e4f08c46 Iustin Pop
add :: Key -> a -> Container a -> Container a
59 e4f08c46 Iustin Pop
add k v c = IntMap.insert k v c
60 e4f08c46 Iustin Pop
61 e4f08c46 Iustin Pop
-- | Remove an element from the map.
62 e4f08c46 Iustin Pop
remove :: Key -> Container a -> Container a
63 e4f08c46 Iustin Pop
remove = IntMap.delete
64 e4f08c46 Iustin Pop
65 e4f08c46 Iustin Pop
-- | Return the list of values in the map.
66 e4f08c46 Iustin Pop
elems :: Container a -> [a]
67 e4f08c46 Iustin Pop
elems = IntMap.elems
68 e4f08c46 Iustin Pop
69 1fd47ca2 Iustin Pop
-- | Return the list of keys in the map.
70 1fd47ca2 Iustin Pop
keys :: Container a -> [Key]
71 1fd47ca2 Iustin Pop
keys = IntMap.keys
72 1fd47ca2 Iustin Pop
73 e4f08c46 Iustin Pop
-- | Create a map from an association list.
74 e4f08c46 Iustin Pop
fromAssocList :: [(Key, a)] -> Container a
75 e4f08c46 Iustin Pop
fromAssocList = IntMap.fromList
76 e4f08c46 Iustin Pop
77 e4f08c46 Iustin Pop
-- | Create a map from an association list with a combining function.
78 e4f08c46 Iustin Pop
fromListWith :: (a -> a -> a) -> [(Key, a)] -> Container a
79 e4f08c46 Iustin Pop
fromListWith = IntMap.fromListWith
80 e4f08c46 Iustin Pop
81 e4f08c46 Iustin Pop
-- | Fold over the values of the map.
82 e4f08c46 Iustin Pop
fold :: (a -> b -> b) -> b -> Container a -> b
83 e4f08c46 Iustin Pop
fold = IntMap.fold
84 e4f08c46 Iustin Pop
85 e4f08c46 Iustin Pop
-- | Add or update two elements of the map.
86 e4f08c46 Iustin Pop
addTwo :: Key -> a -> Key -> a -> Container a -> Container a
87 e4f08c46 Iustin Pop
addTwo k1 v1 k2 v2 c = add k1 v1 $ add k2 v2 c
88 262a08a2 Iustin Pop
89 262a08a2 Iustin Pop
-- | Compute the name of an element in a container
90 262a08a2 Iustin Pop
nameOf :: (T.Element a) => Container a -> Key -> String
91 262a08a2 Iustin Pop
nameOf c k = T.nameOf $ find k c
92 262a08a2 Iustin Pop
93 262a08a2 Iustin Pop
-- | Compute the maximum name length in an Element Container
94 262a08a2 Iustin Pop
maxNameLen :: (T.Element a) => Container a -> Int
95 262a08a2 Iustin Pop
maxNameLen = maximum . map (length . T.nameOf) . elems
96 262a08a2 Iustin Pop
97 262a08a2 Iustin Pop
-- | Find an element by name in a Container; this is a very slow function
98 262a08a2 Iustin Pop
findByName :: (T.Element a, Monad m) =>
99 262a08a2 Iustin Pop
              Container a -> String -> m Key
100 262a08a2 Iustin Pop
findByName c n =
101 262a08a2 Iustin Pop
    let all_elems = elems c
102 262a08a2 Iustin Pop
        result = filter ((== n) . T.nameOf) all_elems
103 262a08a2 Iustin Pop
        nems = length result
104 262a08a2 Iustin Pop
    in
105 262a08a2 Iustin Pop
      if nems /= 1 then
106 262a08a2 Iustin Pop
          fail $ "Wrong number of elems (" ++ (show nems) ++
107 262a08a2 Iustin Pop
                   ") found with name " ++ n
108 262a08a2 Iustin Pop
      else
109 262a08a2 Iustin Pop
          return $ T.idxOf $ head result