Download as pdf or txt
Download as pdf or txt
You are on page 1of 5

Shivansh Juyal, 2020MCS2471 GHS Implementation 2022-03-07

Vijay Bhardwaj, 2020MCS2476 Advanced Distributed Systems, COL819

1 Overview
GHS algorithm is used to find MST of a graph in a distributed setting. This means that each node is aware
of only it’s immediate neighbour. The code is written in JAVA in which each node is simulated using a single
thread. For emulating message passing, each thread can access a common message buffer which is accessible
to all the nodes. This is implemented by a list of BlockQueue which is thread safe.

2 Code Snippets
2.1 Initialise nodes
1 public Node ( int nodeId , HashMap < Integer , Integer > neighboursWtMap , ArrayList < BlockingQueue <
Message > > messageQueue , BlockingQueue < Boolean > algoStops ) throws I n t e r r u p t e d E x c e p t i o n {
2
3 this . nodeId = nodeId ;
4 this . ne ig h bo ur sW t Ma p = n ei g hb ou rs W tM ap ;
5 this . allNeighbours = ne i gh bo ur s Wt Ma p . keySet () ;
6 this . messageQueue = messageQueue ;
7 this . algoStops = algoStops ;
8 this . t o t a l M e s s a g e s S e n t = 0;
9 for ( Integer i : allNeighbours ) {
10 n e i g h b o u r s S t a t u s M a p . put (i , BASIC ) ;
11 }
12 int minWtNeigh = g e t M i n W t N e i g h b o u r () ;
13 n e i g h b o u r s S t a t u s M a p . put ( minWtNeigh , BRANCH ) ;
14 level = 0;
15 state = FOUND ;
16 rec = 0;
17 name = this . nodeId ;
18 parent = -1;
19 bestNode = -1;
20 bestWt = Integer . MAX_VALUE ;
21 testNode = -1;
22
23 Message tmp = new Message () ;
24 tmp . se tMessag eType ( " connect " ) ;
25 tmp . se tS e nd er N od eI d ( nodeId ) ;
26 ArrayList < Integer > a = new ArrayList < >() ;
27 a . add (0) ;
28 tmp . s e t M e s s a g e P a r a m s ( a ) ;
29 to ta l M e s s a g e s S e n t += 1;
30 messageQueue . get ( minWtNeigh ) . put ( tmp ) ;
31
32 }

This is just initialization of each node. Each nodes initialize it’s map to store the weights of it’s neighbours,
map to store the status of all it’s neighbours, sets the status minimum weight neighbour to B̈RANCHänd sends
a connect message to it.

2.2 Handle Connect Message


1 void h a n d l e C o n n e c t M e s s a g e ( Message message ) throws I n t e r r u p t e d E x c e p t i o n {
2 int q = message . g et S en de rN o de Id () ;
3 int L = message . g e t M e s sa g e P a r a m s () . get (0) ;
4
5 if ( L < level ) {
6 n e i g h b o u r s S t a t u s M a p . put (q , BRANCH ) ;
7
8 Message tmp = new Message () ;
9 tmp . s etMessag eType ( " i n i t i a t e " ) ;
10 tmp . se t Se nd er N od eI d ( nodeId ) ;
11 ArrayList < Integer > a = new ArrayList < >() ;
12 a . add ( level ) ;
13 a . add ( name ) ;
14 a . add ( state ) ;
15 tmp . s e t M e s s a g e P a r a m s ( a ) ;
16 t o t a l M e s s a g e s S e n t += 1;
17 messageQueue . get ( q ) . put ( tmp ) ;
18 }
19
20 else if ( n e i g h b o u r s S t a t u s M a p . get ( q ) == BASIC ) {
21 // t o t a l M e s s a g e s S e n t += 1;

1
22 messageQueue . get ( nodeId ) . put ( message ) ;
23 }
24
25 else {
26 Message tmp = new Message () ;
27 tmp . s etMessag eType ( " i n i t i a t e " ) ;
28 tmp . se t Se nd er N od eI d ( nodeId ) ;
29 ArrayList < Integer > a = new ArrayList < >() ;
30 a . add ( level +1) ;
31 a . add ( ne i gh bo ur s Wt Ma p . get ( q ) ) ;
32 a . add ( FIND ) ;
33 tmp . s e t M e s s a g e P a r a m s ( a ) ;
34 t o t a l M e s s a g e s S e n t += 1;
35 messageQueue . get ( q ) . put ( tmp ) ;
36 }
37 }

