📄 ns-rca.tcl
字号:
$self instvar pending_delay_ puts "I've just received an indirect REQ for [$meta_data metatostring]." # What data have we heard advertised for this destination? $advlist_ pp "Current advlist" puts "Looking up destination $link_dst" set adv_meta [$advlist_ findADV $link_dst] puts "Received adv_meta $adv_meta" if {$adv_meta == ""} { # We never heard the ADV. Forget about this message, since # link_dst may not even be our neighbor. puts "Heard an REQ for [$meta_data metatostring] data that we've never heard advertised." $meta_data destroy return } # We need to find the intersection of the data that is being # requested and the data we need. set meta_we_need [$meta_data copy] $meta_we_need subtract $has_ $meta_we_need subtract $pending_ # Now intersect this data with the requested data $meta_we_need intersection $meta_data # Now see whether we've heard an advertisement for this # data from this particular destination. if {![$meta_we_need emptyset?] && [$meta_we_need subset $adv_meta] == 1} { puts "\t adding [$meta_we_need metatostring] to pending_" $pending_ union $meta_we_need # Set this meta data to ageout from the pending list set metastring [$meta_we_need metatostring] $ns_ at [expr [$ns_ now] + $pending_delay_] "$self ageout_pending $link_dst \"$metastring\"" return } $meta_we_need destroy $meta_data destroy}Application/RCApp instproc recvREQ {link_dst sender meta_data} { global REQ $self instvar stats_ $stats_ update_rcvs $sender $REQ [$meta_data numelements] 0 set nodeID [[[$self agent] set node_] id] if {$nodeID != $link_dst} { $self recvIndirectREQ $link_dst $sender $meta_data } else { $self recvDirectREQ $sender $meta_data }}Application/RCApp instproc recvRESEND {sender meta_data} { global DATA REQ MAC_BROADCAST LINK_BROADCAST ns_ $self instvar has_ stats_ already_sent_data_ advlist_ $self instvar pending_delay_ resend_timeout_ puts "I just received a resend request for data [$meta_data metatostring]." # Figure out how much of this data we actually possess set meta_we_have [$meta_data copy] # Send the data if we possess it $meta_we_have intersection $has_ if {[$meta_we_have emptyset?]} { puts "Node $nodeID does not have data requested by Node $sender" $meta_we_have destroy $meta_data destroy return } # Now figure out how large a message would be if we sent it set datasize [$meta_we_have maptosize] set copy_meta [$meta_we_have copy] $self send_now $MAC_BROADCAST $LINK_BROADCAST $DATA $copy_meta $datasize $meta_data destroy $meta_we_have destroy}# RCApp::recvDATA## This function handles a DATA message. If this is not the last packet # of the data, wait for remaining packets before continue and destroy# meta_data. If all the data has been received, figure out what is # new data, update stats, and send data to computation module (meta_data# is destroyed in this function).Application/RCApp instproc recvDATA {link_dst sender meta_data data_size} { global DATA $self instvar has_ stats_ pending_ set full_packet_size [[$self agent] set packetSize_] if {$data_size == $full_packet_size} { puts "Waiting for rest of the data associated with [$meta_data metatostring]" $meta_data destroy return } set origsize [$meta_data maptosize] $stats_ update_rcvs $sender $DATA [$meta_data numelements] $origsize # Take this data out of the pending list $pending_ subtract $meta_data # Figure out which meta-data is new $meta_data subtract $has_ if {![$meta_data emptyset?]} { set usefulsize [$meta_data maptosize] $stats_ update_useful $sender $DATA [$meta_data numelements] $usefulsize # Compute with the new data # When computation is complete, function calls finishCOMP function $self computeDATA $meta_data $sender } else { puts "Node [[[$self agent] set node_] id] received no new data from $sender" $meta_data destroy } return}# RCApp::finishCOMP# This function is called when the computation has finished (simulated# by a certain waiting time). It updates the has_ and wants_ lists based# on the meta_data on which the computation was performed and it decides# whether to ADV any new data to the node's neighbors.Application/RCApp instproc finishCOMP {meta_data sender} { global ADV DATA ns_ MAC_BROADCAST LINK_BROADCAST $self instvar adv_threshold_ has_ wants_ advert_id_ puts "\n***********Finished computation (Time is [$ns_ now])***********" # Update has based on the data we received $has_ union $meta_data # Remove the data we received from wants $wants_ subtract $has_ # log it if there is new stuff # this is separate from the check below, # which may depend upon the energy level. if {![$meta_data emptyset?]} { $self log-acquired $has_ } # Decide whether have enough energy to ADV data # Note: if data is ADV'd, node must send the data #set adv_meta [$self decideADV $meta_data] set adv_meta [$self decideADV $has_] if {![$adv_meta emptyset?]} { puts "Node [[[$self agent] set node_] id] sending ADV ([$adv_meta metatostring]) to neighbors..." set metasize [$adv_meta maptosize] set copy_meta [$adv_meta copy] if {$metasize <= $adv_threshold_} { $self send $MAC_BROADCAST $LINK_BROADCAST $DATA $copy_meta $metasize } else { $self send_meta $MAC_BROADCAST $LINK_BROADCAST $ADV $copy_meta } } else { puts "Decided NOT to send ADV of data [$meta_data metatostring]." } $adv_meta destroy $meta_data destroy}############################################################################## Sending functions############################################################################## RcApp::send_meta and RcApp::send# Sends a message with the given type to the sender These functions_ DO# NOT DESTROY the meta-data that is passed in as an argument.Application/RCApp instproc send_meta {mac_dst link_dst type meta_data} { $self send $mac_dst $link_dst $type $meta_data 0}Application/RCApp instproc send {mac_dst link_dst type meta_data data_size} { global ns_ $self instvar rng_ set random_delay [expr 0.005 + [$rng_ uniform 0 0.005]] $ns_ at [expr [$ns_ now] + $random_delay] "$self send_now $mac_dst $link_dst $type $meta_data $data_size"} Application/RCApp instproc send_now {mac_dst link_dst type meta_data data_size} { global opt $self instvar stats_ $stats_ update_sends $mac_dst $type [$meta_data numelements] $data_size # Set up the message type [$self agent] set packetMsg_ $type # Set the destination [$self agent] set dst_ $mac_dst # Turn the meta-data into a parsable message set meta_string [$meta_data metatostring] set nodeID [[[$self agent] set node_] id] set destinationID $mac_dst set msg [lindex [list ADV REQ DATA RESEND] $type] puts "Node $nodeID sending $msg ($meta_string) to Node $destinationID ($link_dst). Data size is $data_size." [$self agent] sendmsg $data_size $meta_string $mac_dst $link_dst $meta_data destroy}############################################################################## Resource-aware decision-making functions#############################################################################Application/RCApp instproc decideADV meta_data { $self instvar has_ neighbors_ advlist_ md_class_ # Do not advertise this data if all known neighbors have already advertised it. set neighborlist [$neighbors_ settolist] set same 1 # puts "\n\tdecideADV testing for sameness" for {set i 0} {($i < [llength $neighborlist]) && ($same == 1)} {incr i} { set neighbor [lindex $neighborlist $i] set neighbor_meta [$advlist_ findADV $neighbor] if {$neighbor_meta == ""} { set same 0 } else { set same [$meta_data subset $neighbor_meta] } } if {($same == 1) && ($neighborlist != "")} { puts "Yay! We just saved ourselves an advertisement!!!" set emptyset [new $md_class_] return $emptyset } set meta_copy [$meta_data copy] return $meta_copy} Application/RCApp instproc decideREQ meta_data {# puts "Not using resource-aware decision making for decideREQ." return [$meta_data copy]} Application/RCApp instproc computeDATA {meta_data sender} {# puts "Not performing any application computation." $self finishCOMP $meta_data $sender} Application/RCApp instproc ageout_pending {link_dst metastring} { global ns_ REQ MAC_BROADCAST $self instvar pending_ md_class_ pending_delay_ advlist_ puts "Pending timeout: [[$self agent] set addr_] data $metastring." set meta_data [new $md_class_] $meta_data stringtometa $metastring $meta_data intersection $pending_ # Is this data still pending? if {[$meta_data emptyset?]} { puts "Agent [[$self agent] set addr_] data $metastring is no longer pending." $meta_data destroy return } $self send_now $MAC_BROADCAST $link_dst $REQ $meta_data 0 $ns_ at [expr [$ns_ now] + $pending_delay_] "$self ageout_pending $link_dst \"$metastring\""}Application/RCApp instproc resend_timeout {metastring} { global ns_ $self instvar already_sent_data_ md_class_ set nodeID [[[$self agent] set node_] id] puts "Resend timeout: Node $nodeID putting $metastring back on the list of data we can send" set meta_data [new $md_class_] $meta_data stringtometa $metastring $already_sent_data_ subtract $meta_data #NEW!!! $meta_data destroy}Application/RCApp instproc count_duplicates {meta_data} { $self instvar advlist_ neighbors_ has_ # We start out with 1 because we assume that the # meta_data is in our own data-set. set dup 1 foreach pair [$advlist_ settolist] { set neighbor_meta [lindex $pair 1] if {![$meta_data subset $neighbor_meta]} { incr dup } } if {![$meta_data subset $has_]} { incr dup } puts "count duplicates for [$meta_data metatostring] is $dup" return $dup}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -