@@ -102,63 +102,70 @@ private static QueryCacheStats toQueryCacheStatsSafe(@Nullable Stats stats) {
102102 return stats == null ? new QueryCacheStats () : stats .toQueryCacheStats ();
103103 }
104104
105- /** Get usage statistics for the given shard. */
106- public QueryCacheStats getStats (ShardId shard , long precomputedSharedRamBytesUsed ) {
107- final QueryCacheStats queryCacheStats = toQueryCacheStatsSafe (shardStats .get (shard ));
108- queryCacheStats .addRamBytesUsed (precomputedSharedRamBytesUsed );
109- return queryCacheStats ;
110- }
111-
112- @ Override
113- public Weight doCache (Weight weight , QueryCachingPolicy policy ) {
114- while (weight instanceof CachingWeightWrapper ) {
115- weight = ((CachingWeightWrapper ) weight ).in ;
116- }
117- final Weight in = cache .doCache (weight , policy );
118- // We wrap the weight to track the readers it sees and map them with
119- // the shards they belong to
120- return new CachingWeightWrapper (in );
121- }
122-
123105 public static CacheTotals getCacheTotalsForAllShards (IndicesService indicesService ) {
124106 IndicesQueryCache queryCache = indicesService .getIndicesQueryCache ();
125107 boolean hasQueryCache = queryCache != null ;
126108 long totalSize = 0L ;
127109 int shardCount = 0 ;
128- boolean anyNonZero = false ;
129110 for (final IndexService indexService : indicesService ) {
130111 for (final IndexShard indexShard : indexService ) {
131112 long cacheSize = hasQueryCache ? queryCache .getCacheSizeForShard (indexShard .shardId ()) : 0L ;
132113 shardCount ++;
133114 if (cacheSize > 0L ) {
134- anyNonZero = true ;
135115 totalSize += cacheSize ;
136116 }
137117 }
138118 }
139119 long sharedRamBytesUsed = hasQueryCache ? queryCache .getSharedRamBytesUsed () : 0L ;
140- return new CacheTotals (totalSize , shardCount , anyNonZero , sharedRamBytesUsed );
120+ return new CacheTotals (totalSize , shardCount , sharedRamBytesUsed );
141121 }
142122
143- public static long getSharedRamSize (IndicesQueryCache queryCache , IndexShard indexShard , CacheTotals cacheTotals ) {
123+ public static long getSharedRamSizeForShard (IndicesQueryCache queryCache , IndexShard indexShard , CacheTotals cacheTotals ) {
144124 long sharedRamBytesUsed = cacheTotals .sharedRamBytesUsed ();
145- long totalSize = cacheTotals .totalSize ();
146- boolean anyNonZero = cacheTotals .anyNonZero ();
125+ if (sharedRamBytesUsed == 0L ) {
126+ return 0L ;
127+ }
128+
147129 int shardCount = cacheTotals .shardCount ();
148- ShardId shardId = indexShard .shardId ();
149- long cacheSize = queryCache != null ? queryCache .getCacheSizeForShard (shardId ) : 0L ;
150- long sharedRam = 0L ;
151- if (sharedRamBytesUsed != 0L ) {
152- if (anyNonZero == false ) {
153- sharedRam = Math .round ((double ) sharedRamBytesUsed / shardCount );
154- } else if (totalSize != 0 ) {
155- sharedRam = Math .round ((double ) sharedRamBytesUsed * cacheSize / totalSize );
156- }
130+ if (shardCount == 0 ) {
131+ // Sometimes it's not possible to do this when there are no shard entries at all, which can happen as the shared ram usage can
132+ // extend beyond the closing of all shards.
133+ return 0L ;
157134 }
158- return sharedRam ;
135+
136+ long totalSize = cacheTotals .totalSize ();
137+ long cacheSize = queryCache != null ? queryCache .getCacheSizeForShard (indexShard .shardId ()) : 0L ;
138+ final long additionalRamBytesUsed ;
139+ if (totalSize == 0 ) {
140+ // all shards have zero cache footprint, so we apportion the size of the shared bytes equally across all shards
141+ additionalRamBytesUsed = Math .round ((double ) sharedRamBytesUsed / shardCount );
142+ } else {
143+ // some shards have nonzero cache footprint, so we apportion the size of the shared bytes proportionally to cache footprint
144+ additionalRamBytesUsed = Math .round ((double ) sharedRamBytesUsed * cacheSize / totalSize );
145+ }
146+ assert additionalRamBytesUsed >= 0L : additionalRamBytesUsed ;
147+ return additionalRamBytesUsed ;
148+ }
149+
150+ public record CacheTotals (long totalSize , int shardCount , long sharedRamBytesUsed ) {}
151+
152+ /** Get usage statistics for the given shard. */
153+ public QueryCacheStats getStats (ShardId shard , long precomputedSharedRamBytesUsed ) {
154+ final QueryCacheStats queryCacheStats = toQueryCacheStatsSafe (shardStats .get (shard ));
155+ queryCacheStats .addRamBytesUsed (precomputedSharedRamBytesUsed );
156+ return queryCacheStats ;
159157 }
160158
161- public record CacheTotals (long totalSize , int shardCount , boolean anyNonZero , long sharedRamBytesUsed ) {}
159+ @ Override
160+ public Weight doCache (Weight weight , QueryCachingPolicy policy ) {
161+ while (weight instanceof CachingWeightWrapper ) {
162+ weight = ((CachingWeightWrapper ) weight ).in ;
163+ }
164+ final Weight in = cache .doCache (weight , policy );
165+ // We wrap the weight to track the readers it sees and map them with
166+ // the shards they belong to
167+ return new CachingWeightWrapper (in );
168+ }
162169
163170 private class CachingWeightWrapper extends Weight {
164171
0 commit comments