nsmcp::CachedLogSearch method results (public)
<instance of nsmcp::CachedLogSearch> results handle [ cursor ] \ [ limit ]
Defined in /usr/local/ns/tcl/nsmcp/log-summary.tcl
Retrieve a bounded page from an unexpired cached search. Validate the handle and page bounds under the mutex and retain coverage and truncation metadata.
- Parameters:
- handle (required)
- Retained job or conversation handle; ownership and expiry checks still apply.
- cursor (optional, defaults to
"0")- Zero-based cursor into retained results. Defaults to '0'.
- limit (optional, defaults to
"20")- Maximum number of records or entries to return. Defaults to '20'.
- Returns:
- The cached page dictionary.
- Testcases:
- No testcase defined.
Source code: if {![regexp {^[0-9a-f]{64}$} $handle]} { error "invalid result handle" } if {![string is entier -strict $cursor] || $cursor < 0 || ![string is integer -strict $limit] || $limit < 1 || $limit > 100} { error "expected a nonnegative cursor and a limit between 1 and 100" } ns_mutex lock ${:mutex} try { set key ${:cacheKey}:search set query {} if {[nsv_exists ${:store} $key]} { set meta [nsv_get ${:store} $key] dict for {q candidate} [dict get $meta queries] { if {[dict exists $candidate resultHandle] && [dict get $candidate resultHandle] eq $handle} { set query $candidate break } } } if {$query eq ""} { return -code error -errorcode {NSMCP RESULT UNKNOWN} "unknown or expired result handle" } # Result handles created before a live reload have no cap flag. set query [dict merge {limitReached false} $query] file stat ${:path} current set probe [open ${:path} rb] try { set prefix [read $probe [string length [dict get $meta prefix]]] } finally { close $probe } if {[list $current(dev) $current(ino)] ne [dict get $meta identity] || $current(size) < [dict get $meta observedSize] || $prefix ne [dict get $meta prefix]} { error "result handle expired after log rotation; repeat the search" } set end [dict get $query fileBytes] if {$cursor > $end} { error "cursor is beyond the published results" } set f [open [dict get $query resultFile] rb] try { if {$cursor > 0} { seek $f [expr {$cursor-1}] if {[read $f 1] ne "\n"} { error "cursor must be a record boundary" } } seek $f $cursor set records {} set bytes 0 while {[tell $f] < $end && [llength $records] < $limit} { set start [tell $f] set line {} while {1} { set position [tell $f] set chunk [read $f [expr {min(65536,$end-$position,2097153-[string length $line])}]] set newline [string first \n $chunk] if {$newline >= 0} { append line [string range $chunk 0 [expr {$newline-1}]] seek $f [expr {$position+$newline+1}] break } append line $chunk if {[string length $line] >= 2097153} { error "cached record exceeds the page byte limit" } if {$chunk eq "" || [tell $f] >= $end} { error "incomplete result cache" } } set length [expr {[tell $f]-$start}] if {$length > 2097152} { error "cached record exceeds the page byte limit" } if {$bytes+$length > 2097152} { seek $f $start break } incr bytes $length lappend records [ns_json parse [encoding convertfrom utf-8 $line]] } set next [tell $f] } finally { close $f } set more [expr {$next < $end}] return [dict create resultHandle $handle records $records nextCursor [expr {$more ? $next : ""}] more $more resultCount [dict get $query resultCount] scanIncomplete [dict get $query scanIncomplete] pending [dict get $query pending] cacheFull [dict get $query cacheFull] limitReached [dict get $query limitReached] generation [dict get $meta generation]] } finally { ns_mutex unlock ${:mutex} }XQL Not present: Generic, PostgreSQL, Oracle
![[i]](/resources/acs-subsite/ZoomIn16.gif)