Safe Haskell | Safe-Infered |
---|
Implementation of lock allocation.
- data OwnerState
- type IndirectOwners a b = Map (a, b) OwnerState
- data AllocationState a b
- = Exclusive b (IndirectOwners a b)
- | Shared (Set b) (IndirectOwners a b)
- indirectOwners :: (Ord a, Ord b) => Map (a, b) OwnerState -> Set b
- indirectExclusives :: (Ord a, Ord b) => Map (a, b) OwnerState -> Set b
- data LockAllocation a b = LockAllocation {
- laLocks :: Map a (AllocationState a b)
- laOwned :: Map b (Map a OwnerState)
- emptyAllocation :: (Ord a, Ord b) => LockAllocation a b
- lockOwners :: Ord b => LockAllocation a b -> [b]
- listLocks :: Ord b => b -> LockAllocation a b -> Map a OwnerState
- listAllLocks :: Ord b => LockAllocation a b -> [a]
- toOwnersList :: AllocationState a b -> [(b, OwnerState)]
- listAllLocksOwners :: LockAllocation a b -> [(a, [(b, OwnerState)])]
- holdsLock :: (Ord a, Ord b) => b -> a -> OwnerState -> LockAllocation a b -> Bool
- data LockRequest a = LockRequest {
- lockAffected :: a
- lockRequestType :: Maybe OwnerState
- requestExclusive :: a -> LockRequest a
- requestShared :: a -> LockRequest a
- requestRelease :: a -> LockRequest a
- updateAllocState :: (Ord a, Ord b) => (Maybe (AllocationState a b) -> AllocationState a b) -> LockAllocation a b -> a -> LockAllocation a b
- updateLock :: (Ord a, Ord b) => b -> LockAllocation a b -> LockRequest a -> LockAllocation a b
- updateIndirectSet :: (Ord a, Ord b) => (IndirectOwners a b -> IndirectOwners a b) -> LockAllocation a b -> a -> LockAllocation a b
- updateIndirects :: (Lock a, Ord b) => b -> LockAllocation a b -> LockRequest a -> LockAllocation a b
- updateLocks :: (Lock a, Ord b) => b -> [LockRequest a] -> LockAllocation a b -> (LockAllocation a b, Result (Set b))
- manipulateLocksPredicate :: (Lock a, Ord b) => (a -> LockRequest a) -> (a -> Bool) -> b -> LockAllocation a b -> LockAllocation a b
- freeLocksPredicate :: (Lock a, Ord b) => (a -> Bool) -> LockAllocation a b -> b -> LockAllocation a b
- freeLocks :: (Lock a, Ord b) => LockAllocation a b -> b -> LockAllocation a b
- readLockOwnerstate :: JSON a => JSValue -> Result (a, OwnerState)
- readOwnerLock :: (JSON a, JSON b) => JSValue -> Result (b, [(a, OwnerState)])
- toRequest :: (a, OwnerState) -> LockRequest a
- allocationFromOwners :: (Lock a, Ord b, Show b) => [(b, [(a, OwnerState)])] -> Result (LockAllocation a b)
Documentation
data OwnerState Source
Data type describing the way a lock can be owned.
Eq OwnerState | |
Ord OwnerState | |
Show OwnerState | |
Arbitrary OwnerState | |
JSON OwnerState | Serializaiton of Lock Allocations To serialize a lock allocation, we only remember which owner holds which locks at which level (shared or exclusive). From this information, everything else can be reconstructed, simply using updateLocks. |
type IndirectOwners a b = Map (a, b) OwnerStateSource
data AllocationState a b Source
Exclusive b (IndirectOwners a b) | |
Shared (Set b) (IndirectOwners a b) |
(Eq a, Eq b) => Eq (AllocationState a b) | |
(Show a, Show b) => Show (AllocationState a b) |
indirectOwners :: (Ord a, Ord b) => Map (a, b) OwnerState -> Set bSource
indirectExclusives :: (Ord a, Ord b) => Map (a, b) OwnerState -> Set bSource
data LockAllocation a b Source
Representation of a Lock allocation
To keep queries for locks efficient, we keep two associations, with the invariant that they fit together: the association from locks to their allocation state, and the association from an owner to the set of locks owned. As we do not export the constructor, the problem of keeping this invariant reduces to only exporting functions that keep the invariant.
LockAllocation | |
|
(Eq a, Eq b) => Eq (LockAllocation a b) | |
(Show a, Show b) => Show (LockAllocation a b) | |
(Arbitrary a, Lock a, Arbitrary b, Ord b, Show b) => Arbitrary (LockAllocation a b) | |
(Lock a, JSON a, Ord b, JSON b, Show b) => JSON (LockAllocation a b) |
emptyAllocation :: (Ord a, Ord b) => LockAllocation a bSource
A state with all locks being free.
lockOwners :: Ord b => LockAllocation a b -> [b]Source
Obtain the list of all owners holding at least a single lock.
listLocks :: Ord b => b -> LockAllocation a b -> Map a OwnerStateSource
Obtain the locks held by a given owner. The locks are reported as a map from the owned locks to the form of ownership (OwnShared or OwnExclusive).
listAllLocks :: Ord b => LockAllocation a b -> [a]Source
List all locks currently (directly or indirectly) owned by someone.
toOwnersList :: AllocationState a b -> [(b, OwnerState)]Source
listAllLocksOwners :: LockAllocation a b -> [(a, [(b, OwnerState)])]Source
List all locks currently (directly of indirectly) in use together with the direct owners.
holdsLock :: (Ord a, Ord b) => b -> a -> OwnerState -> LockAllocation a b -> BoolSource
Returns True
if the given owner holds the given lock at the given
ownership level or higher. This means that querying for a shared lock
returns True
of the owner holds the lock in shared or exlusive mode.
data LockRequest a Source
Data Type describing a change request on a single lock.
LockRequest | |
|
Eq a => Eq (LockRequest a) | |
Ord a => Ord (LockRequest a) | |
Show a => Show (LockRequest a) | |
Arbitrary a => Arbitrary (LockRequest a) | |
JSON a => JSON (LockRequest a) |
requestExclusive :: a -> LockRequest aSource
Lock request for an exclusive lock.
requestShared :: a -> LockRequest aSource
Lock request for a shared lock.
requestRelease :: a -> LockRequest aSource
Request to release a lock.
updateAllocState :: (Ord a, Ord b) => (Maybe (AllocationState a b) -> AllocationState a b) -> LockAllocation a b -> a -> LockAllocation a bSource
updateLock :: (Ord a, Ord b) => b -> LockAllocation a b -> LockRequest a -> LockAllocation a bSource
updateIndirectSet :: (Ord a, Ord b) => (IndirectOwners a b -> IndirectOwners a b) -> LockAllocation a b -> a -> LockAllocation a bSource
updateIndirects :: (Lock a, Ord b) => b -> LockAllocation a b -> LockRequest a -> LockAllocation a bSource
updateLocks :: (Lock a, Ord b) => b -> [LockRequest a] -> LockAllocation a b -> (LockAllocation a b, Result (Set b))Source
Update the locks of an owner according to the given request. Return the pair of the new state and the result of the operation, which is the the set of owners on which the operation was blocked on. so an empty set is success, and the state is updated if, and only if, the returned set is emtpy. In that way, it can be used in atomicModifyIORef.
manipulateLocksPredicate :: (Lock a, Ord b) => (a -> LockRequest a) -> (a -> Bool) -> b -> LockAllocation a b -> LockAllocation a bSource
freeLocksPredicate :: (Lock a, Ord b) => (a -> Bool) -> LockAllocation a b -> b -> LockAllocation a bSource
freeLocks :: (Lock a, Ord b) => LockAllocation a b -> b -> LockAllocation a bSource
Compute the state after an onwer releases all its locks.
readLockOwnerstate :: JSON a => JSValue -> Result (a, OwnerState)Source
readOwnerLock :: (JSON a, JSON b) => JSValue -> Result (b, [(a, OwnerState)])Source
toRequest :: (a, OwnerState) -> LockRequest aSource
allocationFromOwners :: (Lock a, Ord b, Show b) => [(b, [(a, OwnerState)])] -> Result (LockAllocation a b)Source