/****************************************************************/ /* mcast.may: multicast using different multicast trees */ /* written by Lihao Xu, EE, Caltech */ /* May 1995 */ /****************************************************************/ #include "mcast.h" /* Given a group (an ordered position set with length g_len) and my id, find my parent id and children id on the n-ary tree Return: parent id, -1 if I am not in the group */ int tree(group,g_len,sender,me,n,children,num_children) int group[],children[]; int g_len,me,sender,n,*num_children; { int my_position,subgrp_len; int low,high,i; int subgroup,parent; /* Find my position in the group using binary search */ low=0;high=g_len-1; while(1){ if(group[low]==me){ my_position=low; break; } if(group[high]==me) { my_position=high; break; } my_position=(low+high)/2; if(low>=high) break; if(group[my_position]==me) break; else if(group[my_position]>me) high=my_position-1; else low=my_position+1; } /* end while */ if(group[my_position] != me) return(-1); /* I am not in the group */ /*if(n==1){ if(my_position==0) parent=sender; else parent=group[my_position-1]; if(my_position==g_len-1) *num_children=0; else{ *num_children=1; children[0]=group[my_position+1]; } return(parent); } *//* Special Case: Tree degrades into a line */ parent=sender; subgrp_len=(g_len+n-1)/n; /* Is this an Optimal Tree? */ subgroup=my_position/subgrp_len; low=subgroup*subgrp_len; high=low+subgrp_len-1; high=min(g_len-1,low+subgrp_len-1); /* last subgroup */ if(my_position==low){ subgrp_len=(high-low+n-1)/n; i=low+1; *num_children=0; while(i<=high){ children[*num_children]=group[i]; (*num_children)++; i += subgrp_len; } } else{ parent=group[low]; while( high-low>n ){ parent=group[low]; low++; subgrp_len=(high-low+n)/n; subgroup=(my_position-low)/subgrp_len; low += (subgroup*subgrp_len); high=min(high,low+subgrp_len-1); if(my_position==low) break; }/* end while */ if(my_position==low){ subgrp_len=(high-low+n-1)/n; i=low+1; *num_children=0; while(i<=high){ children[*num_children]=group[i]; (*num_children)++; i += subgrp_len; } /* end while */ } else{ parent=group[low]; *num_children=0; /*for(i=low+1;i<=high;i++) children[i-low-1]=group[i]; *num_children=high-low;*/ } }/* end else */ return(parent); } /* Find children of the sender in the ACK-collect tree */ /* Return: Number of the children */ int get_children(group,g_len,n,children) int group[], children[]; int g_len,n; { int i,j, subgrp_len; subgrp_len=(g_len+n-1)/n; i=0;j=0; while(i<=g_len-1){ children[j]=group[i]; j++; i += subgrp_len; } return(j); } /* Find the child's position in the children array */ int children_position(child,children,children_num) int child,children[],children_num; { for(i=0;icurrent_time){ current_time=send_time; decision=random()%PRECISION; if(decision=msg_num); msg_source=RECEIVED.packet_head.source; num_to_rcv=RECEIVED.packet_head.msg_size; msg_num=RECEIVED.packet_head.msg_num; parent=tree(RECEIVED.packet_head.group,RECEIVED.packet_head.group_size,me,split,children,&num_children); for(i=0;i