Statistics
| Branch: | Tag: | Revision:

root / htools / Ganeti / HTools / PeerMap.hs @ 2e5eb96a

History | View | Annotate | Download (2.8 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
{-
11

    
12
Copyright (C) 2009 Google Inc.
13

    
14
This program is free software; you can redistribute it and/or modify
15
it under the terms of the GNU General Public License as published by
16
the Free Software Foundation; either version 2 of the License, or
17
(at your option) any later version.
18

    
19
This program is distributed in the hope that it will be useful, but
20
WITHOUT ANY WARRANTY; without even the implied warranty of
21
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
22
General Public License for more details.
23

    
24
You should have received a copy of the GNU General Public License
25
along with this program; if not, write to the Free Software
26
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
27
02110-1301, USA.
28

    
29
-}
30

    
31
module Ganeti.HTools.PeerMap
32
    ( PeerMap
33
    , Key
34
    , Elem
35
    , empty
36
    , accumArray
37
    , Ganeti.HTools.PeerMap.find
38
    , add
39
    , remove
40
    , maxElem
41
    ) where
42

    
43
import Data.Maybe (fromMaybe)
44
import Data.List
45
import Data.Ord (comparing)
46

    
47
import Ganeti.HTools.Types
48

    
49
type Key = Ndx
50
type Elem = Int
51
type PeerMap = [(Key, Elem)]
52

    
53
-- * Initialization functions
54

    
55
-- | Create a new empty map.
56
empty :: PeerMap
57
empty = []
58

    
59
-- | Our reverse-compare function.
60
pmCompare :: (Key, Elem) -> (Key, Elem) -> Ordering
61
pmCompare a b = comparing snd b a
62

    
63
-- | Add or update (via a custom function) an element.
64
addWith :: (Elem -> Elem -> Elem) -> Key -> Elem -> PeerMap -> PeerMap
65
addWith fn k v lst =
66
    case lookup k lst of
67
      Nothing -> insertBy pmCompare (k, v) lst
68
      Just o -> insertBy pmCompare (k, fn o v) (remove k lst)
69

    
70
-- | Create a PeerMap from an association list, with possible duplicates
71
accumArray :: (Elem -> Elem -> Elem) -- ^ function used to merge the elements
72
              -> [(Key, Elem)]       -- ^ source data
73
              -> PeerMap             -- ^ results
74
accumArray _  [] = empty
75
accumArray fn ((k, v):xs) = addWith fn k v $ accumArray fn xs
76

    
77
-- * Basic operations
78

    
79
-- | Returns either the value for a key or zero if not found
80
find :: Key -> PeerMap -> Elem
81
find k = fromMaybe 0 . lookup k
82

    
83
-- | Add an element to a peermap, overwriting the previous value
84
add :: Key -> Elem -> PeerMap -> PeerMap
85
add = addWith (flip const)
86

    
87
-- | Remove an element from a peermap
88
remove :: Key -> PeerMap -> PeerMap
89
remove _ [] = []
90
remove k ((x@(x', _)):xs) = if k == x'
91
                            then xs
92
                            else x:remove k xs
93

    
94
-- | Find the maximum element.
95
--
96
-- Since this is a sorted list, we just get the value at the head of
97
-- the list, or zero for a null list
98
maxElem :: PeerMap -> Elem
99
maxElem (x:_) = snd x
100
maxElem _ = 0