nsmcp::AccessDiagnosticTool method scanStep (public)
<instance of nsmcp::AccessDiagnosticTool> scanStep context state
Defined in /usr/local/ns/tcl/nsmcp/traffic-tools.tcl
- Parameters:
- context (required)
- state (required)
- Testcases:
- No testcase defined.
Source code: set options [dict get $state options] if {![dict exists $state bounds]} { if {![dict exists $options scanStrategy]} {dict set options scanStrategy window} set bounds [:scanBounds $context $options] dict set state bounds $bounds if {[dict get $bounds strategy] eq "completion-window"} { dict set options beforeOffset [dict get $bounds to] dict set options sourceBytes [dict get $bounds sourceBytes] dict set options sourceIdentity [dict get $bounds identity] } } set bounds [dict get $state bounds] set aggregateTraffic [expr {[dict exists $options aggregateTraffic] && [dict get $options aggregateTraffic]}] set traffic {} if {$aggregateTraffic} { if {[dict exists $state traffic]} {set traffic [dict get $state traffic]} else { set traffic {sources {} agents {} authenticationStates {} requestCount 0 status503Count 0 successfulCount 0 successfulTimingCount 0 successfulRunTotal 0.0 unknownPeerCount 0 untrackedSourceRecords 0 unknownUserAgentCount 0 untrackedUserAgentRecords 0} dict set traffic salt [ns_crypto::randombytes -encoding hex 32] } } set page [:page $context [:argumentTriples $options] [dict get $bounds from] [expr {$aggregateTraffic ? "traffic" : ""}]] if {$aggregateTraffic} {dict set state traffic $traffic} set value [ns_json parse [ns_json value -- $page]] if {![dict get $value available]} {return [list $page {} {}]} if {![dict exists $state fields]} { dict set state fields [lindex $page 2] dict set state groups {} dict set state totals {} dict set state matches 0 dict set state selected 0 dict set state pages 0 dict set state coverage [dict get $value coverage] } else { set initial [ns_json parse [ns_json value -- [list {} object [dict get $state fields]]]] foreach key {sourceIdentity mappingIdentity from to lookupMode selectedCategory} { if {[dict get $initial $key] ne [dict get $value $key]} {error "Routing scan identity changed; start a new query"} } set coverage [dict get $state coverage] set nextCoverage [dict get $value coverage] foreach key {unrecognizedRecords oversizedRecords missingUserAgent missingPool} { dict incr coverage $key [dict get $nextCoverage $key] } dict set coverage pendingFinalRecord [expr {[dict get $coverage pendingFinalRecord] || [dict get $nextCoverage pendingFinalRecord]}] dict set coverage examinedFromOffset [dict get $nextCoverage examinedFromOffset] dict set coverage unreadEarlierBytes [dict get $nextCoverage unreadEarlierBytes] dict set state coverage $coverage } dict incr state pages dict incr state matches [dict get $value matches] dict incr state selected [dict get $value selectedMatches] set totals [dict get $state totals] dict for {category count} [dict get $value categoryTotals] {dict incr totals $category $count} dict set state totals $totals set groups [dict get $state groups] foreach record [dict get $value records] { set key [:aggregateKey $record] if {[dict exists $groups $key]} { set group [dict get $groups $key] foreach field {count timingCount} {dict incr group $field [dict get $record $field]} dict set group runTotal [expr {[dict get $group runTotal]+[dict get $record runTotal]}] dict set group runMax [expr {max([dict get $group runMax],[dict get $record runMax])}] dict set group firstAt [expr {min([dict get $group firstAt],[dict get $record firstAt])}] dict set group lastAt [expr {max([dict get $group lastAt],[dict get $record lastAt])}] dict set groups $key $group } else { if {[dict size $groups]>=[dict get $options limit]} { set worst [:evidencePriority [dict get $record category]] set victim {} dict for {otherKey otherRecord} $groups { set rank [:evidencePriority [dict get $otherRecord category]] if {$rank>$worst} {set worst $rank; set victim $otherKey} } if {$victim eq ""} {continue} dict unset groups $victim } dict set groups $key $record } } # Bound state by the same evidence byte budget used for individual pages. set ordered {} dict for {key group} $groups {lappend ordered [list [:evidencePriority [dict get $group category]] $key $group]} set groups {}; set entries {}; set index 0; set bytes 0; set returned 0 set omitted {} dict for {category count} $totals { if {[dict get $value selectedCategory] eq "" || [dict get $value selectedCategory] eq $category} {dict set omitted $category $count} } foreach pair [lsort -integer -index 0 $ordered] { lassign $pair priority key record set fields [:recordFields $record] set size [string bytelength [ns_json value -- [list {} object $fields]]] if {$bytes+$size>65536} {continue} incr bytes $size dict set groups $key $record lappend entries $index object $fields incr index incr returned [dict get $record count] dict incr omitted [dict get $record category] [expr {-[dict get $record count]}] } dict set state groups $groups set counts {}; dict for {category count} $totals {lappend counts $category number $count} set omittedCounts {}; dict for {category count} $omitted {lappend omittedCounts $category number $count} set coverage [dict get $state coverage] set coverageFields {} foreach {key type original} [ns_json triples getvalue -output triples -path coverage -- $page] { lappend coverageFields $key $type [dict get $coverage $key] } lappend coverageFields scanStrategy string [dict get $bounds strategy] seekReason string [dict get $bounds reason] seekMarginSeconds number 300 seekProbeBytes number [dict get $bounds probeBytes] skippedEarlierBytes number [dict get $bounds from] skippedLaterBytes number [expr {[dict get $bounds sourceBytes]-[dict get $bounds to]}] completionOrderAssumed boolean [expr {[dict get $bounds strategy] eq "completion-window"}] lappend coverageFields pages number [dict get $state pages] aggregationScope string all-examined-pages sourceFullyExamined boolean [expr {[dict get $coverage unreadEarlierBytes]==0 && [dict get $coverage examinedToOffset]==[dict get $coverage sourceBytes]}] set fields {} foreach {key type original} [dict get $state fields] { switch -- $key { matches {set original [dict get $state matches]} selectedMatches {set original [dict get $state selected]} filteredOutRecords {set original [expr {[dict get $state matches]-[dict get $state selected]}]} categoryTotals {set original $counts} omittedRecords {set original [expr {[dict get $state selected]-$returned}]} omittedCategoryTotals {set original $omittedCounts} records {set original $entries} more {set original false} nextArguments {set original {}} coverage {set original $coverageFields} } lappend fields $key $type $original } if {$aggregateTraffic} { lappend fields trafficAggregation object [:trafficTriples $traffic [expr {[dict get $options to]-[dict get $options from]}] [expr {![dict get $value more]}]] } lappend fields scanComplete boolean [expr {![dict get $value more]}] set continuation {} if {[dict get $value more]} { set nextOptions [dict get $value nextArguments] dict set nextOptions aggregateTraffic $aggregateTraffic dict set state options $nextOptions set continuation $state } set progress [list examinedBytes number [expr {[dict get $bounds to]-[dict get $coverage unreadEarlierBytes]}] sourceBytes number [expr {[dict get $bounds to]-[dict get $bounds from]}]] return [list [list {} object $fields] $continuation $progress]XQL Not present: Generic, PostgreSQL, Oracle
![[i]](/resources/acs-subsite/ZoomIn16.gif)