Revision c2b8d366

b/Makefile.am
126 126
	src/Ganeti/HTools/Program \
127 127
	src/Ganeti/Hypervisor \
128 128
	src/Ganeti/Hypervisor/Xen \
129
        src/Ganeti/Locking \
129 130
	src/Ganeti/Monitoring \
130 131
	src/Ganeti/Query \
131 132
	src/Ganeti/Storage \
......
730 731
	src/Ganeti/JSON.hs \
731 732
	src/Ganeti/Jobs.hs \
732 733
	src/Ganeti/Kvmd.hs \
734
        src/Ganeti/Locking/Allocation.hs \
733 735
	src/Ganeti/Logging.hs \
734 736
	src/Ganeti/Luxi.hs \
735 737
	src/Ganeti/Monitoring/Server.hs \
b/src/Ganeti/Locking/Allocation.hs
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

Also available in: Unified diff