167167import java .util .ArrayList ;
168168import java .util .Arrays ;
169169import java .util .Collection ;
170+ import java .util .Collections ;
170171import java .util .EnumMap ;
171172import java .util .HashMap ;
172173import java .util .Iterator ;
@@ -519,33 +520,81 @@ static Map<Index, CommonStats> statsByIndex(final IndicesService indicesService,
519520 }
520521
521522 static Map <Index , List <IndexShardStats >> statsByShard (final IndicesService indicesService , final CommonStatsFlags flags ) {
522- final Map <Index , List <IndexShardStats >> statsByShard = new HashMap <>();
523-
523+ IndicesQueryCache queryCache = indicesService .getIndicesQueryCache ();
524+ // First pass: gather all shards, cache sizes, and compute totals
525+ class ShardCacheInfo {
526+ final IndexService indexService ;
527+ final IndexShard indexShard ;
528+ final org .elasticsearch .index .shard .ShardId shardId ;
529+ final long cacheSize ;
530+
531+ ShardCacheInfo (IndexService is , IndexShard shard , org .elasticsearch .index .shard .ShardId id , long size ) {
532+ this .indexService = is ;
533+ this .indexShard = shard ;
534+ this .shardId = id ;
535+ this .cacheSize = size ;
536+ }
537+ }
538+ List <ShardCacheInfo > shardInfos = new ArrayList <>();
539+ long totalSize = 0L ;
540+ int shardCount = 0 ;
541+ boolean anyNonZero = false ;
524542 for (final IndexService indexService : indicesService ) {
525543 for (final IndexShard indexShard : indexService ) {
526- try {
527- final IndexShardStats indexShardStats = indicesService .indexShardStats (indicesService , indexShard , flags );
528-
529- if (indexShardStats == null ) {
530- continue ;
531- }
532-
533- if (statsByShard .containsKey (indexService .index ()) == false ) {
534- statsByShard .put (indexService .index (), arrayAsArrayList (indexShardStats ));
535- } else {
536- statsByShard .get (indexService .index ()).add (indexShardStats );
537- }
538- } catch (IllegalIndexShardStateException | AlreadyClosedException e ) {
539- // we can safely ignore illegal state on ones that are closing for example
540- logger .trace (() -> format ("%s ignoring shard stats" , indexShard .shardId ()), e );
544+ org .elasticsearch .index .shard .ShardId shardId = indexShard .shardId ();
545+ long cacheSize = queryCache .getCacheSizeForShard (shardId );
546+ shardInfos .add (new ShardCacheInfo (indexService , indexShard , shardId , cacheSize ));
547+ shardCount ++;
548+ if (cacheSize > 0L ) {
549+ anyNonZero = true ;
550+ totalSize += cacheSize ;
541551 }
542552 }
543553 }
544-
554+ long sharedRamBytesUsed = queryCache .getSharedRamBytesUsed ();
555+ final Map <Index , List <IndexShardStats >> statsByShard = new HashMap <>();
556+ // Second pass: build stats, compute shared RAM on the fly
557+ for (ShardCacheInfo info : shardInfos ) {
558+ long sharedRam = 0L ;
559+ if (sharedRamBytesUsed != 0L ) {
560+ if (anyNonZero == false ) {
561+ sharedRam = Math .round ((double ) sharedRamBytesUsed / shardCount );
562+ } else if (totalSize != 0 ) {
563+ sharedRam = Math .round ((double ) sharedRamBytesUsed * info .cacheSize / totalSize );
564+ }
565+ }
566+ try {
567+ final IndexShardStats indexShardStats = indicesService .indexShardStats (
568+ indicesService ,
569+ info .indexShard ,
570+ flags ,
571+ Collections .singletonMap (info .shardId , sharedRam )
572+ );
573+ if (indexShardStats == null ) {
574+ continue ;
575+ }
576+ if (statsByShard .containsKey (info .indexService .index ()) == false ) {
577+ statsByShard .put (info .indexService .index (), arrayAsArrayList (indexShardStats ));
578+ } else {
579+ statsByShard .get (info .indexService .index ()).add (indexShardStats );
580+ }
581+ } catch (IllegalIndexShardStateException | AlreadyClosedException e ) {
582+ logger .trace (() -> format ("%s ignoring shard stats" , info .shardId ), e );
583+ }
584+ }
545585 return statsByShard ;
546586 }
547587
548588 IndexShardStats indexShardStats (final IndicesService indicesService , final IndexShard indexShard , final CommonStatsFlags flags ) {
589+ return indexShardStats (indicesService , indexShard , flags , null );
590+ }
591+
592+ IndexShardStats indexShardStats (
593+ final IndicesService indicesService ,
594+ final IndexShard indexShard ,
595+ final CommonStatsFlags flags ,
596+ Map <org .elasticsearch .index .shard .ShardId , Long > precomputedSharedRam
597+ ) {
549598 if (indexShard .routingEntry () == null ) {
550599 return null ;
551600 }
@@ -570,7 +619,7 @@ IndexShardStats indexShardStats(final IndicesService indicesService, final Index
570619 new ShardStats (
571620 indexShard .routingEntry (),
572621 indexShard .shardPath (),
573- CommonStats .getShardLevelStats (indicesService .getIndicesQueryCache (), indexShard , flags ),
622+ CommonStats .getShardLevelStats (indicesService .getIndicesQueryCache (), indexShard , flags , precomputedSharedRam ),
574623 commitStats ,
575624 seqNoStats ,
576625 retentionLeaseStats ,
0 commit comments