99
1010package org .elasticsearch .cluster .metadata ;
1111
12+ import org .elasticsearch .TransportVersions ;
1213import org .elasticsearch .common .io .stream .StreamInput ;
1314import org .elasticsearch .common .io .stream .StreamOutput ;
1415import org .elasticsearch .common .io .stream .Writeable ;
16+ import org .elasticsearch .core .Nullable ;
1517import org .elasticsearch .xcontent .ConstructingObjectParser ;
1618import org .elasticsearch .xcontent .ParseField ;
1719import org .elasticsearch .xcontent .ToXContentFragment ;
2729public class IndexWriteLoad implements Writeable , ToXContentFragment {
2830 public static final ParseField SHARDS_WRITE_LOAD_FIELD = new ParseField ("loads" );
2931 public static final ParseField SHARDS_UPTIME_IN_MILLIS = new ParseField ("uptimes" );
32+ public static final ParseField SHARDS_RECENT_WRITE_LOAD_FIELD = new ParseField ("recent_loads" );
3033 private static final Double UNKNOWN_LOAD = -1.0 ;
3134 private static final long UNKNOWN_UPTIME = -1 ;
3235
3336 @ SuppressWarnings ("unchecked" )
3437 private static final ConstructingObjectParser <IndexWriteLoad , Void > PARSER = new ConstructingObjectParser <>(
3538 "index_write_load_parser" ,
3639 false ,
37- (args , unused ) -> IndexWriteLoad .create ((List <Double >) args [0 ], (List <Long >) args [1 ])
40+ (args , unused ) -> IndexWriteLoad .create ((List <Double >) args [0 ], (List <Long >) args [1 ], ( List < Double >) args [ 2 ] )
3841 );
3942
4043 static {
4144 PARSER .declareDoubleArray (ConstructingObjectParser .constructorArg (), SHARDS_WRITE_LOAD_FIELD );
4245 PARSER .declareLongArray (ConstructingObjectParser .constructorArg (), SHARDS_UPTIME_IN_MILLIS );
46+ // The recent write load field is optional so that we can parse XContent built by older versions which did not include it:
47+ PARSER .declareDoubleArray (ConstructingObjectParser .optionalConstructorArg (), SHARDS_RECENT_WRITE_LOAD_FIELD );
4348 }
4449
45- public static IndexWriteLoad create (List <Double > shardsWriteLoad , List <Long > shardsUptimeInMillis ) {
50+ private static IndexWriteLoad create (
51+ List <Double > shardsWriteLoad ,
52+ List <Long > shardsUptimeInMillis ,
53+ @ Nullable List <Double > shardsRecentWriteLoad
54+ ) {
4655 if (shardsWriteLoad .size () != shardsUptimeInMillis .size ()) {
47- assert false ;
56+ assert false : "IndexWriteLoad.create() was called with non-matched lengths for shardWriteLoad and shardUptimeInMillis" ;
4857 throw new IllegalArgumentException (
4958 "The same number of shard write loads and shard uptimes should be provided, but "
5059 + shardsWriteLoad
@@ -55,39 +64,70 @@ public static IndexWriteLoad create(List<Double> shardsWriteLoad, List<Long> sha
5564 }
5665
5766 if (shardsWriteLoad .isEmpty ()) {
58- assert false ;
67+ assert false : "IndexWriteLoad.create() was called with empty shardsRecentWriteLoad" ;
68+ ;
5969 throw new IllegalArgumentException ("At least one shard write load and uptime should be provided, but none was provided" );
6070 }
6171
72+ if (shardsRecentWriteLoad != null && shardsRecentWriteLoad .size () != shardsUptimeInMillis .size ()) {
73+ assert false : "IndexWriteLoad.create() was called with non-matched lengths for shardsRecentWriteLoad and shardUptimeInMillis" ;
74+ throw new IllegalArgumentException (
75+ "The same number of shard write loads and shard uptimes should be provided, but "
76+ + shardsWriteLoad
77+ + " "
78+ + shardsUptimeInMillis
79+ + " were provided"
80+ );
81+ }
82+
6283 return new IndexWriteLoad (
6384 shardsWriteLoad .stream ().mapToDouble (shardLoad -> shardLoad ).toArray (),
64- shardsUptimeInMillis .stream ().mapToLong (shardUptime -> shardUptime ).toArray ()
85+ shardsUptimeInMillis .stream ().mapToLong (shardUptime -> shardUptime ).toArray (),
86+ shardsRecentWriteLoad != null ? shardsRecentWriteLoad .stream ().mapToDouble (shardLoad -> shardLoad ).toArray () : null
6587 );
6688 }
6789
6890 private final double [] shardWriteLoad ;
6991 private final long [] shardUptimeInMillis ;
92+ private final double [] shardRecentWriteLoad ;
7093
71- private IndexWriteLoad (double [] shardWriteLoad , long [] shardUptimeInMillis ) {
72- assert shardWriteLoad .length == shardUptimeInMillis .length ;
94+ private IndexWriteLoad (double [] shardWriteLoad , long [] shardUptimeInMillis , @ Nullable double [] shardRecentWriteLoad ) {
95+ assert shardWriteLoad .length == shardUptimeInMillis .length
96+ : "IndexWriteLoad constructor was called with non-matched lengths for shardWriteLoad and shardUptimeInMillis" ;
7397 this .shardWriteLoad = shardWriteLoad ;
7498 this .shardUptimeInMillis = shardUptimeInMillis ;
99+ if (shardRecentWriteLoad != null ) {
100+ assert shardRecentWriteLoad .length == shardUptimeInMillis .length
101+ : "IndexWriteLoad constructor was called with non-matched lengths for shardRecentWriteLoad and shardUptimeInMillis" ;
102+ this .shardRecentWriteLoad = shardRecentWriteLoad ;
103+ } else {
104+ this .shardRecentWriteLoad = new double [shardUptimeInMillis .length ];
105+ Arrays .fill (this .shardRecentWriteLoad , UNKNOWN_LOAD );
106+ }
75107 }
76108
77109 public IndexWriteLoad (StreamInput in ) throws IOException {
78- this (in .readDoubleArray (), in .readLongArray ());
110+ this (
111+ in .readDoubleArray (),
112+ in .readLongArray (),
113+ in .getTransportVersion ().onOrAfter (TransportVersions .INDEX_METADATA_INCLUDES_RECENT_WRITE_LOAD ) ? in .readDoubleArray () : null
114+ );
79115 }
80116
81117 @ Override
82118 public void writeTo (StreamOutput out ) throws IOException {
83119 out .writeDoubleArray (shardWriteLoad );
84120 out .writeLongArray (shardUptimeInMillis );
121+ if (out .getTransportVersion ().onOrAfter (TransportVersions .INDEX_METADATA_INCLUDES_RECENT_WRITE_LOAD )) {
122+ out .writeDoubleArray (shardRecentWriteLoad );
123+ }
85124 }
86125
87126 @ Override
88127 public XContentBuilder toXContent (XContentBuilder builder , Params params ) throws IOException {
89128 builder .field (SHARDS_WRITE_LOAD_FIELD .getPreferredName (), shardWriteLoad );
90129 builder .field (SHARDS_UPTIME_IN_MILLIS .getPreferredName (), shardUptimeInMillis );
130+ builder .field (SHARDS_RECENT_WRITE_LOAD_FIELD .getPreferredName (), shardRecentWriteLoad );
91131 return builder ;
92132 }
93133
@@ -102,14 +142,20 @@ public OptionalDouble getWriteLoadForShard(int shardId) {
102142 return load != UNKNOWN_LOAD ? OptionalDouble .of (load ) : OptionalDouble .empty ();
103143 }
104144
145+ public OptionalDouble getRecentWriteLoadForShard (int shardId ) {
146+ assertShardInBounds (shardId );
147+
148+ double load = shardRecentWriteLoad [shardId ];
149+ return load != UNKNOWN_LOAD ? OptionalDouble .of (load ) : OptionalDouble .empty ();
150+ }
151+
105152 public OptionalLong getUptimeInMillisForShard (int shardId ) {
106153 assertShardInBounds (shardId );
107154
108155 long uptime = shardUptimeInMillis [shardId ];
109156 return uptime != UNKNOWN_UPTIME ? OptionalLong .of (uptime ) : OptionalLong .empty ();
110157 }
111158
112- // Visible for testing
113159 public int numberOfShards () {
114160 return shardWriteLoad .length ;
115161 }
@@ -124,13 +170,16 @@ public boolean equals(Object o) {
124170 if (this == o ) return true ;
125171 if (o == null || getClass () != o .getClass ()) return false ;
126172 IndexWriteLoad that = (IndexWriteLoad ) o ;
127- return Arrays .equals (shardWriteLoad , that .shardWriteLoad ) && Arrays .equals (shardUptimeInMillis , that .shardUptimeInMillis );
173+ return Arrays .equals (shardWriteLoad , that .shardWriteLoad )
174+ && Arrays .equals (shardUptimeInMillis , that .shardUptimeInMillis )
175+ && Arrays .equals (shardRecentWriteLoad , that .shardRecentWriteLoad );
128176 }
129177
130178 @ Override
131179 public int hashCode () {
132180 int result = Arrays .hashCode (shardWriteLoad );
133181 result = 31 * result + Arrays .hashCode (shardUptimeInMillis );
182+ result = 31 * result + Arrays .hashCode (shardRecentWriteLoad );
134183 return result ;
135184 }
136185
@@ -140,29 +189,33 @@ public static Builder builder(int numShards) {
140189 }
141190
142191 public static class Builder {
143- final double [] shardWriteLoad ;
144- final long [] uptimeInMillis ;
192+ private final double [] shardWriteLoad ;
193+ private final long [] uptimeInMillis ;
194+ private final double [] shardRecentWriteLoad ;
145195
146196 private Builder (int numShards ) {
147197 this .shardWriteLoad = new double [numShards ];
148198 this .uptimeInMillis = new long [numShards ];
199+ this .shardRecentWriteLoad = new double [numShards ];
149200 Arrays .fill (shardWriteLoad , UNKNOWN_LOAD );
150201 Arrays .fill (uptimeInMillis , UNKNOWN_UPTIME );
202+ Arrays .fill (shardRecentWriteLoad , UNKNOWN_LOAD );
151203 }
152204
153- public Builder withShardWriteLoad (int shardId , double load , long uptimeInMillis ) {
205+ public Builder withShardWriteLoad (int shardId , double load , double recentLoad , long uptimeInMillis ) {
154206 if (shardId >= this .shardWriteLoad .length ) {
155207 throw new IllegalArgumentException ();
156208 }
157209
158210 this .shardWriteLoad [shardId ] = load ;
159211 this .uptimeInMillis [shardId ] = uptimeInMillis ;
212+ this .shardRecentWriteLoad [shardId ] = recentLoad ;
160213
161214 return this ;
162215 }
163216
164217 public IndexWriteLoad build () {
165- return new IndexWriteLoad (shardWriteLoad , uptimeInMillis );
218+ return new IndexWriteLoad (shardWriteLoad , uptimeInMillis , shardRecentWriteLoad );
166219 }
167220 }
168221}
0 commit comments