Statistics
| Branch: | Tag: | Revision:

root / Ganeti / HTools / Container.hs @ a80bf544

History | View | Annotate | Download (3.5 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 e2fa2baf Iustin Pop
{-
9 e2fa2baf Iustin Pop
10 e2fa2baf Iustin Pop
Copyright (C) 2009 Google Inc.
11 e2fa2baf Iustin Pop
12 e2fa2baf Iustin Pop
This program is free software; you can redistribute it and/or modify
13 e2fa2baf Iustin Pop
it under the terms of the GNU General Public License as published by
14 e2fa2baf Iustin Pop
the Free Software Foundation; either version 2 of the License, or
15 e2fa2baf Iustin Pop
(at your option) any later version.
16 e2fa2baf Iustin Pop
17 e2fa2baf Iustin Pop
This program is distributed in the hope that it will be useful, but
18 e2fa2baf Iustin Pop
WITHOUT ANY WARRANTY; without even the implied warranty of
19 e2fa2baf Iustin Pop
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20 e2fa2baf Iustin Pop
General Public License for more details.
21 e2fa2baf Iustin Pop
22 e2fa2baf Iustin Pop
You should have received a copy of the GNU General Public License
23 e2fa2baf Iustin Pop
along with this program; if not, write to the Free Software
24 e2fa2baf Iustin Pop
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 e2fa2baf Iustin Pop
02110-1301, USA.
26 e2fa2baf Iustin Pop
27 e2fa2baf Iustin Pop
-}
28 e2fa2baf Iustin Pop
29 669d7e3d Iustin Pop
module Ganeti.HTools.Container
30 e4f08c46 Iustin Pop
    (
31 e4f08c46 Iustin Pop
     -- * Types
32 e4f08c46 Iustin Pop
     Container
33 4333a887 Iustin Pop
    , Key
34 e4f08c46 Iustin Pop
     -- * Creation
35 e4f08c46 Iustin Pop
    , empty
36 e4f08c46 Iustin Pop
    , fromAssocList
37 e4f08c46 Iustin Pop
     -- * Query
38 e4f08c46 Iustin Pop
    , size
39 e4f08c46 Iustin Pop
    , find
40 e4f08c46 Iustin Pop
     -- * Update
41 e4f08c46 Iustin Pop
    , add
42 e4f08c46 Iustin Pop
    , addTwo
43 e4f08c46 Iustin Pop
    , remove
44 ec18dca9 Iustin Pop
    , IntMap.map
45 5d1baf63 Iustin Pop
    , IntMap.mapAccum
46 e4f08c46 Iustin Pop
    -- * Conversion
47 e4f08c46 Iustin Pop
    , elems
48 1fd47ca2 Iustin Pop
    , keys
49 262a08a2 Iustin Pop
    -- * Element functions
50 262a08a2 Iustin Pop
    , nameOf
51 262a08a2 Iustin Pop
    , maxNameLen
52 262a08a2 Iustin Pop
    , findByName
53 e4f08c46 Iustin Pop
    ) where
54 e4f08c46 Iustin Pop
55 e4f08c46 Iustin Pop
import qualified Data.IntMap as IntMap
56 e4f08c46 Iustin Pop
57 262a08a2 Iustin Pop
import qualified Ganeti.HTools.Types as T
58 262a08a2 Iustin Pop
59 e4f08c46 Iustin Pop
type Key = IntMap.Key
60 e4f08c46 Iustin Pop
type Container = IntMap.IntMap
61 e4f08c46 Iustin Pop
62 e4f08c46 Iustin Pop
-- | Create an empty container.
63 e4f08c46 Iustin Pop
empty :: Container a
64 e4f08c46 Iustin Pop
empty = IntMap.empty
65 e4f08c46 Iustin Pop
66 e4f08c46 Iustin Pop
-- | Returns the number of elements in the map.
67 e4f08c46 Iustin Pop
size :: Container a -> Int
68 e4f08c46 Iustin Pop
size = IntMap.size
69 e4f08c46 Iustin Pop
70 e4f08c46 Iustin Pop
-- | Locate a key in the map (must exist).
71 e4f08c46 Iustin Pop
find :: Key -> Container a -> a
72 e4f08c46 Iustin Pop
find k c = c IntMap.! k
73 e4f08c46 Iustin Pop
74 e4f08c46 Iustin Pop
-- | Locate a keyin the map returning a default value if not existing.
75 e4f08c46 Iustin Pop
findWithDefault :: a -> Key -> Container a -> a
76 e4f08c46 Iustin Pop
findWithDefault = IntMap.findWithDefault
77 e4f08c46 Iustin Pop
78 e4f08c46 Iustin Pop
-- | Add or update one element to the map.
79 e4f08c46 Iustin Pop
add :: Key -> a -> Container a -> Container a
80 e4f08c46 Iustin Pop
add k v c = IntMap.insert k v c
81 e4f08c46 Iustin Pop
82 e4f08c46 Iustin Pop
-- | Remove an element from the map.
83 e4f08c46 Iustin Pop
remove :: Key -> Container a -> Container a
84 e4f08c46 Iustin Pop
remove = IntMap.delete
85 e4f08c46 Iustin Pop
86 e4f08c46 Iustin Pop
-- | Return the list of values in the map.
87 e4f08c46 Iustin Pop
elems :: Container a -> [a]
88 e4f08c46 Iustin Pop
elems = IntMap.elems
89 e4f08c46 Iustin Pop
90 1fd47ca2 Iustin Pop
-- | Return the list of keys in the map.
91 1fd47ca2 Iustin Pop
keys :: Container a -> [Key]
92 1fd47ca2 Iustin Pop
keys = IntMap.keys
93 1fd47ca2 Iustin Pop
94 e4f08c46 Iustin Pop
-- | Create a map from an association list.
95 e4f08c46 Iustin Pop
fromAssocList :: [(Key, a)] -> Container a
96 e4f08c46 Iustin Pop
fromAssocList = IntMap.fromList
97 e4f08c46 Iustin Pop
98 e4f08c46 Iustin Pop
-- | Create a map from an association list with a combining function.
99 e4f08c46 Iustin Pop
fromListWith :: (a -> a -> a) -> [(Key, a)] -> Container a
100 e4f08c46 Iustin Pop
fromListWith = IntMap.fromListWith
101 e4f08c46 Iustin Pop
102 e4f08c46 Iustin Pop
-- | Fold over the values of the map.
103 e4f08c46 Iustin Pop
fold :: (a -> b -> b) -> b -> Container a -> b
104 e4f08c46 Iustin Pop
fold = IntMap.fold
105 e4f08c46 Iustin Pop
106 e4f08c46 Iustin Pop
-- | Add or update two elements of the map.
107 e4f08c46 Iustin Pop
addTwo :: Key -> a -> Key -> a -> Container a -> Container a
108 e4f08c46 Iustin Pop
addTwo k1 v1 k2 v2 c = add k1 v1 $ add k2 v2 c
109 262a08a2 Iustin Pop
110 9188aeef Iustin Pop
-- | Compute the name of an element in a container.
111 262a08a2 Iustin Pop
nameOf :: (T.Element a) => Container a -> Key -> String
112 262a08a2 Iustin Pop
nameOf c k = T.nameOf $ find k c
113 262a08a2 Iustin Pop
114 9188aeef Iustin Pop
-- | Compute the maximum name length in an Element Container.
115 262a08a2 Iustin Pop
maxNameLen :: (T.Element a) => Container a -> Int
116 262a08a2 Iustin Pop
maxNameLen = maximum . map (length . T.nameOf) . elems
117 262a08a2 Iustin Pop
118 9188aeef Iustin Pop
-- | Find an element by name in a Container; this is a very slow function.
119 262a08a2 Iustin Pop
findByName :: (T.Element a, Monad m) =>
120 262a08a2 Iustin Pop
              Container a -> String -> m Key
121 262a08a2 Iustin Pop
findByName c n =
122 262a08a2 Iustin Pop
    let all_elems = elems c
123 262a08a2 Iustin Pop
        result = filter ((== n) . T.nameOf) all_elems
124 262a08a2 Iustin Pop
        nems = length result
125 262a08a2 Iustin Pop
    in
126 262a08a2 Iustin Pop
      if nems /= 1 then
127 262a08a2 Iustin Pop
          fail $ "Wrong number of elems (" ++ (show nems) ++
128 262a08a2 Iustin Pop
                   ") found with name " ++ n
129 262a08a2 Iustin Pop
      else
130 262a08a2 Iustin Pop
          return $ T.idxOf $ head result