3.1. Protocol Composition
3.1.1. Data Structure
In order to define data structures to ensure message causal ordering, we need to define additional data types and structures that will be used throughout this document.
Bit Vector
A bit vector is an array of variable size. Each element can take only two values: set (represented by 1) and cleared (represented by 0). Each bit vector can be extended with zeros to a required size and the trailing zeros can be trimmed. An empty bit vector is denoted as Ø.
Bits are numbers starting from 1. V[x] represents a bit at position x in vector V. A bit at position 0 is assumed to be always set. Bit vectors support AND (&), OR (|) and NOT ( ) operations that are bitwise, i.e., the operation is applied to bits at Position 1, then bits at Position 2, etc.
Extended Linear Time
Extended Linear Time (LTx) is a data type that can contain one of the following: An integer number and a bit vector. Extended Linear Time cannot contain an integer and a bit vector at the same time. In addition, it is possible to determine at any given time whether a given linear time contains an integer or a bit vector. If this data type contains an integer, it represents a process, and if it contains a bit vector, it represents a meta-process.
Extended Vector Time
Extended Vector Time (VTx) is a vector of LTx. Each element does not depend on others. Thus, a vector can have one element that is an integer and another element that is a bit vector at the same time.
Data Structures in an Internal Peer
Each internal peer maintains the following data:
idint—identifier of a peer in the internal group. This identifier must be unique in a group.
SN—an integer representing a sequence number of a message.
RV—bit vector representing received messages.
DV—bit vector representing message IDR.
Data Structures in an External Peer
In an external group, each peer maintains the following variables:
idext(p)—identifier of a peer in the external group. This identifier must be unique in a group.
VTx(p)—extended vector time. The size of a vector is G, where G is the number of peers and super peers in an external group.
CI—vector of pairs representing message control information. Each pair consists of a process identifier and LTx. CI[x] is a pair where the process identifier is x.
Data Structures in a Super Peer
A super peer maintains the following variables:
idext(sp)—identifier of a super peer in the external group.
VTx(sp)—extended vector time. The size of a vector is G, where G is the number of peers and super peers in an external group.
I—bit vector representing identifiers of translated messages.
LR—vector of pairs of size L, where L is the number of peers in an internal group of this super peer. Each pair contains two sequence number names, in and out.
TT—vector of vectors of pairs. The size of a vector is G. Each pair consists of two message identifiers called in and out.
Internal Group Message Structure
Messages in an internal group are denoted by
mint and have the following structure:
where
Id—the identifier of a sending process in the internal group.
SN—an integer representing a message sequence number.
Last—an integer identifier of the last message from this peer.
DV—a bit vector representing message dependency.
Data—the user data to be transmitted.
This message structure is used by both peers and super peers in an internal group (see
Figure 2).
External Group Message Structure
In an external group, messages are denoted by
mext and have the following structure:
where
Id—the identifier of a sending process.
SN—an integer representing a message sequence number.
CI—vector of pairs representing message control information. Each pair consists of a process identifier and LTx.
I—bit vector with internal message identifiers.
Data—the user data to be transmitted.
This message structure is used by both peers and super peer in an external group (see
Figure 2).
3.1.2. Specification of the Causal Protocol
Initially each process performs an initialization process. An internal peer performs this process as follows.
Listing 1. Internal peer initialization.
An external peer initializes its variables as follows.
Listing 2. External peer initialization.
|
CI := Ø |
Furthermore, a super peer performs initialization as follows (
Listing 3).
Listing 3. Super peer initialization.
|
LR := (<0, 0>, <0, 0>, …, <0, 0>) |
TT := (Ø, Ø, …, Ø) |
I := Ø |
When an internal peer wants to send a message to a super peer, it constructs the message using the following procedure (see
Listing 4).
Listing 4. Message sending by an internal peer.
1 | SN := SN + 1 |
2 | mint = (idint, SN, 0, DV, Data) |
3 | DV := Ø |
When an internal peer receives a message from a super peer, it verifies its delivery condition. First, it should verify a FIFO condition that a received message has not arrived before a previous message from the same sender. After such verification, a peer needs to check that it has received all of the messages that form the immediate dependency relation with the currently received message (see
Listing 5).
Listing 5. Internal peer delivery condition.
1 | If (RV[mint.Last] = 1) then // FIFO condition |
2 | If (mint.DV & RV = mint.DV) then // Causal condition |
3 | Deliver(mint) |
4 | End if |
5 | End if |
If a delivery condition is satisfied, a peer updates its data structures (see
Listing 6) and it can deliver a message to a corresponding application. If a delivery condition is not satisfied, a message should be buffered.
An internal peer will receive its own message returned by a super peer. In this case, it should only update its receive vector
RV. After a message is delivered, a process should check its buffer. If a message in a buffer satisfies a delivery condition, it should be delivered using the same algorithm (see
Listing 6).
Listing 6. Message delivery to internal peer.
1 | RV[mint.SN] := 1 |
2 | If (mint.id ≠ idint) then |
3 | DV := DV & |
4 | DV[mint.SN] := 1 |
5 | DV[mint.Last] := 0 |
6 | End if |
Since a super peer only transmits messages from other peers, it does not have a message emission phase. When a super peer receives a message from an internal peer, it checks the message delivery condition. Since an internal peer can only receive messages from a super peer, it means that only a FIFO dependency needs to be checked. To check the message delivery condition, a super peer uses the following algorithm (see
Listing 7).
Listing 7. Super peer delivery condition for messages from an internal group.
1 | If (mint.SN = LR[mint.id].in + 1) then |
2 | Deliver(mint) |
3 | End if |
If a delivery condition is satisfied, a super peer can forward this message to other peers (see
Listing 8). If a delivery condition is not satisfied, a message should be buffered.
Listing 8. Internal message delivery to super peer.
1 | mint.Last := LR[mint.id].out |
2 | VTx[idext] := VTx[idext] + 1 |
3 | LR[mint.id] := <mint.SN, VT[idext]> |
4 | mint.SN := VTx[idext] |
5 | Send mint to all peers in the internal group |
6 | Transform and send message mint to all peers in the external group |
After a message is delivered, a process should check its buffer. If a message in a buffer satisfies a delivery condition, it should be delivered using the same algorithm (see
Listing 8). A message transformation will be discussed later in this section.
When an external peer wants to send a message, it constructs it using the algorithm (see
Listing 9).
Listing 9. Message sending by external peer.
1 | VTx[idext] := VTx[idext] + 1 |
2 | mext = (idext, VTx[idext], CI, Ø, Data) |
3 | CI := Ø |
When a message is received by an external peer or a super peer, it requires updating its clock with the internal message identifiers that a message is carrying in its field
mext.
I (see
Listing 10).
Listing 10. Message receiving by peers and super peers in an external group.
1 | If VTx[mext.id] is a bit vector then |
2 | VTx[mext.id] = VTx[mext.id] | mext.I |
3 | End if |
After this update, a message delivery condition can be checked. A message delivery condition consists of two parts. If a message arrived from an external peer, a message FIFO order should be checked. If the message FIFO ordering is not violated or a message has arrived from a super peer, then a message causal delivery condition is checked. This condition consists in checking message identifiers that are inside messages control information (see
Listing 11). These conditions (FIFO and causal) are checked in both external peers and a super peer when it receives a message from an external group.
Listing 11. Message delivery condition in external group.
1 | If (VTx[mext.id] is a bit vector) or (mext.SN = VTx[mext.id] + 1) then // FIFO |
2 | If for each <i, dep> (i ≠ idext) in |
3 | then // Causal Deliver(mext) |
4 | End if |
5 | End if |
If a delivery condition is satisfied in an external peer, it can deliver a message to an application. To do this, a peer is required to update its data structures to ensure that following messages will be correctly ordered (see
Listing 12). This update consists of two parts. First, it needs to update the clock so that the messages that depend on this one can be delivered. The second part is to update control information so that a message sent from this peer will be correctly ordered by other peers.
Listing 12. Message delivery to an external peer.
1 | If VTx[mext.id] is an integer then |
2 | VTx[mext.id] := mext.SN |
3 | Else |
4 | VTx[mext.id][mext.SN] := 1 |
5 | End if |
6 | If VTx[mext.id] is an integer then |
7 | If exists <i, dep> in CI that i = mext.id then |
8 | CI := CI \ <i, dep> |
9 | End if |
10 | CI := CI ∪ <mext.id, mext.SN> |
11 | Else |
12 | If not exists <i, dep> in CI that i = mext.id then |
13 | CI := CI ∪ <mext.id, Ø> |
14 | End if |
15 | CI[mext.id][mext.SN]: = 1 |
16 | End if |
17 | For each <i, dep> in mext.CI |
18 | If VTx[i] is an integer then |
19 | CI := CI \ <i, dep> |
20 | Else |
21 | CI[i] := CI[i] & dep |
22 | End if |
23 | End for |
If for any pair in CI a bit vector is empty, this pair can be removed from CI. If a delivery condition is satisfied in a super peer, it can forward this message to an internal group. To do this, a peer is required to update its data structures to ensure the delivery of messages that depend on this one. This requires an update of a clock so that messages that depend on this one can be delivered.
Listing 13. External message delivery to a super peer.
1 | If VTx[mext.id] is an integer then |
2 | VTx[mext.id] := mext.SN |
3 | Else |
4 | VTx[mext.id][mext.SN] := 1 |
5 | End if |
6 | VTx[idext] := VTx[idext] + 1 |
7 | Transform and send message mext to all peers in the internal group |
After a message is delivered to a peer or a super peer, a process should check its buffer. If a message in a buffer satisfies a delivery condition, it should be delivered using the same algorithm (see
Listing 12 for external peer, and
Listing 13 for super peer).
As bit vectors RV, DV and VTx grow in size during the execution of a protocol with each message, it is necessary to use mechanisms to reduce bit vector sizes. Communication channels are considered to be reliable; thus, every message sent by a super peer will be delivered to an internal group peer. This means that an RV and VTx will have bits for each message set. Since a super peer numbers messages with consecutive integers after some execution time, an RV and VTx will start with consecutive set bits. Considering that, after a bit is set, it is not changed to a cleared state at any time. Thus, it is required to store bits between the first cleared bit and the last set bit.
A vector DV is based on the immediate dependency relation. Each bit is set only once and then it is cleared when a message is sent or a dependent message is received. Thus, it is only required to store bits between the first and the last set bits.
To be completely functional, a protocol requires a mechanism to transform messages from an internal group to an external group and vice versa. This transformation is performed by a super peer because it participates in both groups at the same time.
A message that originated from an internal group generally carries dependencies on other messages from an internal group and dependencies on messages from an external group. The dependencies on messages from an internal group are represented in a form of bit vector, but to be interpreted correctly in an external group, they should be transformed into a vector of pairs (process identifier, and message dependency). This transformation can be achieved by using the algorithm presented below (see
Listing 14).
Listing 14. Message transformation from an internal to an external group.
1 | Im := I // Bit vector |
2 | I := Ø |
3 | CI := (<idext, mint.DV>) // Vector of pairs. |
4 | CI[idext][mint.Last] := 1 |
5 | For each <id, PT> in TT // PT is a vector of pairs |
6 | For each <in, out> in PT in reverse order |
7 | If mint.DV[out] = 1 then |
8 | Im[out] := 1 |
9 | CI[idext][out] := 0 |
10 | If VTx[id] is an integer then |
11 | CI := CI ∪ <id, in> |
12 | Exit For |
13 | Else |
14 | If not exists <i, dep> in CI that i = id then |
15 | CI := CI ∪ <id, Ø> |
16 | End if |
17 | CI[id][in] := 1 |
18 | End if |
19 | End if |
20 | End for |
21 | End for |
22 | mext := (idext, mint.SN, CI, Im, mint.Data) |
If a message carries only dependencies on external messages, a CI[idext] will be an empty vector. In this case, this dependency can be removed from CI.
Listing 15. Message transformation from an external to an internal group.
1 | DV := mext.CI[idext] // Bit vector |
2 | For each <id, dep> in mext.CI |
3 | If (VTx[id] is an integer) |
4 | If (exists <in, out> in TT[id] where in = dep) then |
5 | DV[out] := 1 |
6 | End if |
7 | Else |
8 | For each 1 in dep in position i |
9 | If exists <in, out> in TT[id] where in = i then |
10 | DV[out] := 1 |
11 | End if |
12 | End for |
13 | End if |
14 | End for |
15 | mint = (0, VTx[idext], 0, DV, mext.Data) |
16 | If TT[mext.id] is not empty and VTx[mext.id] is an integer then |
17 | mint.Last := TT[mext.id][last].out |
18 | End if |
19 | TT[mext.id] := TT[mext.id] ∪ <mext.SN, VTx[idext]> |
20 | I[VTx[idext]] := 1 |
A message received by a super peer that originated from an external group generally carries dependencies on other messages from an external group, as well as dependencies on messages from an internal group. The dependencies on messages from an external group are represented in a form of pairs (process identifier, and message dependency), but to be interpreted correctly in an internal group, they should be transformed to a bit vector form (see
Listing 15). In addition, a super peer can receive messages that contain dependencies on messages that are not yet received. To deal with this, a super peer checks the message delivery condition as described previously to ensure that this message can be delivered by a super peer, and only then, transforms it to ensure that all of the message dependencies are resolved. This does not affect the message order in any way. If a super peer does not receive message
m, none of the peers in an internal group have received this message
m. Thus, a message
m′ that requires
m to be delivered before it cannot be delivered to any peer in an internal group.
3.1.3. Correctness Proof
To show that our algorithm ensures the causal delivery (correctness), we provide a correctness proof. In order to do the proof as simple as possible, we focus on the part of the internal group where the message dependencies are represented on a bit level. In this proof we will use the following notations:
We show that with this information we ensure the causal order.
Theorem 1. For each set bit in ml.DV[k], k identifies a message from the same group or TT contains (in, out) at position id such that (k = out), where (id, in) identifies a message mk, which has IDR with ml.
Main steps of the proof. The proof is composed of three lemmas and a proposition. The lemmas are intermediate results necessary for our proof:
Lemma 1 shows that if ml.DV[k] is set, then the message with SN = k causally precedes message ml.
Lemma 2 shows that if ml.Last = k, then message with SN = k causally precedes message ml.
Lemma 3 indicates that the message mk has an immediate dependency relation with the other message ml if and only if bit ml.DV[k] is set.
Proposition 1 shows that through the bits structure h(m) attached to messages sent and the causal information at the super peer, we ensure the causal order (Theorem 1).
Lemma 1. If ml.DV[k] is set then message mk → ml
Proof: By Line 2 in
Listing 4, we have that
ml.
DV[
k] is set if and only if
DV[
k] at peer
pj is set when the sending of
ml is carried out by
pj. By using Line 4 in
Listing 6, we have that
DV[
k] is set only after the delivery of
mk. In addition, the super peer does not make any modifications to the
DV of a message. This implies that the delivery of
mk precedes the sending of
ml (
delivery(
mk) →
send(
ml)). Therefore,
mk →
ml.
Lemma 2. If ml.Last = k then message mk → ml
Proof. By Line 1 of
Listing 8, we have that
ml.
Last is set to the value of
LR[
ml.
id].
out at the super peer. By Line 3 of
Listing 8,
LR[
ml.
id].
out is set to
k upon send of
mk which was received by super peer from peer with id
ml.
id. This means that
mk and
ml were sent by the same peer and therefore
mk →
ml. Lemma 3. mk↓ml if and only if ml.DV[k] is set
The proof to this lemma is divided into two steps: First, we show that if mk↓ml then ml.DV[k] is set and second, we show that if ml.DV[k] is set, then mk↓ml.
Step 1: If mk↓ml then ml.DV[k] is set
The proof is by contrapositive. We proof that if ml.DV[k] is cleared then mr exists such that mk → mr → ml; thus, the message mk does not have an immediate dependency relation with message ml. We assume that ml.DV[k] is cleared. Only two events can clear DV[k] before sending ml, these are:
By Lines 3, 5 of
Listing 6,
DV[
k] is cleared when the delivery of message
mr is carried out with
mr.
DV[
k] bit set or
mr.
Last =
k. Lemmas 1 and 2 show that if
mr.
DV[
k] is set or
ml.Last =
k then
mk →
ml. Moreover,
delivery(
mr) →
send(
ml) implies that
mr →
ml and then
mk →
mr →
ml. Therefore,
mk does not directly precede message
ml.
By Line 3 of
Listing 4, the sending of
mr empties
DV. In addition, the event of
send(
mr) takes place such that
delivery(
mk) →
send(
mr) →
send(
ml). Therefore,
mk does not directly precede message
ml.
If neither of these two events occur, we have that
DV[
k] is set when the
send(
ml) is carried out and by Line 1 of
Listing 4, we have that
ml.
DV[
k] is set.
Step 2: If ml.DV[k] is set, then mk↓ml.
The proof is by contradiction. By Lemma 1, we know that if ml.DV[k] is set then mk → ml with pi ≠ pj. We suppose that there is a message mr such that send(mk) by pi → send(mr) by pr → send(ml) by pj, and in addition that mk↓mr. The proof considers two cases: pr ≠ pj and pr = pj.
We consider the case where
pr ≠
pj and the delivery
mk causally precedes
mr (
delivery(
mk) →
delivery(
mr)) at
pj. By step 1, we know that
mr.
DV[
k] is set. Hence, on the delivery
mr (
delivery(
mr)) at
pj,
DV[
k] is cleared Line 3 of
Listing 6. When performing the sending of
ml (
send(
ml)) and because of
delivery(
mr) →
send(
ml), then
DV[
k] at peer
pj is cleared and therefore,
ml.
DV[
k] is cleared, which is a contradiction.
In the case where
pr =
pj, we have that
delivery(
mk) →
send(
mr) →
send(
ml), because the sending of
mr (
send(
mr)) takes place,
DV[
k] is cleared by Line 3 of
Listing 4. Therefore, we have that
ml.
DV[
k] is cleared, which is a contradiction.
Finally, the following proposition shows that through the bits attached to the sent messages and the information stored at the super peer, we ensure the causal order in the overlay peer-to-peer network.
Proposition 1. If ml.DV[k] is set and mk is a message from the external group then TT contains (in, k).
Proof. By Line 19 of
Listing 15, we have that (
in,
k′) is inserted into
TT[
mk′.
id] only after the delivery of message
mk′ at the super peer where (
mk′.
id,
in) identifies a message in the external group. The corresponding internal message has
SN equals to
k′. In the delivery of
mk′ at
pj with
SN=
k′, we have (by Line 4 of
Listing 6) that
DV[
k′] is set. We know by Lemma 3 that if
ml.
DV[
k′] is set then
mk′↓ml. On the reception of message
ml sent by
pj with
ml.
DV[
k′] set at the super peer, by Lines 5–21 of
Listing 14, we have that
TT contains an element (
in′,
out′) where
out’ =
k′ at position
mk′.
id which identifies a message (
mk′.
id,
in′) in the IDR protocol of the external group.
3.1.4. Causal Protocol Description
To describe how our proposed protocol detects causal order violations, we use a scenario (see
Figure 3) composed of a network that consists of the following:
Two internal peers with identifiers in an internal group 1 and 2, denoted as P(i)1 and P(i)2.
A super peer with an identifier in an external group 1, denoted as Sp1.
Two external peers with identifiers in an external group 2 and 3, denoted as P(i)2 and P(i)3.
This scenario contains three types of messages:
Messages in an external group, represented as a solid line.
Messages in an internal group from peer to super peer, represented by a dashed line.
Messages in an internal group from super peer to peers, represented by a dotted line.
We mark with the X a message delivery that violates a causal order.
Diffusion of m3 at P(i)2
First, an internal peer increments its sequence number to 1 (see
Listing 4, Line 1).
An internal peer generates a message
m3 = (2, 1, 0, 01,
Data) (see
Listing 4, Line 2).
The
DV variable is cleared (see
Listing 4, Line 3).
Reception of m(e)3 at P(e)3
Reception of m2 at P(e)3
When a peer
P(
e)
3 receives
m2, it checks its delivery condition.
- ◦
The FIFO delivery condition is satisfied (see
Listing 11, Line 1): 1 = 0 + 1 and
m2.
CI contains <3, 1>, and this dependency is satisfied because
idext = 3. Both conditions are satisfied, and the message
m2 can be delivered.
A clock component for peer 2 is updated with a new value (see
Listing 12, Line 2):
VTx(
p) = (11, 1, 1) and
CI is empty, so a new message dependency is inserted (see
Listing 12, Line 10):
CI = <2, 1>.
Message buffer contains
m(
e)
3. Its delivery condition should be revalidated.
- ◦
The FIFO delivery condition is not checked because the message arrived from a super peer.
- ◦
m(
e)
3.
CI contains <2, 1> and
VTx[2] is an integer, so the causal condition is satisfied (see
Listing 11, Line 2): 1 ≤ 1.
- ◦
Both conditions are satisfied, and the message m(e)3 can be delivered.
A clock component for super peer (
idext = 1) is updated with a new value (see
Listing 12, Line 2):
VTx(
p) = (111, 1, 1).
The
CI does not contain an element for peer 1, so a new message dependency is inserted (see
Listing 12, Line 10):
CI = <1, 001>, <2, 1>.
m(
e)
3.
CI contains <2, 1>, so this pair is removed from
CI (see
Listing 12, Line 19):
CI = <1, 001>
Diffusion of m4 at P(e)2
First, an external peer increments its clock (see
Listing 9, Line 1):
VTx(
p) = (111, 2, 1). An external peer generates a message
m4 = (2, 2, <1, 001>, Ø,
Data) (see
Listing 9, Line 2), and the
CI is cleared (see
Listing 9, Line 3).
Reception of m4 at P(e)3
When a peer
P(
e)
3 receives
m4, it checks its delivery condition.
- ◦
The FIFO delivery condition is satisfied (see
Listing 11, Line 1): 2 = 1 + 1 and
m4.
CI contains <1, 001> and
VTx[1] is a bit vector, so this dependency is satisfied (see
Listing 11, Line 2): 001 & 111 = 001. Both conditions are satisfied, and the message
m4 can be delivered.
A clock component for peer 2 is updated with a new value (see
Listing 12, Line 2):
VTx(
p) = (111, 2, 1).
The
CI does not contain an element for peer 2, so a new message dependency is inserted (see
Listing 12, Line 10):
CI = <1, 001>, <2, 2>.
m4.
CI contains <1, 001> so this pair is modified (see
Listing 12, Line 21):
CI = <1, 000>, <2, 2>, and empty dependency <1, 000> is removed, so
CI = <2, 2>.
Reception of m4 at Sp1
When a super peer
Sp1 receives
m4, it checks its delivery condition.
- ◦
The FIFO delivery condition is satisfied (see
Listing 11, Line 1): 2 = 1 + 1.
m4.
CI contains <1, 001> and this dependency is satisfied because
idext = 1. Both conditions are satisfied and the message
m4 can be delivered.
A clock component for peer 2 (see
Listing 13, Line 29) and for this super peer (see
Listing 13, Line 6) are updated with a new value:
VTx(
p) = (4, 2, 1).
Reception of m(i)4 at P(i)2
When a peer
P(
i)
2 receives
m(
i)
4, it checks its delivery condition.
- ◦
The FIFO delivery condition is satisfied (see
Listing 5, Line 1):
RV[2] = 1, and the causal delivery condition (see
Listing 5, Line 2) is also satisfied: 001 & 111 = 001.
- ◦
Both conditions are satisfied, and the message m(i)4 can be delivered.
The receive vector is updated (see
Listing 6, Line 1):
RV = 1111.
The message dependency vector is updated as well (see
Listing 6, Lines 3–5):
DV = 0001.
Reception of m(i)4 at P(i)1
When a peer
P(
i)
1 receives
m(
i)
4, it checks its delivery condition.
- ◦
The FIFO delivery condition is satisfied (see
Listing 5, Line 1):
RV[2] = 1, but the causal delivery condition (see
Listing 5, Line 2) is violated: 001 & 11 = Ø ≠ 001. Therefore, the message delivery condition is not satisfied, and message
m(
i)
4 should be buffered.
Reception of m(i)3 at P(i)1
When a peer
P(
i)
1 receives
m(
i)
3, it checks its delivery condition.
- ◦
The FIFO delivery condition is satisfied (see
Listing 5, Line 1):
RV[0] = 1. The causal delivery condition (see
Listing 5, Line 2) is also satisfied: 01 & 11 = 01. Both conditions are satisfied, and the message
m(
i)
3 can be delivered.
The receive vector is updated (see
Listing 6, Line 1):
RV = 111.
The message dependency vector is updated as well (see
Listing 6, Lines 3–5):
DV = 001.
The message buffer contains
m(
i)
4. Its delivery condition should be revalidated.
- ◦
The FIFO delivery condition is satisfied (see
Listing 5, Line 1):
RV[2] = 1, and the causal delivery condition (see
Listing 5, Line 2) is also satisfied: 001 & 111 = 001. Both conditions are satisfied, and the message
m(
i)
4 can be delivered.
The receive vector is updated (see
Listing 6, Line 1):
RV = 1111.
The message dependency vector is updated as well (see
Listing 6, Lines 3–5):
DV = 0001.
3.1.5. Overhead Analysis
As the proposed protocol depends on the Immediate Dependency Relation protocol [
14], the size of the control information of message
m depends on the number of concurrent messages that form an IDR with
m.
In the internal group, all of the messages are sequentially numbered. As a message m cannot form an IDR with more than n-1 messages (n is the number of processes in a system), its dependency vector cannot contain more than the n-1 set bits. However, the set bits can be separated by cleared bits. Let m1 be the message with the lowest sequence number to form an IDR with m. Then a bit vector can have no more bits than the number of messages concurrent to m1 that exist in a system. As message delay is finite, then each process can generate a finite number of messages concurrent to m1. Thus, a total number of messages concurrent to m1 is also finite and it is proportional to a number of processes in a system producing an overhead of O(n) bits.
In the external group, message dependencies are represented as a combination of dependencies on external messages and dependencies on internal messages. The number of elements that represent dependencies on external messages are limited by the number of processes in an external group (peers and super peers), thus limiting a number of pairs that represent message dependency to O(l) (l is the number of peers and super peers in the external group). As vector I in the external message, its size is limited by the number of messages that can be generated in the external and internal groups producing an overhead of vector I to O(n) (the same as overhead in the internal group).
We notice that in our protocol, as for the minimal causal algorithm in [
14], the likelihood that the worst case will occur approaches zero as the number of participants in the group grows. This is because the likelihood that
k concurrent messages occur decreases inversely proportional to the size of the communication group. This behavior has been shown in [
14].
3.2. Simulations
To analyze our protocol, we carry out different simulations. The scenario used in these simulations consists of one internal group and one external group connected by one super peer. All of the peers in the system are divided equally between these two groups. In the simulation, each peer generates a message every 70–90 milliseconds. The system is simulated with a different number of peers and with different delays in the communication channels. All of the simulation scenarios are listed in
Table 1. The simulations are performed in the OMNeT++ discrete event simulator [
31].
All of the delays are distributed normally with the mean being the middle of the interval and variance equal to one fourth of the interval (for example, message generation time is distributed like N(80, 5) milliseconds). If a random value is generated outside of the interval, the value of the nearest interval end is taken instead.
The simulation program uses the Immediate Dependency Protocol [
14] to compare and validate the protocol presented in this paper. When a message can be delivered to an application by our protocol, it is validated against an IDR to detect causal order violations not detected by our protocol. In addition, the overheads for IDR and Dependency Sequences (DS) [
15] were calculated to be compared with an overhead generated by our protocol.
As the IDR protocol is designed for plain networks, it is simulated in the following way. The super peer in the system is considered transparent for the IDR implementation, and each peer (internal and external) performs the full calculations of the IDR protocol as described in [
14]. A super peer only retransmits the messages between groups.
As for DS protocol simulations, only the external group is considered. Each external peer is simulated as a super peer with exactly one peer in its group.
The results of simulations are analyzed in the following way. Two overheads are mainly analyzed: an overhead of communication (amount of control information required to be sent with a message) and storage overhead (amount of information required to be stored in each peer).
As the Dependency Sequences [
15] stores information only at super peers level, the storage overhead for this protocol is not analyzed.
By considering channel delays from 0 to 50 milliseconds (see
Figure 4), the simulation results show that an overhead in an internal group is lower than an overhead in an external group, and an overhead in an external group is lower than an overhead produced by the Immediate Dependency Relation and the Dependency Sequences protocols. For 900 peers, each internal peer requires storing on average 128 bytes of information, and the average overhead in an internal group is around 90 bytes. In the external group, each peer stores on average 2700 bytes and produces an overhead on average of 950 bytes. The IDR protocol requires storing on average 4900 bytes on each peer and to send 1650 bytes, while the DS protocol sends on average 3950 bytes.
For these delays the results show that the overhead in an internal group is 18.3 times lower than the overhead of IDR and require storing 38 times less information. Overhead in an external group is about 1.7 times lower than the overhead of IDR and 4.1 times lower than the one of DS protocol, and require storing 1.7 times less information.
As all of the overheads have a liner type growth we calculate the slope using the least squares method. For communication overheads, the slopes are: 0.098 for internal group, 1.018 for external group, 1.760 for IDR and 4.356 for DS protocol. For storage overheads, the slopes are: 0.143 in internal group, 2.952 in external group and 5.388 for IDR protocol.
In our work in order to reduce the size of the variable TT in a super peer, we use the fact that a peer in the internal group can only receive a message that has been already received and delivered by a corresponding super peer. If m1 and m2 are messages that have an immediate dependency relationship m1↓m2, and all the peers in the internal group have received and delivered m2, then the information about m1 can be removed from a super peer. This can be seen from two different aspects: message reception and message sending.
Message reception: a peer can deliver m2 that m1↓m2 if and only if it has already delivered m1. If a peer received a message m3 that m1↓m3 and has already delivered m2 (which implies delivery of m1), then it can deliver m3 without any delay. This way the information about dependency on m1 does not affect the m3 delivery in any way.
Message sending: if a peer delivered message m2, then no message originated from this peer can carry any dependency on m1 and the information about m1 in super peer is no longer required.
Therefore, if all peers have delivered m2 such that m1↓m2, then the delivery of messages depending on m1 will not be affected in the internal group in any way, and a super peer will not receive any message depending on m1 from the internal group. Thus, the information about m1 can be deleted from variable TT in a super peer.
By considering channel delays from 50 to 250 milliseconds (see
Figure 5), the results also show that an overhead in an internal group is lower than an overhead in an external group, and the overhead in an external group is lower than an overhead produced by the Immediate Dependency Relation and the Dependency Sequences protocols. For 500 peers, each internal peer requires storing on average 300 bytes of information, and the average overhead in an internal group is around 230 bytes. In the external group, each peer stores on average 2100 bytes and produces an overhead on average of 1700 bytes. The IDR protocol requires storing on average of 3400 bytes on each peer and sending 2400 bytes, while the DS have a communication overhead of 2800 bytes.
The results for delays from 50 to 250 milliseconds show that the overhead in an internal group is ten times lower than the overhead of IDR and requires storing eleven times less information. The overhead in an external group is about 1.4 times lower than the overhead of IDR and 1.64 times lower than the one of the DS, and requires storing 1.6 times less information.
For communication overheads, the slopes are: 0.461 for internal group, 3.480 for external group, 4.965 for IDR and 5.561 for DS protocol. For storage overheads, the slopes are: 0.603 in internal group, 4.225 in external group and 6.838 for IDR protocol.
In scenario with delays from 50 to 550 milliseconds (see
Figure 6) and for 400 peers, each internal peer requires storing on average 550 bytes of information and the average overhead in an internal group is around 400 bytes. In the external group, each peer stores on average 1860 bytes and produces an overhead on average of 1400 bytes. The IDR protocol requires storing on average 2500 bytes on each peer and sending 1500 bytes while the DS requires sending 2850 bytes.
These results show that the overhead in an internal group is 3.5 times lower than the overhead of the IDR and requires storing 4.5 times less information. The overhead in an external group is similar to the overhead of the IDR, but requires storing 1.3 times less information. As for the DS protocol, the proposed solution has two times lower communication overhead.
For communication overheads, the slopes are: 0.990 for internal group, 3.617 for external group, 3.830 for IDR and 7.162 for DS protocol. For storage overheads, the slopes are: 1.325 in internal group, 4.680 in external group and 6.378 for IDR protocol.
Scalability Analysis
To analyze the scalability of the system, we evaluate the control information management of the protocol against the message density, which is defined as the number of messages sent per process per time unit. For this last analysis, we conducted the following experiment. The system model from the previous experiment was modified in the following way: each peer, instead of generating the message every 80 milliseconds was modified to generate messages so that the total number of messages remain fixed for each number of peers in the system. For example, in a system with a generation rate of 1000 messages per second, with 50 peers, each peer generates 20 messages per second; in a system with 100 peers, each peer generates 10 messages per second; and in a system with 500 peers, each peer generates two messages per second.
The system is analyzed for the following message generation rates: 2500, 2000, 1500 and 1000 messages per second. The obtained results are compared with the results from the experiment described above. In the experiment above, the number of messages generated in the system is 12.5 per second per peer.
By considering channel delays from 0 to 50 milliseconds (see
Figure 7), the simulation results show that more messages are generated in the system per second; more control information is required to ensure the causal ordering of messages. In addition, the overhead growth has two different stages: a slow growth for a low number of peers (less than 100), and a linear growth part when the number of peers is high (more that 100–200 in this experiment).
Analyzing the growth of the overhead (linear growth part) in the internal group, the slopes are 0.0612 for 2500 messages/second, 0.0611 for 2000 messages per second, 0.0603 for 1500 messages/second and 0.0583 for 1000 messages/second. In the external group, the slopes are 0.0685 for 2500 messages/second, 0.0728 for 2000 messages/second, 0.0735 for 1500 messages/second and 0.0719 for 1000 messages/second. In the original experiment, the slopes are 0.0979 for the internal group and 1.0177 for the external group.
In this scenario, the difference between slopes with the message limit is less than five percent. However, the difference with the original experiment is 1.60 times for the internal group and 13.9 times for the external group.
By considering channel delays from 50 to 250 milliseconds (see
Figure 8), the results also show that more messages are generated in the system per second; more overhead is required to ensure the causal ordering. The overhead has the same growth stages as for the system with communication channel delays from 0 to 50 milliseconds.
Analyzing the growth of the overhead (linear growth part) in the internal group, the slopes are 0.0083 for 2500 messages/second, 0.0041 for 2000 messages per second, 0.0045 for 1500 messages/second and 0.0241 for 1000 messages/second. In the external group, the slopes are 0.4632 for 2500 messages/second, 0.1215 for 2000 messages/second, 0.0147 for 1500 messages/second and −0.0374 for 1000 messages/second. In the original experiment, the slopes are 0.4606 for the internal group and 3.4804 for the external group.
In this scenario in both groups the slopes have a tendency toward zero, which means that the overhead directly depends on the density of the messages exchanged, and does not depend on the number of peers in the system. The slopes from this experiment are 45 times lower for the internal group and 25 times lower for the external group.
In a scenario with delays from 50 to 550 milliseconds (see
Figure 9), the results show that more messages are generated in the system per second, more overhead is required to ensure the causal ordering. The overhead has the same growth stages as for the system with communication channel delays from 0 to 50 milliseconds and from 50 to 250 milliseconds.
Analyzing the growth of the overhead in the internal group, the slopes are 0.002177379 for 2500 messages per second, 0.00272099 for 2000 messages per second, 0.005812997 for 1500 messages per second and −0.006493243 for 1000 messages per second while in the original experiment the slope is 0.990. As for external group the slopes could not be calculated because the linear growth part was not reached but the same tendency as for other network delays can be observed.
In this scenario, the slopes have a tendency toward zero which means that the overhead does not directly depends on the number of peers in the system, but it depends on the message density in the system.
The results obtained from this experiment show that when the number of messages generated in the system per second remains constant, the overhead growth slope has a tendency toward zero. This means that there is no direct dependency between the number of peers in the system and the amount of control information required for causal message ordering. Thus, the number of peers in the system can be relatively high while the message generation rate of the system remains constant.
In addition, it should be noted that the above experiments consider that all of the peers in the system equally participate in the communication. All of the peers that are passive receivers do not increase system overhead. For example, in a system with 300 peers where 200 peers are passive receivers and do not generate any messages, the overhead will be the same as in a system containing only 100 participating peers. We note that in real world P2P applications, such as video call/meeting, current solutions only support up to 25 peers participating equally in the communication. This means that with our protocol, applications could allow up to 100 peers exchange streams in an equitable participation, keeping a controlled overhead growth.
This leads to the following. If several communication groups exist over the same peer-to-peer network, the communication and storage overhead will only depend on the number of peers participating in a group communication, not on the total number of peers in the system. For example, the overhead will depend on the number of people participating in a video conference, and not on a total number of people using the software.