The connect message is handled as follows. If the received level is less than the node’s level, this means that
the other fragment wants to merge. In that case we send it the initiate message. Otherwise if the status of the
node from which it sends if basic, we wait for sometime. Otherwise we combine with rule equal to and send
an initiate message with level incremented and name changed.

2.3 Handle Initiate message


1 void h a n d l e I n i t i a t e M e s s a g e ( Message message ) throws I n t e r r u p t e d E x c e p t i o n {
2 int q = message . g et S en de rN o de Id () ;
3 int level1 = message . g e t M e s s a g eP a r a m s () . get (0) ;
4 int name1 = message . g et M e s s a g e P a r a m s () . get (1) ;
5 int state1 = message . g e t M e s s a g eP a r a m s () . get (2) ;
6 level = level1 ;
7 name = name1 ;
8 state = state1 ;
9 parent = q ;
10 bestNode = -1;
11 bestWt = Integer . MAX_VALUE ;
12 testNode = -1;
13
14 for ( Integer i : allNeighbours ) {
15 if ( n e i g h b o u r s S t a t u s M a p . get ( i ) == BRANCH && i != q ) {
16 Message tmp = new Message () ;
17 tmp . se tMessag eType ( " i n i t i a t e " ) ;
18 tmp . se t Se nd er N od eI d ( nodeId ) ;
19 ArrayList < Integer > a = new ArrayList < >() ;
20 a . add ( level1 ) ;
21 a . add ( name1 ) ;
22 a . add ( state1 ) ;
23 tmp . s e t M e s s a g e P a r a m s ( a ) ;
24 t o t a l M e s s a g e s S e n t += 1;
25 messageQueue . get ( i ) . put ( tmp ) ;
26 }
27 }
28
29 if ( state == FIND ) {
30 rec = 0;
31 findMin () ;
32 }
33 }

If a node receives an initiate message, it updates it’s fragment information and reports other node in it’s
fragment about the new data.

2.4 Handle Test message


1 void han d l e T e s t M e s s a g e ( Message message ) throws I n t e r r u p t e d E x c e p t i o n {
2
3 int q = message . g et S en de rN o de Id () ;
4 int level1 = message . g e t M e s s a g eP a r a m s () . get (0) ;
5 int name1 = message . g et M e s s a g e P a r a m s () . get (1) ;
6
7 if ( level1 > level ) {
8 // t o t a l M e s s a g e s S e n t += 1;
9 messageQueue . get ( nodeId ) . put ( message ) ;
10 }
11
12 else if ( name1 == name ) {
13
14 if ( n e i g h b o u r s S t a t u s M a p . get ( q ) == BASIC ) {
15 t o t a l M e s s a g e s S e n t += 1;
16 n e i g h b o u r s S t a t u s M a p . put (q , REJECT ) ;
17 }
18
19 if ( q != testNode ) {
20 Message tmp = new Message () ;
21 tmp . se tMessag eType ( " reject " ) ;
22 tmp . se t Se nd er N od eI d ( nodeId ) ;

2
23 ArrayList < Integer > a = new ArrayList < >() ;
24 t o t a l M e s s a g e s S e n t += 1;
25 messageQueue . get ( q ) . put ( tmp ) ;
26 }
27
28 else {
29 findMin () ;
30 }
31
32 }
33 else {
34 Message tmp = new Message () ;
35 tmp . s etMessag eType ( " accept " ) ;
36 tmp . se t Se nd er N od eI d ( nodeId ) ;
37 ArrayList < Integer > a = new ArrayList < >() ;
38 t o t a l M e s s a g e s S e n t += 1;
39 messageQueue . get ( q ) . put ( tmp ) ;
40 }
41
42 }

