-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathUtils.hs
93 lines (68 loc) · 3.17 KB
/
Utils.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
module Utils where
import Message
import qualified Data.HashMap.Strict as HM
import Data.Time.Clock
import Data.Hashable
import Debug.Trace
majority :: Int
majority = 2 -- because 1 is always implied (1 + 2)
timeoutRange :: (Int, Int)
timeoutRange = (900, 1200) -- ms
sendCooldown = 0.006
heartbeatRate :: Int
heartbeatRate = 700 -- ms
commandCap = 18
cooledOff :: UTCTime -> UTCTime -> Bool
cooledOff now t = diff > sendCooldown
where diff = abs $ diffUTCTime now t
timedOut :: UTCTime -> UTCTime -> Int -> Bool
timedOut clock now timeout = diff > timeout'
where timeout' = 0.001 * realToFrac timeout
diff = abs $ diffUTCTime now clock
ts :: (Show a) => UTCTime -> a -> String
ts now a = (show now) ++ " : " ++ (show a)
push :: a -> [a] -> [a]
push a as = as ++ [a]
getLastLogIndex :: [Command] -> Int
getLastLogIndex slog = length slog - 1
getLastLogTerm :: [Command] -> Int
getLastLogTerm slog = if length slog == 0 then (-1) else cterm $ last slog
zipAddAllM :: [String] -> [Message] -> HM.HashMap String Message -> HM.HashMap String Message
zipAddAllM as bs hm
| length as /= length bs = error $ "zipAddAllM: list lengths are not the same size " ++ (show as) ++ " : " ++ (show bs)
| otherwise = HM.union (HM.fromList $ zip as bs) hm
zipAddAllT :: [String] -> [UTCTime] -> HM.HashMap String UTCTime -> HM.HashMap String UTCTime
zipAddAllT as bs hm
| length as /= length bs = error $ "zipAddAllT: list lengths are not the same size " ++ (show as) ++ " : " ++ (show bs)
| otherwise = HM.union (HM.fromList $ zip as bs) hm
getNeedResending :: UTCTime -> HM.HashMap a UTCTime -> [a]
getNeedResending now timeQ = HM.keys $ HM.filter (cooledOff now) timeQ
getPrevLogIndex :: Int -> Int
getPrevLogIndex nextIndex = nextIndex - 1
getPrevLogTerm :: [Command] -> Int -> Int
getPrevLogTerm [] _ = (-1)
getPrevLogTerm slog nextIndex
| nextIndex > length slog = error $ "getPrevLogTerm: nextIndex greater than slog length " ++ (show nextIndex) ++ " : " ++ (show $ length slog)
| nextIndex <= 0 = (-1)
| otherwise = cterm $ (slog!!(nextIndex - 1))
getNextCommands :: [Command] -> Int -> [Command]
getNextCommands [] _ = []
getNextCommands slog nextIndex
| nextIndex > length slog = error $ "getNextCommands: nextIndex greater than slength " ++ (show nextIndex) ++ " : " ++ (show $ length slog)
| nextIndex == length slog = []
| otherwise = take commandCap $ drop nextIndex slog
upToDate :: [Command] -> Int -> Int -> Bool
upToDate [] _ _ = True
upToDate base lastLogTerm lastLogIndex
| lastLogTerm >= myLastLogTerm && lastLogIndex >= myLastLogIndex = True
-- | lastLogIndex < myLastLogIndex = trace ("upToDate fail: myLLI: " ++ (show myLastLogIndex) ++ ", theirLLI: " ++ (show lastLogIndex)) False
| lastLogIndex < myLastLogIndex = False
| otherwise = False
where myLastLogTerm = cterm $ last base
myLastLogIndex = length base - 1
getNewCommitIndex :: Int -> Int -> Int -> Int -> Int
getNewCommitIndex leaderCommit commitIndex prevLogIndex lengthEntries
| leaderCommit > commitIndex = min leaderCommit (prevLogIndex + lengthEntries)
| otherwise = commitIndex
cleanSlog :: [Command] -> Int -> [Command]
cleanSlog slog prevLogIndex = take prevLogIndex slog