diff options
author | Joe Crayne <joe@jerkface.net> | 2019-01-16 01:37:29 -0500 |
---|---|---|
committer | Joe Crayne <joe@jerkface.net> | 2019-01-16 01:37:29 -0500 |
commit | f9339cd18bceba3f5000f1d2ccd9ce7dbc5f2cb0 (patch) | |
tree | 56271148ca1f09b1a2dc4ddadf84d1c5194b1a7d /src/Data | |
parent | 3dae31030c20ed9ad831dfba88db781ebe71ca54 (diff) |
Data.TableMethods
Diffstat (limited to 'src/Data')
-rw-r--r-- | src/Data/TableMethods.hs | 105 | ||||
-rw-r--r-- | src/Data/Wrapper/PSQ.hs | 5 |
2 files changed, 108 insertions, 2 deletions
diff --git a/src/Data/TableMethods.hs b/src/Data/TableMethods.hs new file mode 100644 index 00000000..e4208a69 --- /dev/null +++ b/src/Data/TableMethods.hs | |||
@@ -0,0 +1,105 @@ | |||
1 | {-# LANGUAGE CPP #-} | ||
2 | {-# LANGUAGE GADTs #-} | ||
3 | {-# LANGUAGE LambdaCase #-} | ||
4 | {-# LANGUAGE PartialTypeSignatures #-} | ||
5 | {-# LANGUAGE RankNTypes #-} | ||
6 | {-# LANGUAGE ScopedTypeVariables #-} | ||
7 | {-# LANGUAGE TupleSections #-} | ||
8 | module Data.TableMethods where | ||
9 | |||
10 | import Data.Functor.Contravariant | ||
11 | import Data.Time.Clock.POSIX | ||
12 | import Data.Word | ||
13 | import qualified Data.IntMap.Strict as IntMap | ||
14 | ;import Data.IntMap.Strict (IntMap) | ||
15 | import qualified Data.Map.Strict as Map | ||
16 | ;import Data.Map.Strict (Map) | ||
17 | import qualified Data.Word64Map as W64Map | ||
18 | ;import Data.Word64Map (Word64Map) | ||
19 | |||
20 | import Data.Wrapper.PSQ as PSQ | ||
21 | |||
22 | type Priority = POSIXTime | ||
23 | |||
24 | data OptionalPriority t tid x | ||
25 | = NoPriority | ||
26 | | HasPriority (Priority -> t x -> ([(tid, Priority, x)], t x)) | ||
27 | |||
28 | -- | The standard lookup table methods. | ||
29 | data TableMethods t tid = TableMethods | ||
30 | { -- | Insert a new /tid/ entry into the transaction table. | ||
31 | tblInsert :: forall a. tid -> a -> Priority -> t a -> t a | ||
32 | -- | Delete transaction /tid/ from the transaction table. | ||
33 | , tblDelete :: forall a. tid -> t a -> t a | ||
34 | -- | Lookup the value associated with transaction /tid/. | ||
35 | , tblLookup :: forall a. tid -> t a -> Maybe a | ||
36 | } | ||
37 | |||
38 | data QMethods t tid x = QMethods | ||
39 | { qTbl :: TableMethods t tid | ||
40 | , qAtMostView :: OptionalPriority t tid x | ||
41 | } | ||
42 | |||
43 | vanillaTable :: TableMethods t tid -> QMethods t tid x | ||
44 | vanillaTable tbl = QMethods tbl NoPriority | ||
45 | |||
46 | priorityTable :: TableMethods t tid | ||
47 | -> (Priority -> t x -> ([(k, Priority, x)], t x)) | ||
48 | -> (k -> x -> tid) | ||
49 | -> QMethods t tid x | ||
50 | priorityTable tbl atmost f = QMethods | ||
51 | { qTbl = tbl | ||
52 | , qAtMostView = HasPriority $ \p t -> case atmost p t of | ||
53 | (es,t') -> (map (\(k,p,a) -> (f k a, p, a)) es, t') | ||
54 | } | ||
55 | |||
56 | -- | Methods for using 'Data.IntMap'. | ||
57 | intMapMethods :: TableMethods IntMap Int | ||
58 | intMapMethods = TableMethods | ||
59 | { tblInsert = \tid a p -> IntMap.insert tid a | ||
60 | , tblDelete = IntMap.delete | ||
61 | , tblLookup = IntMap.lookup | ||
62 | } | ||
63 | |||
64 | -- | Methods for using 'Data.Word64Map'. | ||
65 | w64MapMethods :: TableMethods Word64Map Word64 | ||
66 | w64MapMethods = TableMethods | ||
67 | { tblInsert = \tid a p -> W64Map.insert tid a | ||
68 | , tblDelete = W64Map.delete | ||
69 | , tblLookup = W64Map.lookup | ||
70 | } | ||
71 | |||
72 | -- | Methods for using 'Data.Map' | ||
73 | mapMethods :: Ord tid => TableMethods (Map tid) tid | ||
74 | mapMethods = TableMethods | ||
75 | { tblInsert = \tid a p -> Map.insert tid a | ||
76 | , tblDelete = Map.delete | ||
77 | , tblLookup = Map.lookup | ||
78 | } | ||
79 | |||
80 | -- psqMethods :: PSQKey tid => QMethods (HashPSQ tid Priority) tid x | ||
81 | psqMethods :: PSQKey k => (tid -> k) -> (k -> x -> tid) -> QMethods (PSQ' k Priority) tid x | ||
82 | psqMethods g f = priorityTable (contramap g tbl) PSQ.atMostView f | ||
83 | where | ||
84 | tbl :: PSQKey tid => TableMethods (PSQ' tid Priority) tid | ||
85 | tbl = TableMethods | ||
86 | { tblInsert = PSQ.insert' | ||
87 | , tblDelete = PSQ.delete | ||
88 | , tblLookup = \tid t -> case PSQ.lookup tid t of | ||
89 | Just (p,a) -> Just a | ||
90 | Nothing -> Nothing | ||
91 | } | ||
92 | |||
93 | |||
94 | -- | Change the key type for a lookup table implementation. | ||
95 | -- | ||
96 | -- This can be used with 'intMapMethods' or 'mapMethods' to restrict lookups to | ||
97 | -- only a part of the generated /tid/ value. This is useful for /tid/ types | ||
98 | -- that are especially large due their use for other purposes, such as secure | ||
99 | -- nonces for encryption. | ||
100 | instance Contravariant (TableMethods t) where | ||
101 | -- contramap :: (tid -> t1) -> TableMethods t t1 -> TableMethods t tid | ||
102 | contramap f (TableMethods ins del lookup) = | ||
103 | TableMethods (\k p v t -> ins (f k) p v t) | ||
104 | (\k t -> del (f k) t) | ||
105 | (\k t -> lookup (f k) t) | ||
diff --git a/src/Data/Wrapper/PSQ.hs b/src/Data/Wrapper/PSQ.hs index 745e556b..4fdeec67 100644 --- a/src/Data/Wrapper/PSQ.hs +++ b/src/Data/Wrapper/PSQ.hs | |||
@@ -28,8 +28,9 @@ import qualified Data.HashPSQ as Q | |||
28 | singleton) | 28 | singleton) |
29 | import Data.Time.Clock.POSIX (POSIXTime) | 29 | import Data.Time.Clock.POSIX (POSIXTime) |
30 | 30 | ||
31 | type PSQ' k p v = HashPSQ k p v | 31 | -- type PSQ' k p v = HashPSQ k p v |
32 | type PSQ k p = PSQ' k p () | 32 | type PSQ' = HashPSQ |
33 | type PSQ k p = PSQ' k p () | ||
33 | 34 | ||
34 | type Binding' k p v = (k,p,v) | 35 | type Binding' k p v = (k,p,v) |
35 | type Binding k p = Binding' k p () | 36 | type Binding k p = Binding' k p () |