-
Notifications
You must be signed in to change notification settings - Fork 86
/
Types.hs
131 lines (107 loc) · 4.67 KB
/
Types.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Ouroboros.Storage.VolatileDB.Types
(
module Ouroboros.Storage.VolatileDB.Types
, module Ouroboros.Storage.Common
, module Ouroboros.Network.Block
) where
import Control.Exception (Exception (..))
import Data.Map (Map)
import Data.Set (Set)
import Data.Typeable
import Data.Word (Word64)
import Ouroboros.Network.Block
import Ouroboros.Storage.Common
import Ouroboros.Storage.FS.API.Types
type FileId = Int
-- For each file, we store the latest blockId, the number of blocks
-- and a Map for its contents.
type Index blockId = Map String (FileInfo blockId)
-- For each blockId, we store the file we can find the block, the offset, its size
-- in bytes and its predecessor.
type ReverseIndex blockId = Map blockId (InternalBlockInfo blockId)
-- For each block, we store the Set of all blocks which have this block as
-- a predecessor (its successors).
type SuccessorsIndex blockId = Map (Maybe blockId) (Set blockId)
-- | Errors which might arise when working with this database.
data VolatileDBError blockId =
UserError UserError
-- ^ An error thrown because of incorrect usage of the volatile database
-- by the user.
| UnexpectedError (UnexpectedError blockId)
-- ^ An unexpected error thrown because something went wrong on a lower
-- layer.
deriving Show
data UserError =
InvalidArgumentsError String
| ClosedDBError
deriving (Show, Eq)
data UnexpectedError blockId =
FileSystemError FsError
| ParserError (ParserError blockId)
deriving (Show)
instance Eq blockId => Eq (VolatileDBError blockId) where
(==) = sameVolatileDBError
instance (Show blockId, Typeable blockId) => Exception (VolatileDBError blockId) where
displayException = show
data ParserError blockId =
DuplicatedSlot (Map blockId ([String], [String]))
| InvalidFilename String
| DecodeFailed String Word64
deriving (Show)
instance Eq blockId => Eq (ParserError blockId) where
(==) = sameParseError
sameVolatileDBError :: Eq blockId => VolatileDBError blockId -> VolatileDBError blockId -> Bool
sameVolatileDBError e1 e2 = case (e1, e2) of
(UserError ue1, UserError ue2) -> ue1 == ue2
(UnexpectedError ue1, UnexpectedError ue2) -> sameUnexpectedError ue1 ue2
_ -> False
-- (FileSystemError fs1, FileSystemError fs2) -> sameFsError fs1 fs2
-- (VParserError p1, VParserError p2) -> p1 == p2
-- (ClosedDBError, ClosedDBError) -> True
-- (InvalidArgumentsError _, InvalidArgumentsError _) -> True
-- _ -> False
-- TODO: Why is this not comparing the arguments to 'DuplicatedSlot'?
sameUnexpectedError :: Eq blockId => UnexpectedError blockId -> UnexpectedError blockId -> Bool
sameUnexpectedError e1 e2 = case (e1, e2) of
(FileSystemError fs1, FileSystemError fs2) -> sameFsError fs1 fs2
(ParserError p1, ParserError p2) -> p1 == p2
_ -> False
sameParseError :: ParserError blockId -> ParserError blockId -> Bool
sameParseError e1 e2 = case (e1, e2) of
(DuplicatedSlot _, DuplicatedSlot _) -> True
(InvalidFilename str1, InvalidFilename str2) -> str1 == str2
(DecodeFailed _ _ , DecodeFailed _ _) -> True
_ -> False
type FileSize = Word64
type BlockSize = Word64
newtype Parser e m blockId = Parser {
-- | Parse block storage at the given path.
-- The parser returns for each block, its size its blockId, its slot and its predecessor's blockId.
parse :: FsPath -> m ([(SlotOffset, (BlockSize, BlockInfo blockId))], Maybe e)
}
-- This is the information a user has to provide for each new block.
data BlockInfo blockId = BlockInfo {
bbid :: blockId
, bslot :: SlotNo
, bpreBid :: Maybe blockId
}
-- The Internal information the db keeps for each block.
data InternalBlockInfo blockId = InternalBlockInfo {
ibFile :: String
, ibSlotOffset :: SlotOffset
, ibBlockSize :: BlockSize
, ibSlot :: SlotNo
, ibPreBid :: Maybe blockId
}
-- The Internal information the db keeps for each file.
data FileInfo blockId = FileInfo {
fLatestSlot :: Maybe SlotNo
, fNBlocks :: Int
, fContents :: Map SlotOffset (BlockSize, blockId)
}