package gw.api.cache2 uses gw.api.locale.DisplayKey uses com.guidewire.pl.system.cache2.CacheStatisticsSnapshot uses com.guidewire.pl.domain.cache2.impl.CacheStatisticsRollupSnapshotImpl uses com.guidewire.pl.system.cache2.CacheStatisticsRollupSnapshotData uses com.guidewire.pl.system.cache2.CacheStatisticsRollupSnapshotDataImpl uses com.guidewire.pl.system.cache2.CentipedeCacheStatisticsRollup uses com.guidewire.pl.system.cache2.GlobalCacheImpl uses com.guidewire.pl.system.cache2.CacheContentsUtil uses com.guidewire.pl.system.dependency.PLDependencies uses gw.api.system.PLConfigParameters uses gw.util.Pair uses java.lang.Integer uses java.lang.Math uses java.util.ArrayList uses java.lang.StringBuilder uses com.guidewire.pl.web.util.WebFileUtil uses gw.util.StreamUtil uses java.util.Map uses com.guidewire.commons.util.MutableReference uses java.util.Collections uses java.util.Date uses java.util.Calendar uses java.util.HashMap final class CacheInfoPageHelper { public static final var INSTANCE : CacheInfoPageHelper = new CacheInfoPageHelper() var _timestamp : Date var _snapshots : CacheStatisticsSnapshot[] var _numAges : int var _cacheContentsRaw : HashMap>[] var _cacheContentsProcessed : ArrayList>>> var _cacheContentsAcrossAges : Pair>> = null var _lastWeekRollupSnapshot : ArrayList var _numDaysOfRollupData : int var _todayRollupSnapshot : ArrayList var _timesOfDay : Date[] private construct() { reload() _timesOfDay = new Date[CentipedeCacheStatisticsRollup.NUM_ROLLUPS_PER_DAY] var today = Calendar.getInstance() // In case this gets initialized right before midnight... for (var i in 0..|CentipedeCacheStatisticsRollup.NUM_ROLLUPS_PER_DAY) { var cal = Calendar.getInstance() var minutesSinceMidnight = (CentipedeCacheStatisticsRollup.ROLLUP_TIME_MINS * i) var hourPastMidnight = minutesSinceMidnight / 60 var minutesPastTheHour = minutesSinceMidnight - (hourPastMidnight * 60) cal.set(Calendar.YEAR, today.get(Calendar.YEAR)) cal.set(Calendar.MONTH, today.get(Calendar.MONTH)) cal.set(Calendar.DAY_OF_MONTH, today.get(Calendar.DAY_OF_MONTH)) cal.set(Calendar.HOUR_OF_DAY, hourPastMidnight) cal.set(Calendar.MINUTE, minutesPastTheHour) _timesOfDay[i] = cal.Time } } public final function reload() { _timestamp = Date.CurrentDate _snapshots = (PLDependencies.getGlobalCache() as GlobalCacheImpl).CacheStatistics _numAges = Math.min(_snapshots.length, PLConfigParameters.GlobalCacheStatsWindowMinutes.Value + 1) _cacheContentsRaw = (PLDependencies.getGlobalCache() as GlobalCacheImpl).getWhatIsInTheCache() _cacheContentsProcessed = null _lastWeekRollupSnapshot = new ArrayList(CentipedeCacheStatisticsRollup.NUM_ROLLUPS_PER_DAY) _numDaysOfRollupData = 0 var lastWeekRollup = (PLDependencies.getGlobalCache() as GlobalCacheImpl).LastRetentionPeriodRollup for (var timeOfDayIndex in 0..|CentipedeCacheStatisticsRollup.NUM_ROLLUPS_PER_DAY) { var numDays = 0 var averageSpaceRetained = 0 as long var averageNumHits = 0 as long var averageNumMisses = 0 as long var averageNumMissesBecauseEvictedWhenCacheFull = 0 as long for (var dayRollup in lastWeekRollup) { if (dayRollup != null) { if (dayRollup[timeOfDayIndex] != null) { averageSpaceRetained += dayRollup[timeOfDayIndex].AverageSpaceRetained averageNumHits += dayRollup[timeOfDayIndex].AverageNumHits averageNumMisses += dayRollup[timeOfDayIndex].AverageNumMisses averageNumMissesBecauseEvictedWhenCacheFull += dayRollup[timeOfDayIndex].AverageNumMissesWhenCacheFull numDays++ } } } if (_numDaysOfRollupData < numDays) { _numDaysOfRollupData = numDays } if (numDays > 0) { var snapshot = new CacheStatisticsRollupSnapshotDataImpl(_timesOfDay[timeOfDayIndex], averageSpaceRetained / numDays, averageNumHits / numDays, averageNumMisses / numDays, averageNumMissesBecauseEvictedWhenCacheFull / numDays) _lastWeekRollupSnapshot.add(snapshot) } } var todayRollup = (PLDependencies.getGlobalCache() as GlobalCacheImpl).TodayRollup _todayRollupSnapshot = new ArrayList(CentipedeCacheStatisticsRollup.NUM_ROLLUPS_PER_DAY) for (var timeOfDayIndex in 0..|CentipedeCacheStatisticsRollup.NUM_ROLLUPS_PER_DAY) { if (todayRollup[timeOfDayIndex] != null) { var snapshot = new CacheStatisticsRollupSnapshotDataImpl(_timesOfDay[timeOfDayIndex], todayRollup[timeOfDayIndex].AverageSpaceRetained, todayRollup[timeOfDayIndex].AverageNumHits, todayRollup[timeOfDayIndex].AverageNumMisses, todayRollup[timeOfDayIndex].AverageNumMissesWhenCacheFull) _todayRollupSnapshot.add(snapshot) } } } property get Timestamp() : Date { return _timestamp } property get Snapshots() : CacheStatisticsSnapshot[] { return _snapshots } property get NumAges() : int { return _numAges } property get LatestSnapshot() : CacheStatisticsSnapshot { return _snapshots[_snapshots.length - 1] } property get ContentsMapByAge() : ArrayList>>> { if (_cacheContentsProcessed == null) { _cacheContentsProcessed = CacheContentsUtil.filterByLargestAndPutRestInOtherBucket(_cacheContentsRaw) _cacheContentsAcrossAges = CacheContentsUtil.combinedCacheInfoInOrder(_cacheContentsProcessed) } var filteredContents = new ArrayList>>>() for (var contentsByAge in _cacheContentsProcessed) { var filteredContentsByAge = new ArrayList>() filteredContents.add(new Pair>>(contentsByAge.First, filteredContentsByAge)) for (var item in contentsByAge.Second) { if (item.Second > 0) { // PL-28099: Filter in stuff that exist for that age filteredContentsByAge.add(item) } } } return filteredContents } property get YoungestContentsMap() : Pair>> { if (ContentsMapByAge.Empty) { return new Pair>>(0, new ArrayList>()) } else { return ContentsMapByAge.get(0) } } property get CombinedContentsMap() : Pair>> { if (_cacheContentsAcrossAges == null) { return new Pair>>(-1, new ArrayList>()) } else { return _cacheContentsAcrossAges } } function getSnapshotIndex(snapshot : CacheStatisticsSnapshot) : int { for (i in 0..|_snapshots.length) { if (_snapshots[i] == snapshot) { return i } } // Shouldn't happen throw "Invalid snapshot" } function getCategoryLabel(snapshot : CacheStatisticsSnapshot) : String { var ageIndex = getAgeIndex(snapshot) return ageIndex == 0 ? DisplayKey.get("Web.InternalTools.InfoPages.CacheInfo.Now") : ageIndex as String } function getAgeIndex(snapshot : CacheStatisticsSnapshot) : int { return getSnapshotIndex(snapshot) - _numAges + 1 } function getAgeDistributionLabel(snapshot : CacheStatisticsSnapshot) : String { var age = getAgeIndex(snapshot) return age == 0 ? DisplayKey.get("Web.InternalTools.InfoPages.CacheInfo.AgeDistributionTime0") : DisplayKey.get("Web.InternalTools.InfoPages.CacheInfo.AgeDistribution", - age) } static function getCacheContentsLabel(contentsMap : Pair>>) : String { // PL-28099: Sum the count of each entity type for the given age var total = 0; for (var t in contentsMap.Second) { total += t.Second } if (contentsMap.First < 0) { return DisplayKey.get("Web.InternalTools.InfoPages.CacheInfo.WhatIsInTheCache", DisplayKey.get("Java.Select.All"), total) } return DisplayKey.get("Web.InternalTools.InfoPages.CacheInfo.WhatIsInTheCache", contentsMap.First, total) } function getNumAgesInSizeDistribution(snapshot : CacheStatisticsSnapshot) : int { return java.lang.Math.min(snapshot.SizeDistributionByAgeFromCurrentTime.length, PLConfigParameters.GlobalCacheReapingTimeMinutes.Value) } function getDataSeriesForSizeDistribution(snapshot : CacheStatisticsSnapshot) : ArrayList> { return makeDataSeriesFromIntArray(snapshot.SizeDistributionByAgeFromCurrentTime) } function makeDataSeriesFromIntArray(arr : int[]) : ArrayList> { var dataSeries = new ArrayList>(arr.length) var i = 0 for (value in arr) { dataSeries.add(new Pair(i as String, value)) i++ } return dataSeries } function download() { var output = getStatisticsAsCSV() WebFileUtil.copyStreamToClient("text/csv", DisplayKey.get("Web.InternalTools.InfoPages.CacheInfo") + ".csv", StreamUtil.getStringInputStream(output), output.length) } private function getStatisticsAsCSV() : String { // Use rough approximation of size var output = new StringBuilder(_snapshots.length * 200 + 250) appendSnapshotData(output) appendWhatIsInTheCacheData(output) output.append(getLastWeekLabel()).append("\n") output.append(CacheStatisticsRollupSnapshotImpl.getCSVHeader()) appendRollup(output, _lastWeekRollupSnapshot) output.append(DisplayKey.get("Web.InternalTools.InfoPages.CacheInfo.TodayRollup")).append("\n") output.append(CacheStatisticsRollupSnapshotImpl.getCSVHeader()) appendRollup(output, _todayRollupSnapshot) return output.toString() } private function appendSnapshotData(output : StringBuilder) { output.append(CacheStatisticsSnapshot.getCSVHeader()) var i = 0 for (snapshot in _snapshots) { output.append(snapshot.getCSVLine()) i++ } output.append("\n\n") } private function appendWhatIsInTheCacheData(output : StringBuilder) { var i = 0 output.append(DisplayKey.get("Web.InternalTools.InfoPages.CacheInfo.WhatIsInTheCacheTitle")).append("\n") for (var cacheContentsByAge in _cacheContentsRaw) { if (!cacheContentsByAge.Empty) { var contents = new ArrayList>>(cacheContentsByAge.entrySet()) output.append(DisplayKey.get("Web.InternalTools.InfoPages.CacheInfo.WhatIsInTheCache", i as String, contents.size())) output.append("\n") Collections.sort(contents, \ x, y -> { return (y as Map.Entry>).Value.get().compareTo((x as Map.Entry>).Value.get()) }) for (var data in contents) { output.append(data.Key).append(",").append(data.Value.get()).append("\n") } } i++ } output.append("\n\n") } private function appendRollup(output : StringBuilder, rollupSnapshots : ArrayList) { for (var rollupSnapshot in rollupSnapshots) { output.append(rollupSnapshot.getCSVLine()) } output.append("\n\n") } property get LastWeekRollupSnapshot() : ArrayList { return _lastWeekRollupSnapshot } property get NumDaysOfRollupData() : int { return _numDaysOfRollupData } property get TodayRollupSnapshot() : ArrayList { return _todayRollupSnapshot } function getLastWeekLabel() : String { return (NumDaysOfRollupData == 1) ? DisplayKey.get("Web.InternalTools.InfoPages.CacheInfo.Yesterday") : DisplayKey.get("Web.InternalTools.InfoPages.CacheInfo.LastWeekDays", NumDaysOfRollupData) } }