Statistics
| Branch: | Tag: | Revision:

root / Ganeti / HTools / PeerMap.hs @ 9188aeef

History | View | Annotate | Download (2.2 kB)

1
{-|
2
  Module abstracting the peer map implementation.
3

    
4
This is abstracted separately since the speed of peermap updates can
5
be a significant part of the total runtime, and as such changing the
6
implementation should be easy in case it's needed.
7

    
8
-}
9

    
10
module Ganeti.HTools.PeerMap
11
    ( PeerMap
12
    , Key
13
    , Elem
14
    , empty
15
    , accumArray
16
    , Ganeti.HTools.PeerMap.find
17
    , add
18
    , remove
19
    , maxElem
20
    ) where
21

    
22
import Data.Maybe (fromMaybe)
23
import Data.List
24
import Data.Function
25
import Data.Ord
26

    
27
import Ganeti.HTools.Types
28

    
29
type Key = Ndx
30
type Elem = Int
31
type PeerMap = [(Key, Elem)]
32

    
33
-- * Initialization functions
34

    
35
-- | Create a new empty map.
36
empty :: PeerMap
37
empty = []
38

    
39
-- | Our reverse-compare function.
40
pmCompare :: (Key, Elem) -> (Key, Elem) -> Ordering
41
pmCompare a b = (compare `on` snd) b a
42

    
43
-- | Add or update (via a custom function) an element.
44
addWith :: (Elem -> Elem -> Elem) -> Key -> Elem -> PeerMap -> PeerMap
45
addWith fn k v lst =
46
    let r = lookup k lst
47
    in
48
      case r of
49
        Nothing -> insertBy pmCompare (k, v) lst
50
        Just o -> insertBy pmCompare (k, fn o v) (remove k lst)
51

    
52
-- | Create a PeerMap from an association list, with possible duplicates
53
accumArray :: (Elem -> Elem -> Elem) -- ^ function used to merge the elements
54
              -> [(Key, Elem)]       -- ^ source data
55
              -> PeerMap             -- ^ results
56
accumArray fn lst =
57
    case lst of
58
      [] -> empty
59
      (k, v):xs -> addWith fn k v $ accumArray fn xs
60

    
61
-- * Basic operations
62

    
63
-- | Returns either the value for a key or zero if not found
64
find :: Key -> PeerMap -> Elem
65
find k c = fromMaybe 0 $ lookup k c
66

    
67
-- | Add an element to a peermap, overwriting the previous value
68
add :: Key -> Elem -> PeerMap -> PeerMap
69
add k v c = addWith (flip const) k v c
70

    
71
-- | Remove an element from a peermap
72
remove :: Key -> PeerMap -> PeerMap
73
remove k c = case c of
74
               [] -> []
75
               (x@(x', _)):xs -> if k == x' then xs
76
                            else x:(remove k xs)
77

    
78
-- | Find the maximum element.
79
--
80
-- Since this is a sorted list, we just get the value at the head of
81
-- the list, or zero for a null list
82
maxElem :: PeerMap -> Elem
83
maxElem c = if null c then 0 else snd . head $ c