7
7
8
8
package org .elasticsearch .xpack .lucene .bwc .codecs ;
9
9
10
- import org .apache .lucene .backward_codecs .lucene70 .Lucene70Codec ;
11
10
import org .apache .lucene .codecs .Codec ;
12
11
import org .apache .lucene .codecs .FieldInfosFormat ;
13
12
import org .apache .lucene .codecs .FieldsConsumer ;
18
17
import org .apache .lucene .codecs .PostingsFormat ;
19
18
import org .apache .lucene .codecs .SegmentInfoFormat ;
20
19
import org .apache .lucene .codecs .TermVectorsFormat ;
20
+ import org .apache .lucene .codecs .perfield .PerFieldPostingsFormat ;
21
21
import org .apache .lucene .index .FieldInfo ;
22
22
import org .apache .lucene .index .FieldInfos ;
23
23
import org .apache .lucene .index .Fields ;
27
27
import org .apache .lucene .index .Terms ;
28
28
import org .apache .lucene .store .Directory ;
29
29
import org .apache .lucene .store .IOContext ;
30
+ import org .apache .lucene .util .Version ;
30
31
import org .elasticsearch .xpack .lucene .bwc .codecs .lucene70 .BWCLucene70Codec ;
32
+ import org .elasticsearch .xpack .lucene .bwc .codecs .lucene80 .BWCLucene80Codec ;
33
+ import org .elasticsearch .xpack .lucene .bwc .codecs .lucene84 .BWCLucene84Codec ;
34
+ import org .elasticsearch .xpack .lucene .bwc .codecs .lucene86 .BWCLucene86Codec ;
35
+ import org .elasticsearch .xpack .lucene .bwc .codecs .lucene87 .BWCLucene87Codec ;
31
36
32
37
import java .io .IOException ;
33
38
import java .util .ArrayList ;
39
44
*/
40
45
public abstract class BWCCodec extends Codec {
41
46
47
+ private final FieldInfosFormat fieldInfosFormat ;
48
+ private final SegmentInfoFormat segmentInfosFormat ;
49
+ private final PostingsFormat postingsFormat ;
50
+
42
51
protected BWCCodec (String name ) {
43
52
super (name );
44
- }
45
53
46
- @ Override
47
- public NormsFormat normsFormat () {
48
- throw new UnsupportedOperationException ();
49
- }
54
+ this .fieldInfosFormat = new FieldInfosFormat () {
55
+ final FieldInfosFormat wrappedFormat = originalFieldInfosFormat ();
50
56
51
- @ Override
52
- public TermVectorsFormat termVectorsFormat () {
53
- throw new UnsupportedOperationException ();
54
- }
57
+ @ Override
58
+ public FieldInfos read (Directory directory , SegmentInfo segmentInfo , String segmentSuffix , IOContext iocontext )
59
+ throws IOException {
60
+ return filterFields (wrappedFormat .read (directory , segmentInfo , segmentSuffix , iocontext ));
61
+ }
55
62
56
- @ Override
57
- public KnnVectorsFormat knnVectorsFormat () {
58
- throw new UnsupportedOperationException ();
59
- }
63
+ @ Override
64
+ public void write (Directory directory , SegmentInfo segmentInfo , String segmentSuffix , FieldInfos infos , IOContext context )
65
+ throws IOException {
66
+ wrappedFormat .write (directory , segmentInfo , segmentSuffix , infos , context );
67
+ }
68
+ };
69
+
70
+ this .segmentInfosFormat = new SegmentInfoFormat () {
71
+ final SegmentInfoFormat wrappedFormat = originalSegmentInfoFormat ();
60
72
61
- protected static SegmentInfoFormat wrap (SegmentInfoFormat wrapped ) {
62
- return new SegmentInfoFormat () {
63
73
@ Override
64
74
public SegmentInfo read (Directory directory , String segmentName , byte [] segmentID , IOContext context ) throws IOException {
65
- return wrap (wrapped .read (directory , segmentName , segmentID , context ));
75
+ return wrap (wrappedFormat .read (directory , segmentName , segmentID , context ));
66
76
}
67
77
68
78
@ Override
69
79
public void write (Directory dir , SegmentInfo info , IOContext ioContext ) throws IOException {
70
- wrapped .write (dir , info , ioContext );
80
+ wrappedFormat .write (dir , info , ioContext );
71
81
}
72
82
};
73
- }
74
83
75
- protected static FieldInfosFormat wrap (FieldInfosFormat wrapped ) {
76
- return new FieldInfosFormat () {
84
+ this .postingsFormat = new PerFieldPostingsFormat () {
77
85
@ Override
78
- public FieldInfos read (Directory directory , SegmentInfo segmentInfo , String segmentSuffix , IOContext iocontext )
79
- throws IOException {
80
- return filterFields (wrapped .read (directory , segmentInfo , segmentSuffix , iocontext ));
81
- }
82
-
83
- @ Override
84
- public void write (Directory directory , SegmentInfo segmentInfo , String segmentSuffix , FieldInfos infos , IOContext context )
85
- throws IOException {
86
- wrapped .write (directory , segmentInfo , segmentSuffix , infos , context );
86
+ public PostingsFormat getPostingsFormatForField (String field ) {
87
+ throw new UnsupportedOperationException ("Old codecs can't be used for writing" );
87
88
}
88
89
};
89
90
}
90
91
92
+ @ Override
93
+ public final FieldInfosFormat fieldInfosFormat () {
94
+ return fieldInfosFormat ;
95
+ }
96
+
97
+ @ Override
98
+ public final SegmentInfoFormat segmentInfoFormat () {
99
+ return segmentInfosFormat ;
100
+ }
101
+
102
+ @ Override
103
+ public PostingsFormat postingsFormat () {
104
+ return postingsFormat ;
105
+ }
106
+
107
+ /**
108
+ * This method is not supported for archive indices and older codecs and will always throw an {@link UnsupportedOperationException}.
109
+ * This method is never called in practice, as we rewrite field infos to override the info about which features are present in
110
+ * the index. Even if norms are present, field info lies about it.
111
+ *
112
+ * @return nothing, as this method always throws an exception
113
+ * @throws UnsupportedOperationException always thrown to indicate that this method is not supported
114
+ */
115
+ @ Override
116
+ public final NormsFormat normsFormat () {
117
+ throw new UnsupportedOperationException ();
118
+ }
119
+
120
+ /**
121
+ * This method is not supported for archive indices and older codecs and will always throw an {@link UnsupportedOperationException}.
122
+ * This method is never called in practice, as we rewrite field infos to override the info about which features are present in
123
+ * the index. Even if term vectors are present, field info lies about it.
124
+ *
125
+ * @return nothing, as this method always throws an exception
126
+ * @throws UnsupportedOperationException always thrown to indicate that this method is not supported
127
+ */
128
+ @ Override
129
+ public final TermVectorsFormat termVectorsFormat () {
130
+ throw new UnsupportedOperationException ();
131
+ }
132
+
133
+ /**
134
+ * This method is not supported for archive indices and older codecs and will always throw an {@link UnsupportedOperationException}.
135
+ * The knn vectors can't be present because it is not supported yet in any of the lucene versions that we support for archive indices.
136
+ *
137
+ * @return nothing, as this method always throws an exception
138
+ * @throws UnsupportedOperationException always thrown to indicate that this method is not supported
139
+ */
140
+ @ Override
141
+ public final KnnVectorsFormat knnVectorsFormat () {
142
+ throw new UnsupportedOperationException ();
143
+ }
144
+
145
+ /**
146
+ * Returns the original {@link SegmentInfoFormat} used by this codec.
147
+ * This method should be implemented by subclasses to provide the specific
148
+ * {@link SegmentInfoFormat} that this codec is intended to use.
149
+ *
150
+ * @return the original {@link SegmentInfoFormat} used by this codec
151
+ */
152
+ protected abstract SegmentInfoFormat originalSegmentInfoFormat ();
153
+
154
+ /**
155
+ * Returns the original {@link FieldInfosFormat} used by this codec.
156
+ * This method should be implemented by subclasses to provide the specific
157
+ * {@link FieldInfosFormat} that this codec is intended to use.
158
+ *
159
+ * @return the original {@link FieldInfosFormat} used by this codec
160
+ */
161
+ protected abstract FieldInfosFormat originalFieldInfosFormat ();
162
+
91
163
// mark all fields as no term vectors, no norms, no payloads, and no vectors.
92
164
private static FieldInfos filterFields (FieldInfos fieldInfos ) {
93
165
List <FieldInfo > fieldInfoCopy = new ArrayList <>(fieldInfos .size ());
@@ -119,15 +191,14 @@ private static FieldInfos filterFields(FieldInfos fieldInfos) {
119
191
}
120
192
121
193
public static SegmentInfo wrap (SegmentInfo segmentInfo ) {
122
- // special handling for Lucene70Codec (which is currently bundled with Lucene)
123
- // Use BWCLucene70Codec instead as that one extends BWCCodec (similar to all other older codecs)
124
- final Codec codec = segmentInfo .getCodec () instanceof Lucene70Codec ? new BWCLucene70Codec () : segmentInfo .getCodec ();
194
+ Codec codec = getBackwardCompatibleCodec (segmentInfo .getCodec ());
195
+
125
196
final SegmentInfo segmentInfo1 = new SegmentInfo (
126
197
segmentInfo .dir ,
127
198
// Use Version.LATEST instead of original version, otherwise SegmentCommitInfo will bark when processing (N-1 limitation)
128
199
// TODO: perhaps store the original version information in attributes so that we can retrieve it later when needed?
129
- org . apache . lucene . util . Version .LATEST ,
130
- org . apache . lucene . util . Version .LATEST ,
200
+ Version .LATEST ,
201
+ Version .LATEST ,
131
202
segmentInfo .name ,
132
203
segmentInfo .maxDoc (),
133
204
segmentInfo .getUseCompoundFile (),
@@ -142,6 +213,28 @@ public static SegmentInfo wrap(SegmentInfo segmentInfo) {
142
213
return segmentInfo1 ;
143
214
}
144
215
216
+ /**
217
+ * Returns a backward-compatible codec for the given codec. If the codec is one of the known Lucene 8.x codecs,
218
+ * it returns a corresponding read-only backward-compatible codec. Otherwise, it returns the original codec.
219
+ * Lucene 8.x codecs are still shipped with the current version of Lucene.
220
+ * Earlier codecs we are providing directly they will also be read-only backward-compatible, but they don't require the renaming.
221
+ *
222
+ * This switch is only for indices created in ES 6.x, later written into in ES 7.x (Lucene 8.x). Indices created
223
+ * in ES 7.x can be read directly by ES if marked read-only, without going through archive indices.
224
+ */
225
+ private static Codec getBackwardCompatibleCodec (Codec codec ) {
226
+ if (codec == null ) return null ;
227
+
228
+ return switch (codec .getClass ().getSimpleName ()) {
229
+ case "Lucene70Codec" -> new BWCLucene70Codec ();
230
+ case "Lucene80Codec" -> new BWCLucene80Codec ();
231
+ case "Lucene84Codec" -> new BWCLucene84Codec ();
232
+ case "Lucene86Codec" -> new BWCLucene86Codec ();
233
+ case "Lucene87Codec" -> new BWCLucene87Codec ();
234
+ default -> codec ;
235
+ };
236
+ }
237
+
145
238
/**
146
239
* In-memory postings format that shows no postings available.
147
240
*/
0 commit comments