nsmcp::AccessDiagnosticTool method scanStep (public)

 <instance of nsmcp::AccessDiagnosticTool[i]> 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
[ hide source ] | [ make this the default ]
Show another procedure: