Statistics
| Branch: | Tag: | Revision:

root / src / Ganeti / Locking / Allocation.hs @ c2b8d366

History | View | Annotate | Download (2.4 kB)

1
{-| Implementation of lock allocation.
2

    
3
-}
4

    
5
{-
6

    
7
Copyright (C) 2014 Google Inc.
8

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

    
14
This program is distributed in the hope that it will be useful, but
15
WITHOUT ANY WARRANTY; without even the implied warranty of
16
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
General Public License for more details.
18

    
19
You should have received a copy of the GNU General Public License
20
along with this program; if not, write to the Free Software
21
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22
02110-1301, USA.
23

    
24
-}
25

    
26
module Ganeti.Locking.Allocation
27
  ( LockAllocation
28
  , emptyAllocation
29
  , OwnerState(..)
30
  , listLocks
31
  ) where
32

    
33
import qualified Data.Map as M
34
import Data.Maybe (fromMaybe)
35
import qualified Data.Set as S
36

    
37
{-
38

    
39
This module is parametric in the type of locks and lock owners.
40
While we only state minimal requirements for the types, we will
41
consistently use the type variable 'a' for the type of locks and
42
the variable 'b' for the type of the lock owners throughout this
43
module.
44

    
45
-}
46

    
47
-- | The state of a lock that is taken.
48
data AllocationState a = Exclusive a | Shared (S.Set a) deriving (Eq, Show)
49

    
50
-- | Data type describing the way a lock can be owned.
51
data OwnerState = OwnShared | OwnExclusive deriving (Ord, Eq, Show)
52

    
53
{-| Representation of a Lock allocation
54

    
55
To keep queries for locks efficient, we keep two
56
associations, with the invariant that they fit
57
together: the association from locks to their
58
allocation state, and the association from an
59
owner to the set of locks owned. As we do not
60
export the constructor, the problem of keeping
61
this invariant reduces to only exporting functions
62
that keep the invariant.
63

    
64
-}
65

    
66
data LockAllocation a b =
67
  LockAllocation { laLocks :: M.Map a (AllocationState b)
68
                 , laOwned :: M.Map b (M.Map a OwnerState)
69
                 }
70
  deriving (Eq, Show)
71

    
72
-- | A state with all locks being free.
73
emptyAllocation :: (Ord a, Ord b) => LockAllocation a b
74
emptyAllocation =
75
  LockAllocation { laLocks = M.empty
76
                 , laOwned = M.empty
77
                 }
78

    
79
-- | Obtain the set of locks held by a given owner.
80
listLocks :: Ord b => b -> LockAllocation a b -> M.Map a OwnerState
81
listLocks owner = fromMaybe M.empty . M.lookup owner . laOwned