99package org .elasticsearch .action .fieldcaps ;
1010
1111import org .elasticsearch .Version ;
12- import org .elasticsearch .action .ActionResponse ;
1312import org .elasticsearch .common .io .stream .StreamInput ;
1413import org .elasticsearch .common .io .stream .StreamOutput ;
1514import org .elasticsearch .common .io .stream .Writeable ;
15+ import org .elasticsearch .core .Nullable ;
1616
1717import java .io .IOException ;
18+ import java .util .List ;
1819import java .util .Map ;
1920import java .util .Objects ;
21+ import java .util .function .Predicate ;
22+ import java .util .stream .Collectors ;
23+ import java .util .stream .Stream ;
24+
25+ final class FieldCapabilitiesIndexResponse implements Writeable {
26+ private static final Version MAPPING_HASH_VERSION = Version .V_8_2_0 ;
2027
21- public class FieldCapabilitiesIndexResponse extends ActionResponse implements Writeable {
2228 private final String indexName ;
29+ @ Nullable
30+ private final String indexMappingHash ;
2331 private final Map <String , IndexFieldCapabilities > responseMap ;
2432 private final boolean canMatch ;
2533 private final transient Version originVersion ;
2634
27- FieldCapabilitiesIndexResponse (String indexName , Map <String , IndexFieldCapabilities > responseMap , boolean canMatch ) {
35+ FieldCapabilitiesIndexResponse (
36+ String indexName ,
37+ @ Nullable String indexMappingHash ,
38+ Map <String , IndexFieldCapabilities > responseMap ,
39+ boolean canMatch
40+ ) {
2841 this .indexName = indexName ;
42+ this .indexMappingHash = indexMappingHash ;
2943 this .responseMap = responseMap ;
3044 this .canMatch = canMatch ;
3145 this .originVersion = Version .CURRENT ;
3246 }
3347
3448 FieldCapabilitiesIndexResponse (StreamInput in ) throws IOException {
35- super (in );
3649 this .indexName = in .readString ();
3750 this .responseMap = in .readMap (StreamInput ::readString , IndexFieldCapabilities ::new );
3851 this .canMatch = in .readBoolean ();
3952 this .originVersion = in .getVersion ();
53+ if (in .getVersion ().onOrAfter (MAPPING_HASH_VERSION )) {
54+ this .indexMappingHash = in .readOptionalString ();
55+ } else {
56+ this .indexMappingHash = null ;
57+ }
58+ }
59+
60+ @ Override
61+ public void writeTo (StreamOutput out ) throws IOException {
62+ out .writeString (indexName );
63+ out .writeMap (responseMap , StreamOutput ::writeString , (valueOut , fc ) -> fc .writeTo (valueOut ));
64+ out .writeBoolean (canMatch );
65+ if (out .getVersion ().onOrAfter (MAPPING_HASH_VERSION )) {
66+ out .writeOptionalString (indexMappingHash );
67+ }
68+ }
69+
70+ private record GroupByMappingHash (List <String > indices , String indexMappingHash , Map <String , IndexFieldCapabilities > responseMap )
71+ implements
72+ Writeable {
73+ GroupByMappingHash (StreamInput in ) throws IOException {
74+ this (in .readStringList (), in .readString (), in .readMap (StreamInput ::readString , IndexFieldCapabilities ::new ));
75+ }
76+
77+ @ Override
78+ public void writeTo (StreamOutput out ) throws IOException {
79+ out .writeStringCollection (indices );
80+ out .writeString (indexMappingHash );
81+ out .writeMap (responseMap , StreamOutput ::writeString , (valueOut , fc ) -> fc .writeTo (valueOut ));
82+ }
83+
84+ List <FieldCapabilitiesIndexResponse > getResponses () {
85+ return indices .stream ().map (index -> new FieldCapabilitiesIndexResponse (index , indexMappingHash , responseMap , true )).toList ();
86+ }
87+ }
88+
89+ static List <FieldCapabilitiesIndexResponse > readList (StreamInput input ) throws IOException {
90+ if (input .getVersion ().before (MAPPING_HASH_VERSION )) {
91+ return input .readList (FieldCapabilitiesIndexResponse ::new );
92+ }
93+ final List <FieldCapabilitiesIndexResponse > ungroupedList = input .readList (FieldCapabilitiesIndexResponse ::new );
94+ final List <GroupByMappingHash > groups = input .readList (GroupByMappingHash ::new );
95+ return Stream .concat (ungroupedList .stream (), groups .stream ().flatMap (g -> g .getResponses ().stream ())).toList ();
96+ }
97+
98+ static void writeList (StreamOutput output , List <FieldCapabilitiesIndexResponse > responses ) throws IOException {
99+ if (output .getVersion ().before (MAPPING_HASH_VERSION )) {
100+ output .writeCollection (responses );
101+ return ;
102+ }
103+ final Predicate <FieldCapabilitiesIndexResponse > canGroup = r -> r .canMatch && r .indexMappingHash != null ;
104+ final List <FieldCapabilitiesIndexResponse > ungroupedResponses = responses .stream ().filter (r -> canGroup .test (r ) == false ).toList ();
105+ final List <GroupByMappingHash > groupedResponses = responses .stream ()
106+ .filter (canGroup )
107+ .collect (Collectors .groupingBy (r -> r .indexMappingHash ))
108+ .values ()
109+ .stream ()
110+ .map (rs -> {
111+ final String indexMappingHash = rs .get (0 ).indexMappingHash ;
112+ final Map <String , IndexFieldCapabilities > responseMap = rs .get (0 ).responseMap ;
113+ final List <String > indices = rs .stream ().map (r -> r .indexName ).toList ();
114+ return new GroupByMappingHash (indices , indexMappingHash , responseMap );
115+ })
116+ .toList ();
117+ output .writeList (ungroupedResponses );
118+ output .writeList (groupedResponses );
40119 }
41120
42121 /**
@@ -46,6 +125,14 @@ public String getIndexName() {
46125 return indexName ;
47126 }
48127
128+ /**
129+ * Returns the index mapping hash associated with this index if exists
130+ */
131+ @ Nullable
132+ public String getIndexMappingHash () {
133+ return indexMappingHash ;
134+ }
135+
49136 public boolean canMatch () {
50137 return canMatch ;
51138 }
@@ -69,23 +156,19 @@ Version getOriginVersion() {
69156 return originVersion ;
70157 }
71158
72- @ Override
73- public void writeTo (StreamOutput out ) throws IOException {
74- out .writeString (indexName );
75- out .writeMap (responseMap , StreamOutput ::writeString , (valueOut , fc ) -> fc .writeTo (valueOut ));
76- out .writeBoolean (canMatch );
77- }
78-
79159 @ Override
80160 public boolean equals (Object o ) {
81161 if (this == o ) return true ;
82162 if (o == null || getClass () != o .getClass ()) return false ;
83163 FieldCapabilitiesIndexResponse that = (FieldCapabilitiesIndexResponse ) o ;
84- return canMatch == that .canMatch && Objects .equals (indexName , that .indexName ) && Objects .equals (responseMap , that .responseMap );
164+ return canMatch == that .canMatch
165+ && Objects .equals (indexName , that .indexName )
166+ && Objects .equals (indexMappingHash , that .indexMappingHash )
167+ && Objects .equals (responseMap , that .responseMap );
85168 }
86169
87170 @ Override
88171 public int hashCode () {
89- return Objects .hash (indexName , responseMap , canMatch );
172+ return Objects .hash (indexName , indexMappingHash , responseMap , canMatch );
90173 }
91174}
0 commit comments