Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (2.8 kB)

1
{-| Module abstracting the node and instance container implementation.
2

    
3
This is currently implemented on top of an 'IntMap', which seems to
4
give the best performance for our workload.
5

    
6
-}
7

    
8
module Ganeti.HTools.Container
9
    (
10
     -- * Types
11
     Container
12
    , Key
13
     -- * Creation
14
    , empty
15
    , fromAssocList
16
     -- * Query
17
    , size
18
    , find
19
     -- * Update
20
    , add
21
    , addTwo
22
    , remove
23
    , IntMap.map
24
    , IntMap.mapAccum
25
    -- * Conversion
26
    , elems
27
    , keys
28
    -- * Element functions
29
    , nameOf
30
    , maxNameLen
31
    , findByName
32
    ) where
33

    
34
import qualified Data.IntMap as IntMap
35

    
36
import qualified Ganeti.HTools.Types as T
37

    
38
type Key = IntMap.Key
39
type Container = IntMap.IntMap
40

    
41
-- | Create an empty container.
42
empty :: Container a
43
empty = IntMap.empty
44

    
45
-- | Returns the number of elements in the map.
46
size :: Container a -> Int
47
size = IntMap.size
48

    
49
-- | Locate a key in the map (must exist).
50
find :: Key -> Container a -> a
51
find k c = c IntMap.! k
52

    
53
-- | Locate a keyin the map returning a default value if not existing.
54
findWithDefault :: a -> Key -> Container a -> a
55
findWithDefault = IntMap.findWithDefault
56

    
57
-- | Add or update one element to the map.
58
add :: Key -> a -> Container a -> Container a
59
add k v c = IntMap.insert k v c
60

    
61
-- | Remove an element from the map.
62
remove :: Key -> Container a -> Container a
63
remove = IntMap.delete
64

    
65
-- | Return the list of values in the map.
66
elems :: Container a -> [a]
67
elems = IntMap.elems
68

    
69
-- | Return the list of keys in the map.
70
keys :: Container a -> [Key]
71
keys = IntMap.keys
72

    
73
-- | Create a map from an association list.
74
fromAssocList :: [(Key, a)] -> Container a
75
fromAssocList = IntMap.fromList
76

    
77
-- | Create a map from an association list with a combining function.
78
fromListWith :: (a -> a -> a) -> [(Key, a)] -> Container a
79
fromListWith = IntMap.fromListWith
80

    
81
-- | Fold over the values of the map.
82
fold :: (a -> b -> b) -> b -> Container a -> b
83
fold = IntMap.fold
84

    
85
-- | Add or update two elements of the map.
86
addTwo :: Key -> a -> Key -> a -> Container a -> Container a
87
addTwo k1 v1 k2 v2 c = add k1 v1 $ add k2 v2 c
88

    
89
-- | Compute the name of an element in a container
90
nameOf :: (T.Element a) => Container a -> Key -> String
91
nameOf c k = T.nameOf $ find k c
92

    
93
-- | Compute the maximum name length in an Element Container
94
maxNameLen :: (T.Element a) => Container a -> Int
95
maxNameLen = maximum . map (length . T.nameOf) . elems
96

    
97
-- | Find an element by name in a Container; this is a very slow function
98
findByName :: (T.Element a, Monad m) =>
99
              Container a -> String -> m Key
100
findByName c n =
101
    let all_elems = elems c
102
        result = filter ((== n) . T.nameOf) all_elems
103
        nems = length result
104
    in
105
      if nems /= 1 then
106
          fail $ "Wrong number of elems (" ++ (show nems) ++
107
                   ") found with name " ++ n
108
      else
109
          return $ T.idxOf $ head result