When a test message is received, if the sender’s fragment is greater than the receiver, we wait. Otherwise if
they belong to the same fragment, an accept message is sent, otherwise a reject message is sent.

2.5 Handle Accept message


1 void h a n d l e A c c e p t M e s s a g e ( Message message ) throws I n t e r r u p t e d E x c e p t i o n {
2
3 int q = message . g et S en de rN o de Id () ;
4 testNode = -1;
5
6 if ( n ei gh bo u rs Wt Ma p . get ( q ) < bestWt ) {
7 bestWt = n ei gh b ou rs Wt M ap . get ( q ) ;
8 bestNode = q ;
9 }
10
11 report () ;
12
13 }

When an accept message is received, it updates the information and calls report(). report() waits for all it’s
neighbours other than it’s parent to send tell their status and then report it back to it’s own parent.

2.6 Handle Reject message


1 void h a n d l e R e j e c t M e s s a g e ( Message message ) throws I n t e r r u p t e d E x c e p t i o n {
2
3 int q = message . g et S en de rN o de Id () ;
4 if ( n e i g h b o u r s S t a t u s M a p . get ( q ) == BASIC ) {
5
6 n e i g h b o u r s S t a t u s M a p . put (q , REJECT ) ;
7 }
8 findMin () ;
9 }

When a reject message is received, the node changes the status of the branch to reject and then checks if it has
the possibility of sending a test message to one of it’s node which is not rejected yet.

2.7 Handle Report message


1 void h a n d l e R e p o r t M e s s a g e ( Message message ) throws I n t e r r u p t e d E x c e p t i o n {
2
3 int q = message . g et S en de rN o de Id () ;
4 int omega = message . g et M e s s a g e P a r a m s () . get (0) ;
5
6 if ( q != parent ) {
7 if ( omega < bestWt ) {
8 bestWt = omega ;
9 bestNode = q ;
10 }
11 rec += 1;
12 report () ;
13 }
14 else {
15 if ( state == FIND ) {
16 // t o t a l M e s s a g e s S e n t += 1;
17 messageQueue . get ( nodeId ) . put ( message ) ;
18 }
19
20 else if ( omega > bestWt ) {
21 changeRoot () ;
22 }

3
23
24 else if ( omega == bestWt && omega == Integer . MAX_VALUE ) {
25 System . out . println ( " Stops + + + + + + + + " ) ;
26 algoStops . add ( true ) ;
27 }
28 }
29
30 }

When a report message is received, if it’s not from it’s parent, if the weight received is less than the best weight
the node has, it changes the status of best weight and best node corresponding to the sender. It then calls
the report() function. If the message is received from it’s parent, if the node is still in the process of finding,
it waits. Otherwise if the weight received is greater than the best weight, changeRoot() function is called.
Otherwise if both the received weight and best weight is infinity, the algorithm has come to end and thus halt.

2.8 Handle ChangeRoot message


1 void h a n d l e C h a n g e R o o t M e s s a g e ( Message message ) throws I n t e r r u p t e d E x c e p t i o n {
2
3 changeRoot () ;
4
5 }

If a node receives a change root message, it just calls changeRoot().

3 Results
3.1 Results with dense graphs

The probability of an edge between two nodes is 0.8 in our implementation of dense graph. The message
complexity is 2E + O(NlogN) and the plot adheres to this.

4
3.2 Results with sparse graphs

The probability of an edge between two nodes is 0.2 in our implementation of sparse graph. The message
complexity is 2E + O(NlogN) and the plot adheres to this.

You might also like