1 module hunt.raft.Util;
2 
3 import hunt.raft.Msg;
4 import hunt.raft.Node;
5 
6 import hunt.logging;
7 import hunt.util.Serialize;
8 
9 import std.format;
10 
11 immutable ulong None = 0;
12 immutable noLimit = ulong.max;
13 bool IsLocalMsg(MessageType msgt)
14 {
15 	return msgt == MessageType.MsgHup ||
16 		msgt == MessageType.MsgBeat ||
17 		msgt == MessageType.MsgUnreachable ||
18 		msgt == MessageType.MsgSnapStatus ||
19 			msgt == MessageType.MsgCheckQuorum;
20 }
21 
22 bool IsResponseMsg(MessageType msgt)
23 {
24 	return msgt == MessageType.MsgAppResp || 
25 		msgt == MessageType.MsgVoteResp ||
26 		msgt == MessageType.MsgHeartbeatResp ||
27 		msgt == MessageType.MsgUnreachable ||
28 			msgt == MessageType.MsgPreVoteResp;
29 }
30 
31 MessageType voteRespMsgType(MessageType msgt)
32 {
33 	switch(msgt)
34 	{
35 		case MessageType.MsgVote:
36 			return MessageType.MsgVoteResp;
37 		case MessageType.MsgPreVote:
38 			return MessageType.MsgPreVoteResp;
39 		default:
40 			logError("not a vode message: " , msgt);
41 			return msgt;
42 	}
43 
44 }
45 
46 
47 
48 string DescribeMessage(Message m)
49 {
50 	string str = format("%x->%x %s Term:%d Log:%d/%d" ,
51 		m.From , m.To , m.Type , m.Term , m.LogTerm , m.Index);
52 	if( m.Reject )
53 	{
54 		str ~= " Rejected";
55 		if( m.Reject != 0)
56 		{
57 			str ~= format("(Hint:%d)", m.RejectHint);
58 		}
59 	}
60 
61 	if ( m.Commit != 0)
62 	{
63 		str ~= format(" Commit:%d", m.Commit);
64 	}
65 
66 	if( m.Entries.length > 0)
67 	{
68 		str ~=  "Entries:[";
69 		for( auto i = 0 ; i < m.Entries.length ; i++)
70 		{
71 			if( i != 0)
72 			{
73 				str ~= ", ";
74 			}
75 
76 			str ~= DescribeEntry(m.Entries[i]);
77 		}
78 	}
79 
80   	if(!IsEmptySnap(m.snap))
81 	{
82 		str ~= " snapshot:V";
83 	}
84 
85 	return str;
86 }
87 
88 
89 string DescribeEntry(Entry e)
90 {
91 	return format("%d/%d %s %s", e.Term, e.Index, e.Type , e.Data);
92 }
93 
94 
95 Entry[] limitSize(Entry[] ents , ulong maxSize)
96 {
97 	if(ents.length == 0)
98 		return ents;
99 
100 	auto size = getsize!Entry(ents[0]);
101 	auto limit = 1;
102 	for(; limit < ents.length ; limit++)
103 	{	size += getsize(ents[limit]);
104 		if( size > maxSize)
105 			break;
106 	}
107 
108 	return ents[0 .. limit];
109 }
110