📄 srm.tcl
字号:
if ![catch "$agent_ set trace_" traceVar] { $self set trace_ $traceVar } $self array set times_ [list \ startTime [$ns_ now] serviceTime -1 distance -1]}SRM instproc set-params {sender msgid} { $self next $self instvar agent_ sender_ msgid_ round_ sent_ set sender_ $sender set msgid_ $msgid set round_ [$agent_ round? $sender_ $msgid_] set sent_ 0}SRM instproc cancel {} { $self instvar ns_ eventID_ if [info exists eventID_] { $ns_ cancel $eventID_ unset eventID_ }}SRM instproc schedule {} { $self instvar round_ incr round_}SRM instproc distance? node { $self instvar agent_ times_ distf_ set times_(distance) [$distf_ $times_(distance) \ [$agent_ distance? $node]]}SRM instproc serviceTime {} { $self instvar ns_ times_ set times_(serviceTime) [expr ([$ns_ now] - $times_(startTime)) / \ ( 2 * $times_(distance))]}# Some routines to make SRM tracing standardSRM instproc logpfx fp { $self instvar ns_ nid_ sender_ msgid_ round_ puts -nonewline $fp [format "%7.4f" [$ns_ now]] puts -nonewline $fp " n $nid_ m <$sender_:$msgid_> r $round_ "}SRM instproc dump-stats fp { $self instvar times_ statistics_ $self logpfx $fp puts -nonewline $fp "type [string range [$self info class] 4 end] " puts $fp "[array get times_] [array get statistics_]"}SRM instproc evTrace {tag type args} { $self instvar trace_ if [info exists trace_] { $self logpfx $trace_ puts -nonewline $trace_ "$tag $type" foreach elem $args { puts -nonewline $trace_ " $elem" } puts $trace_ {} }}####SRM/request instproc init args { eval $self next $args $self array set statistics_ "dupRQST 0 dupREPR 0 #sent 0 backoff 0"}SRM/request instproc set-params args { eval $self next $args $self instvar agent_ sender_ foreach var {C1_ C2_} { if ![catch "$agent_ set $var" val] { $self instvar $var set $var $val } } $self distance? $sender_ $self instvar backoff_ backoffCtr_ backoffLimit_ set backoff_ 1 set backoffCtr_ 0 set backoffLimit_ [$agent_ set requestBackoffLimit_] $self evTrace Q DETECT}SRM/request instproc dup-request? {} { $self instvar ns_ round_ ignore_ if {$round_ == 2 && [$ns_ now] <= $ignore_} { return 1 } else { return 0 }}SRM/request instproc dup-repair? {} { return 0}SRM/request instproc backoff? {} { $self instvar backoff_ backoffCtr_ backoffLimit_ set retval $backoff_ if {[incr backoffCtr_] <= $backoffLimit_} { incr backoff_ $backoff_ } set retval}SRM/request instproc compute-delay {} { $self instvar C1_ C2_ set rancomp [expr $C1_ + $C2_ * [uniform 0 1]] $self instvar sender_ backoff_ set dist [$self distance? $sender_] $self evTrace Q INTERVALS C1 $C1_ C2 $C2_ d $dist i $backoff_ set delay [expr $rancomp * $dist]}SRM/request instproc schedule {} { $self instvar ns_ eventID_ delay_ $self next set now [$ns_ now] set delay_ [expr [$self compute-delay] * [$self backoff?]] set fireTime [expr $now + $delay_] $self evTrace Q NTIMER at $fireTime set eventID_ [$ns_ at $fireTime "$self send-request"]}SRM/request instproc cancel type { $self next if {$type == "REQUEST" || $type == "REPAIR"} { $self instvar agent_ round_ if {$round_ == 1} { $agent_ update-ave req [$self serviceTime] } }}SRM/request instproc send-request {} { $self instvar agent_ round_ sender_ msgid_ sent_ round_ $self evTrace Q SENDNACK $agent_ send request $round_ $sender_ $msgid_ $self instvar statistics_ incr statistics_(#sent) set sent_ $round_}SRM/request instproc recv-request {} { $self instvar ns_ agent_ round_ delay_ ignore_ statistics_ if {[info exists ignore_] && [$ns_ now] < $ignore_} { incr statistics_(dupRQST)# $self evTrace Q NACK dup } else { $self cancel REQUEST $self schedule ;# or rather, reschedule-rqst set ignore_ [expr [$ns_ now] + ($delay_ / 2)] incr statistics_(backoff) $self evTrace Q NACK IGNORE-BACKOFF $ignore_ }}SRM/request instproc recv-repair {} { $self instvar ns_ agent_ sender_ msgid_ ignore_ eventID_ if [info exists eventID_] { $self serviceTime set ignore_ [expr [$ns_ now] + 3 * [$self distance? $sender_]] $ns_ at $ignore_ "$agent_ clear $self $sender_ $msgid_" $self cancel REPAIR $self evTrace Q REPAIR IGNORES $ignore_ } else { ;# we must be in the 3dS,B holdDown interval $self instvar statistics_ incr statistics_(dupREPR)# $self evTrace Q REPAIR dup }}#SRM/repair instproc init args { eval $self next $args $self array set statistics_ "dupRQST 0 dupREPR 0 #sent 0"}SRM/repair instproc set-params args { eval $self next $args $self instvar agent_ requestor_ foreach var {D1_ D2_} { if ![catch "$agent_ set $var" val] { $self instvar $var set $var $val } } $self distance? $requestor_ $self evTrace P NACK from $requestor_}SRM/repair instproc dup-request? {} { return 0}SRM/repair instproc dup-repair? {} { $self instvar ns_ round_ if {$round_ == 1} { ;# because repairs do not reschedule return 1 } else { return 0 }}#SRM/repair instproc compute-delay {} { $self instvar D1_ D2_ set rancomp [expr $D1_ + $D2_ * [uniform 0 1]] $self instvar requestor_ set dist [$self distance? $requestor_] $self evTrace P INTERVALS D1 $D1_ D2 $D2_ d $dist set delay [expr $rancomp * $dist]}SRM/repair instproc schedule {} { $self instvar ns_ eventID_ $self next set fireTime [expr [$ns_ now] + [$self compute-delay]] $self evTrace P RTIMER at $fireTime set eventID_ [$ns_ at $fireTime "$self send-repair"]}SRM/repair instproc cancel type { $self next if {$type == "REQUEST" || $type == "REPAIR"} { $self instvar agent_ round_ if {$round_ == 1} { $agent_ update-ave rep [$self serviceTime] } }}SRM/repair instproc send-repair {} { $self instvar ns_ agent_ round_ sender_ msgid_ requestor_ sent_ round_ $self evTrace P SENDREP $agent_ set requestor_ $requestor_ $agent_ send repair $round_ $sender_ $msgid_ $self instvar statistics_ incr statistics_(#sent) set sent_ $round_}SRM/repair instproc recv-request {} { # duplicate (or multiple) requests $self instvar statistics_ incr statistics_(dupRQST)# $self evTrace P NACK dup}SRM/repair instproc recv-repair {} { $self instvar ns_ agent_ round_ sender_ msgid_ eventID_ requestor_ if [info exists eventID_] { # # holdDown is identical to the ignore_ parameter in # SRM/request::recv-repair. However, since recv-request # for this class is very simple, we do not need an # instance variable to record the current state, and # hence only require a simple variable. # set holdDown [expr [$ns_ now] + \ 3 * [$self distance? $requestor_]] $ns_ at $holdDown "$agent_ clear $self $sender_ $msgid_" $self cancel REPAIR $self evTrace P REPAIR IGNORES $holdDown } else { ;# we must in the 3dS,B holdDown interval $self instvar statistics_ incr statistics_(dupREPR)# $self evTrace P REPAIR dup }}#SRM/session instproc init args { eval $self next $args $self instvar agent_ sessionDelay_ round_ set sessionDelay_ [$agent_ set sessionDelay_] set round_ 1 $self array set statistics_ "#sent 0" $self set sender_ 0 $self set msgid_ 0}SRM/session instproc delete {} { $self instvar $ns_ eventID_ $ns_ cancel $eventID_ $self next}SRM/session instproc schedule {} { $self instvar ns_ agent_ sessionDelay_ eventID_ $self next # What is a reasonable interval to schedule session messages? set fireTime [expr $sessionDelay_ * [uniform 0.9 1.1]] # set fireTime [expr $sessionDelay_ * [uniform 0.9 1.1] * \ (1 + log([$agent_ set groupSize_])) ] set eventID_ [$ns_ at [expr [$ns_ now] + $fireTime] \ "$self send-session"]}SRM/session instproc send-session {} { $self instvar agent_ statistics_ $agent_ send session $self evTrace S SESSION incr statistics_(#sent) $self schedule}SRM/session instproc evTrace args {} ;# because I don't want to trace # session messages.Class SRM/session/log-scaledSRM/session/log-scaled instproc schedule {} { $self instvar ns_ agent_ sessionDelay_ eventID_ # What is a reasonable interval to schedule session messages? #set fireTime [expr $sessionDelay_ * [uniform 0.9 1.1]] set fireTime [expr $sessionDelay_ * [uniform 0.9 1.1] * \ (1 + log([$agent_ set groupSize_])) ] set eventID_ [$ns_ at [expr [$ns_ now] + $fireTime] \ "$self send-session"]}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -