public/Message/Measure-Frequency.ps1

using module '..\..\modules\Enums.psm1'
using module '..\..\modules\Helper\DateTimeHelper.psm1'
using module '..\..\modules\Helper\StringHelper.psm1'
using module '..\..\modules\Helper\ObjectHelper.psm1'
using module '..\..\modules\Session.psd1'
using module '..\..\modules\FeedProcessor\ProcessorBase.psm1'
using module '..\..\modules\FeedProcessor\Auditlog\Message.psm1'

function Measure-Frequency{
    [CmdletBinding()]
    [Alias('msc')]
    param(
        [Parameter(ValueFromPipeline=$true, Mandatory=$true)]
        [Message] $message,
        [int] $aboveAppereances,
        [int] $bellowAppereances,
        [switch] $summary,
        [int32] $intervalBlock = 100,
        [int32] $percentageThreshold = 5
    )

    BEGIN {
        [hashtable] $frequency = @{}
        $count = 0; $previousBlock = 1
        $maxFrequency = 0; $maxKey = $null
        $processor = $null

        try {
            $maxBlocks = [int32](10000/$intervalBlock)
        }
        catch {
            $maxBlocks = 200
        }
        $threshold = @()
        for ($i=0; $i -le $maxBlocks; $i++) { $threshold += 0 }
    }
    PROCESS {
        $count++

        if ($null -eq $processor) { $processor = [ProcessorFactory]::getBySource($message.source) }
        $processor.message = $message
        $processor.ProcessMarket($message.line, [SEARCH_SCOPE]::internalId, '*', '*')

        foreach ($market in $processor.message.event.markets) {
            $key = $market.ident()
            if (-not $frequency.ContainsKey($key)){
                $frequency.Add($key, 1)
            }
            else {
                $frequency[$key] += 1
            }

            if ($frequency[$key] -gt $maxFrequency){
                $maxKey = $key
                $maxFrequency = $frequency[$key]
            }
        }
    }
    END {
        if ($frequency.Count -gt 0){
            if ($summary){

                $allFrequencies = @()
                foreach ($item in $frequency.Values){
                    $allFrequencies += $item
                    $i = ([Math]::floor($item/$intervalBlock))
                    $threshold[[Math]::min($i, $maxBlocks)] += 1
                }

                Write-Output "Summary of total $($frequency.Count) analyzed markets:"
                $percentile = [Config]::Load().percentile

                Write-Debug ('Interval block: {0}, threshold: {1}, percentile: {2}' -f @($intervalBlock, $percentageThreshold, $percentile))
                Write-Output ([StringHelper]::groupValueByBlocks($threshold, $intervalBlock, $percentageThreshold, $percentile, $false))

                $sorted = ($allFrequencies | Sort-Object )

                $printLines = [ordered]@{}
                foreach ($i in $percentile) {
                    $array = $sorted | Select-Object -First $([Math]::Floor($i * $frequency.Count))

                    $average = ($array | Measure-Object -Average).Average
                    $median = [StringHelper]::getMedian($array)

                    $line = @(("{0}th" -f ($i * 100)), $sorted[$([Math]::Floor($i * $analyzedLines - 1))], `
                        ("{0:N0}" -f $average), ("{0:N0}" -f $median))
                    $printLines.Add($i, $line)
                }

                Write-Table -title 'Percentile analysis:' -columns @('percentile', 'frequency', 'average', 'median') -values $printLines
            }
            else {
                $count=0
                $filtered = ($frequency.GetEnumerator() | `
                    Where-Object { ($aboveAppereance -eq 0 -or ($aboveAppereance -ne -0 -and $_.Value -ge $aboveAppereances)) -or
                        ($bellowAppereance -eq 0 -or ($bellowAppereance -ne 0 -and $_.Value -le $bellowAppereance)) } | `
                    Sort-Object Value -Desc )

                foreach($item in $filtered){

                    $count++
                    $temp = [Market]::reverseIdent($item.Key)

                    Write-Output ([PSCustomObject]@{PSTypeName='MarketFrequency'; marketId=$temp[0]; `
                        specifiers=$temp[1]; frequency=$item.Value})
                }

                if ($bellowAppereance -and $aboveAppereance){
                    Write-Output ("Total {0} out of {1} ({2:P1}) were processed between {3} and {4} times." `
                        -f @($count, $frequency.Count, ($count / $frequency.Count), $aboveAppereances, $bellowAppereance))
                }
                elseif ($aboveAppereance){
                    Write-Output ("Total {0} out of {1} ({2:P1}) were processed above {3} times." `
                        -f @($count, $frequency.Count, ($count / $frequency.Count), $aboveAppereances))
                }
                elseif ($bellowAppereance){
                    Write-Output ("Total {0} out of {1} ({2:P1}) were processed bellow {3} times." `
                        -f @($count, $frequency.Count, ($count / $frequency.Count), $bellowAppereance))
                }
            }
        }
        else {
            Write-Output "No lines for analysis."
        }
    }
}