|
155 | 155 | import java.io.Closeable;
|
156 | 156 | import java.io.IOException;
|
157 | 157 | import java.io.PrintStream;
|
| 158 | +import java.lang.invoke.MethodHandles; |
| 159 | +import java.lang.invoke.VarHandle; |
158 | 160 | import java.nio.channels.ClosedByInterruptException;
|
159 | 161 | import java.nio.charset.StandardCharsets;
|
160 | 162 | import java.util.ArrayList;
|
@@ -1019,14 +1021,24 @@ private Engine.IndexResult applyIndexOperation(
|
1019 | 1021 | return index(engine, operation);
|
1020 | 1022 | }
|
1021 | 1023 |
|
1022 |
| - public void setFieldInfos(FieldInfos fieldInfos) { |
1023 |
| - this.fieldInfos = fieldInfos; |
| 1024 | + private static final VarHandle FIELD_INFOS; |
| 1025 | + |
| 1026 | + static { |
| 1027 | + try { |
| 1028 | + FIELD_INFOS = MethodHandles.lookup().findVarHandle(IndexShard.class, "fieldInfos", FieldInfos.class); |
| 1029 | + } catch (Exception e) { |
| 1030 | + throw new ExceptionInInitializerError(e); |
| 1031 | + } |
1024 | 1032 | }
|
1025 | 1033 |
|
1026 | 1034 | public FieldInfos getFieldInfos() {
|
1027 | 1035 | var res = fieldInfos;
|
1028 | 1036 | if (res == null) {
|
1029 |
| - return loadFieldInfos(); |
| 1037 | + // don't replace field infos loaded via the refresh listener to avoid overwriting the field with an older version of the |
| 1038 | + // field infos when racing with a refresh |
| 1039 | + var read = loadFieldInfos(); |
| 1040 | + var existing = (FieldInfos) FIELD_INFOS.compareAndExchange(this, null, read); |
| 1041 | + return existing == null ? read : existing; |
1030 | 1042 | }
|
1031 | 1043 | return res;
|
1032 | 1044 | }
|
@@ -4135,15 +4147,14 @@ public void beforeRefresh() {}
|
4135 | 4147 | @Override
|
4136 | 4148 | public void afterRefresh(boolean didRefresh) {
|
4137 | 4149 | if (enableFieldHasValue && (didRefresh || fieldInfos == null)) {
|
4138 |
| - loadFieldInfos(); |
| 4150 | + FIELD_INFOS.setRelease(IndexShard.this, loadFieldInfos()); |
4139 | 4151 | }
|
4140 | 4152 | }
|
4141 | 4153 | }
|
4142 | 4154 |
|
4143 | 4155 | private FieldInfos loadFieldInfos() {
|
4144 | 4156 | try (Engine.Searcher hasValueSearcher = getEngine().acquireSearcher("field_has_value")) {
|
4145 | 4157 | var res = FieldInfos.getMergedFieldInfos(hasValueSearcher.getIndexReader());
|
4146 |
| - setFieldInfos(res); |
4147 | 4158 | return res;
|
4148 | 4159 | } catch (AlreadyClosedException ignore) {
|
4149 | 4160 | // engine is closed - no update to3 FieldInfos is fine
|
|
0 commit comments