1414import org .opensearch .core .xcontent .XContentBuilder ;
1515
1616import java .io .IOException ;
17+ import java .util .ArrayList ;
1718import java .util .HashMap ;
1819import java .util .List ;
1920import java .util .Map ;
2021import java .util .concurrent .ConcurrentHashMap ;
2122import java .util .concurrent .ConcurrentMap ;
2223
2324/**
24- * A CacheStats implementation for caches that aggregate over a single dimension.
25+ * A CacheStats implementation for caches that aggregate over a single dimension, as well as holding a tier dimension .
2526 * For example, caches in the IndicesRequestCache only aggregate over ShardId value.
2627 */
2728public class SingleDimensionCacheStats implements CacheStats {
@@ -41,8 +42,10 @@ public class SingleDimensionCacheStats implements CacheStats {
4142
4243 // The allowed dimension name. This stats only allows a single dimension name
4344 private final String allowedDimensionName ;
45+ // The value of the tier dimension for entries in this Stats object.
46+ private final String tierDimensionValue ;
4447
45- public SingleDimensionCacheStats (String allowedDimensionName ) {
48+ public SingleDimensionCacheStats (String allowedDimensionName , String tierDimensionValue ) {
4649 this .hitsMap = new ConcurrentHashMap <>();
4750 this .missesMap = new ConcurrentHashMap <>();
4851 this .evictionsMap = new ConcurrentHashMap <>();
@@ -56,6 +59,7 @@ public SingleDimensionCacheStats(String allowedDimensionName) {
5659 this .totalEntries = new CounterMetric ();
5760
5861 this .allowedDimensionName = allowedDimensionName ;
62+ this .tierDimensionValue = tierDimensionValue ;
5963 }
6064
6165 public SingleDimensionCacheStats (StreamInput in ) throws IOException {
@@ -77,6 +81,7 @@ public SingleDimensionCacheStats(StreamInput in) throws IOException {
7781 totalEntries .inc (in .readVLong ());
7882
7983 this .allowedDimensionName = in .readString ();
84+ this .tierDimensionValue = in .readString ();
8085 }
8186
8287 @ Override
@@ -104,7 +109,34 @@ public long getTotalEntries() {
104109 return this .totalEntries .count ();
105110 }
106111
107- private long internalGetByDimension (List <CacheStatsDimension > dimensions , Map <String , CounterMetric > metricsMap ) {
112+ private long internalGetByDimension (List <CacheStatsDimension > dimensions , Map <String , CounterMetric > metricsMap , CounterMetric totalMetric ) {
113+ CacheStatsDimension tierDimension = getTierDimensionIfPresent (dimensions );
114+ if (tierDimension != null ) {
115+ // This get request includes a tier dimension. Return values only if the tier dimension value
116+ // matches the one for this stats object, otherwise return 0
117+ assert dimensions .size () == 1 || dimensions .size () == 2 ; // There can be at most one non-tier dimension value
118+ if (tierDimension .dimensionValue .equals (tierDimensionValue )) {
119+ // The list passed in may not be mutable; create a mutable copy to remove the tier dimension
120+ ArrayList <CacheStatsDimension > modifiedDimensions = new ArrayList <>(dimensions );
121+ modifiedDimensions .remove (tierDimension );
122+
123+ if (modifiedDimensions .size () == 1 ){
124+ return internalGetHelper (modifiedDimensions , metricsMap );
125+ } else {
126+ return totalMetric .count ();
127+ }
128+
129+ } else {
130+ // Return 0 for incorrect tier value
131+ return 0 ;
132+ }
133+ } else {
134+ // This get request doesn't include a tier dimension. Return the appropriate values.
135+ return internalGetHelper (dimensions , metricsMap );
136+ }
137+ }
138+
139+ private long internalGetHelper (List <CacheStatsDimension > dimensions , Map <String , CounterMetric > metricsMap ) {
108140 assert dimensions .size () == 1 ;
109141 CounterMetric counter = metricsMap .get (dimensions .get (0 ).dimensionValue );
110142 if (counter == null ) {
@@ -113,29 +145,41 @@ private long internalGetByDimension(List<CacheStatsDimension> dimensions, Map<St
113145 return counter .count ();
114146 }
115147
148+ /**
149+ * Returns the dimension that represents a tier value, if one is present. Otherwise return null.
150+ */
151+ private CacheStatsDimension getTierDimensionIfPresent (List <CacheStatsDimension > dimensions ) {
152+ for (CacheStatsDimension dim : dimensions ) {
153+ if (dim .dimensionName .equals (CacheStatsDimension .TIER_DIMENSION_NAME )) {
154+ return dim ;
155+ }
156+ }
157+ return null ;
158+ }
159+
116160 @ Override
117161 public long getHitsByDimensions (List <CacheStatsDimension > dimensions ) {
118- return internalGetByDimension (dimensions , hitsMap );
162+ return internalGetByDimension (dimensions , hitsMap , totalHits );
119163 }
120164
121165 @ Override
122166 public long getMissesByDimensions (List <CacheStatsDimension > dimensions ) {
123- return internalGetByDimension (dimensions , missesMap );
167+ return internalGetByDimension (dimensions , missesMap , totalMisses );
124168 }
125169
126170 @ Override
127171 public long getEvictionsByDimensions (List <CacheStatsDimension > dimensions ) {
128- return internalGetByDimension (dimensions , evictionsMap );
172+ return internalGetByDimension (dimensions , evictionsMap , totalEvictions );
129173 }
130174
131175 @ Override
132176 public long getMemorySizeByDimensions (List <CacheStatsDimension > dimensions ) {
133- return internalGetByDimension (dimensions , memorySizeMap );
177+ return internalGetByDimension (dimensions , memorySizeMap , totalMemorySize );
134178 }
135179
136180 @ Override
137181 public long getEntriesByDimensions (List <CacheStatsDimension > dimensions ) {
138- return internalGetByDimension (dimensions , entriesMap );
182+ return internalGetByDimension (dimensions , entriesMap , totalEntries );
139183 }
140184
141185 private boolean checkDimensionList (List <CacheStatsDimension > dimensions ) {
@@ -199,6 +243,7 @@ public void writeTo(StreamOutput out) throws IOException {
199243 out .writeVLong (totalEntries .count ());
200244
201245 out .writeString (allowedDimensionName );
246+ out .writeString (tierDimensionValue );
202247 }
203248
204249 public String getAllowedDimensionName () {
0 commit comments