Skip to content

Commit 3c1b7ba

Browse files
authored
Merge branch 'main' into inference-entitlements
2 parents 50aa3de + 4841f43 commit 3c1b7ba

File tree

36 files changed

+1347
-211
lines changed

36 files changed

+1347
-211
lines changed

docs/changelog/121548.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 121548
2+
summary: Adding support for specifying embedding type to Jina AI service settings
3+
area: Machine Learning
4+
type: enhancement
5+
issues: []

libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/policy/FileAccessTree.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,10 @@ private FileAccessTree(
138138
});
139139
}
140140

141-
// everything has access to the temp dir and the jdk
141+
// everything has access to the temp dir, config dir and the jdk
142142
addPathAndMaybeLink.accept(pathLookup.tempDir(), Mode.READ_WRITE);
143+
// TODO: this grants read access to the config dir for all modules until explicit read entitlements can be added
144+
addPathAndMaybeLink.accept(pathLookup.configDir(), Mode.READ);
143145

144146
// TODO: watcher uses javax.activation which looks for known mime types configuration, should this be global or explicit in watcher?
145147
Path jdk = Paths.get(System.getProperty("java.home"));

libs/entitlement/src/test/java/org/elasticsearch/entitlement/runtime/policy/FileAccessTreeTests.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ public void testPathAndFileWithSamePrefix() {
136136
}
137137

138138
public void testReadWithRelativePath() {
139-
for (var dir : List.of("config", "home")) {
139+
for (var dir : List.of("home")) {
140140
var tree = accessTree(entitlement(Map.of("relative_path", "foo", "mode", "read", "relative_to", dir)), List.of());
141141
assertThat(tree.canRead(path("foo")), is(false));
142142

@@ -153,7 +153,7 @@ public void testReadWithRelativePath() {
153153
}
154154

155155
public void testWriteWithRelativePath() {
156-
for (var dir : List.of("config", "home")) {
156+
for (var dir : List.of("home")) {
157157
var tree = accessTree(entitlement(Map.of("relative_path", "foo", "mode", "read_write", "relative_to", dir)), List.of());
158158
assertThat(tree.canWrite(path("/" + dir + "/foo")), is(true));
159159
assertThat(tree.canWrite(path("/" + dir + "/foo/subdir")), is(true));
@@ -289,6 +289,12 @@ public void testTempDirAccess() {
289289
assertThat(tree.canWrite(TEST_PATH_LOOKUP.tempDir()), is(true));
290290
}
291291

292+
public void testConfigDirAccess() {
293+
var tree = FileAccessTree.of("test-component", "test-module", FilesEntitlement.EMPTY, TEST_PATH_LOOKUP, List.of());
294+
assertThat(tree.canRead(TEST_PATH_LOOKUP.configDir()), is(true));
295+
assertThat(tree.canWrite(TEST_PATH_LOOKUP.configDir()), is(false));
296+
}
297+
292298
public void testBasicExclusiveAccess() {
293299
var tree = accessTree(entitlement("foo", "read"), exclusivePaths("test-component", "test-module", "foo"));
294300
assertThat(tree.canRead(path("foo")), is(true));

modules/data-streams/src/test/java/org/elasticsearch/datastreams/mapper/DataStreamTimestampFieldMapperTests.java

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
*/
99
package org.elasticsearch.datastreams.mapper;
1010

11+
import org.elasticsearch.cluster.metadata.IndexMetadata;
1112
import org.elasticsearch.common.settings.Settings;
1213
import org.elasticsearch.core.CheckedConsumer;
1314
import org.elasticsearch.datastreams.DataStreamsPlugin;
@@ -537,4 +538,199 @@ public void testFieldTypeWithDocValuesSkipper_CustomTimestampField() throws IOEx
537538
assertFalse(defaultTimestamp.fieldType().hasDocValuesSkipper());
538539
}
539540
}
541+
542+
public void testFieldTypeWithDocValuesSkipper_TSDBModeDisabledDocValuesSkipper() throws IOException {
543+
final Settings settings = Settings.builder()
544+
.put(IndexSettings.MODE.getKey(), IndexMode.TIME_SERIES.name())
545+
.put(IndexMetadata.INDEX_ROUTING_PATH.getKey(), "dim")
546+
.put(IndexSettings.TIME_SERIES_START_TIME.getKey(), "2021-04-28T00:00:00Z")
547+
.put(IndexSettings.TIME_SERIES_END_TIME.getKey(), "2021-04-29T00:00:00Z")
548+
.put(IndexSettings.USE_DOC_VALUES_SKIPPER.getKey(), false)
549+
.build();
550+
final MapperService mapperService = createMapperService(settings, timestampMapping(true, b -> {
551+
b.startObject(DataStreamTimestampFieldMapper.DEFAULT_PATH);
552+
b.field("type", "date");
553+
b.endObject();
554+
}));
555+
556+
final DateFieldMapper timestampMapper = (DateFieldMapper) mapperService.documentMapper()
557+
.mappers()
558+
.getMapper(DataStreamTimestampFieldMapper.DEFAULT_PATH);
559+
assumeTrue("doc_values_skipper feature flag enabled", IndexSettings.DOC_VALUES_SKIPPER.isEnabled());
560+
assertTrue(timestampMapper.fieldType().hasDocValues());
561+
assertFalse(timestampMapper.fieldType().hasDocValuesSkipper());
562+
assertTrue(timestampMapper.fieldType().isIndexed());
563+
}
564+
565+
public void testFieldTypeWithDocValuesSkipper_TSDBMode() throws IOException {
566+
final Settings settings = Settings.builder()
567+
.put(IndexSettings.MODE.getKey(), IndexMode.TIME_SERIES.name())
568+
.put(IndexMetadata.INDEX_ROUTING_PATH.getKey(), "dim")
569+
.put(IndexSettings.TIME_SERIES_START_TIME.getKey(), "2021-04-28T00:00:00Z")
570+
.put(IndexSettings.TIME_SERIES_END_TIME.getKey(), "2021-04-29T00:00:00Z")
571+
.build();
572+
final MapperService mapperService = createMapperService(settings, timestampMapping(true, b -> {
573+
b.startObject(DataStreamTimestampFieldMapper.DEFAULT_PATH);
574+
b.field("type", "date");
575+
b.endObject();
576+
}));
577+
578+
final DateFieldMapper timestampMapper = (DateFieldMapper) mapperService.documentMapper()
579+
.mappers()
580+
.getMapper(DataStreamTimestampFieldMapper.DEFAULT_PATH);
581+
assertTrue(timestampMapper.fieldType().hasDocValues());
582+
if (IndexSettings.USE_DOC_VALUES_SKIPPER.get(settings)) {
583+
assumeTrue("doc_values_skipper feature flag enabled", IndexSettings.DOC_VALUES_SKIPPER.isEnabled());
584+
assertFalse(timestampMapper.fieldType().isIndexed());
585+
assertTrue(timestampMapper.fieldType().hasDocValuesSkipper());
586+
} else {
587+
// TODO: remove this 'else' branch when removing the `doc_values_skipper` feature flag
588+
assumeFalse("doc_values_skipper feature flag enabled", IndexSettings.DOC_VALUES_SKIPPER.isEnabled() == false);
589+
assertTrue(timestampMapper.fieldType().isIndexed());
590+
assertFalse(timestampMapper.fieldType().hasDocValuesSkipper());
591+
}
592+
}
593+
594+
public void testFieldTypeWithDocValuesSkipper_TSDBModeNoTimestampMapping() throws IOException {
595+
final Settings settings = Settings.builder()
596+
.put(IndexSettings.MODE.getKey(), IndexMode.TIME_SERIES.name())
597+
.put(IndexMetadata.INDEX_ROUTING_PATH.getKey(), "dim")
598+
.put(IndexSettings.TIME_SERIES_START_TIME.getKey(), "2021-04-28T00:00:00Z")
599+
.put(IndexSettings.TIME_SERIES_END_TIME.getKey(), "2021-04-29T00:00:00Z")
600+
.build();
601+
final MapperService mapperService = createMapperService(settings, timestampMapping(true, b -> {}));
602+
603+
final DateFieldMapper timestampMapper = (DateFieldMapper) mapperService.documentMapper()
604+
.mappers()
605+
.getMapper(DataStreamTimestampFieldMapper.DEFAULT_PATH);
606+
assertTrue(timestampMapper.fieldType().hasDocValues());
607+
if (IndexSettings.USE_DOC_VALUES_SKIPPER.get(settings)) {
608+
assumeTrue("doc_values_skipper feature flag enabled", IndexSettings.DOC_VALUES_SKIPPER.isEnabled());
609+
assertFalse(timestampMapper.fieldType().isIndexed());
610+
assertTrue(timestampMapper.fieldType().hasDocValuesSkipper());
611+
} else {
612+
// TODO: remove this 'else' branch when removing the `doc_values_skipper` feature flag
613+
assumeFalse("doc_values_skipper feature flag enabled", IndexSettings.DOC_VALUES_SKIPPER.isEnabled() == false);
614+
assertTrue(timestampMapper.fieldType().isIndexed());
615+
assertFalse(timestampMapper.fieldType().hasDocValuesSkipper());
616+
}
617+
}
618+
619+
public void testFieldTypeWithDocValuesSkipper_TSDBModeTimestampDateNanos() throws IOException {
620+
final Settings settings = Settings.builder()
621+
.put(IndexSettings.MODE.getKey(), IndexMode.TIME_SERIES.name())
622+
.put(IndexMetadata.INDEX_ROUTING_PATH.getKey(), "dim")
623+
.put(IndexSettings.TIME_SERIES_START_TIME.getKey(), "2021-04-28T00:00:00Z")
624+
.put(IndexSettings.TIME_SERIES_END_TIME.getKey(), "2021-04-29T00:00:00Z")
625+
.build();
626+
final MapperService mapperService = withMapping(
627+
new TestMapperServiceBuilder().settings(settings).applyDefaultMapping(false).build(),
628+
timestampMapping(true, b -> {
629+
b.startObject(DataStreamTimestampFieldMapper.DEFAULT_PATH);
630+
b.field("type", "date_nanos");
631+
b.endObject();
632+
})
633+
);
634+
635+
final DateFieldMapper timestampMapper = (DateFieldMapper) mapperService.documentMapper()
636+
.mappers()
637+
.getMapper(DataStreamTimestampFieldMapper.DEFAULT_PATH);
638+
assertTrue(timestampMapper.fieldType().hasDocValues());
639+
if (IndexSettings.USE_DOC_VALUES_SKIPPER.get(settings)) {
640+
assumeTrue("doc_values_skipper feature flag enabled", IndexSettings.DOC_VALUES_SKIPPER.isEnabled());
641+
assertFalse(timestampMapper.fieldType().isIndexed());
642+
assertTrue(timestampMapper.fieldType().hasDocValuesSkipper());
643+
} else {
644+
// TODO: remove this 'else' branch when removing the `doc_values_skipper` feature flag
645+
assumeFalse("doc_values_skipper feature flag enabled", IndexSettings.DOC_VALUES_SKIPPER.isEnabled() == false);
646+
assertTrue(timestampMapper.fieldType().isIndexed());
647+
assertFalse(timestampMapper.fieldType().hasDocValuesSkipper());
648+
}
649+
}
650+
651+
public void testFieldTypeWithDocValuesSkipper_TSDBModeExplicitTimestampIndexEnabledDocValuesSkipper() throws IOException {
652+
final Settings settings = Settings.builder()
653+
.put(IndexSettings.MODE.getKey(), IndexMode.TIME_SERIES.name())
654+
.put(IndexMetadata.INDEX_ROUTING_PATH.getKey(), "dim")
655+
.put(IndexSettings.TIME_SERIES_START_TIME.getKey(), "2021-04-28T00:00:00Z")
656+
.put(IndexSettings.TIME_SERIES_END_TIME.getKey(), "2021-04-29T00:00:00Z")
657+
.build();
658+
final MapperService mapperService = createMapperService(settings, timestampMapping(true, b -> {
659+
b.startObject(DataStreamTimestampFieldMapper.DEFAULT_PATH);
660+
b.field("type", "date");
661+
b.field("index", true);
662+
b.endObject();
663+
}));
664+
665+
final DateFieldMapper timestampMapper = (DateFieldMapper) mapperService.documentMapper()
666+
.mappers()
667+
.getMapper(DataStreamTimestampFieldMapper.DEFAULT_PATH);
668+
assertTrue(timestampMapper.fieldType().hasDocValues());
669+
if (IndexSettings.USE_DOC_VALUES_SKIPPER.get(settings)) {
670+
assumeTrue("doc_values_skipper feature flag enabled", IndexSettings.DOC_VALUES_SKIPPER.isEnabled());
671+
assertFalse(timestampMapper.fieldType().isIndexed());
672+
assertTrue(timestampMapper.fieldType().hasDocValuesSkipper());
673+
} else {
674+
// TODO: remove this 'else' branch when removing the `doc_values_skipper` feature flag
675+
assumeFalse("doc_values_skipper feature flag enabled", IndexSettings.DOC_VALUES_SKIPPER.isEnabled() == false);
676+
assertTrue(timestampMapper.fieldType().isIndexed());
677+
assertFalse(timestampMapper.fieldType().hasDocValuesSkipper());
678+
}
679+
}
680+
681+
public void testFieldTypeWithDocValuesSkipper_TSDBModeExplicitTimestampIndexDisabledDocValuesSkipper() throws IOException {
682+
final Settings settings = Settings.builder()
683+
.put(IndexSettings.MODE.getKey(), IndexMode.TIME_SERIES.name())
684+
.put(IndexMetadata.INDEX_ROUTING_PATH.getKey(), "dim")
685+
.put(IndexSettings.TIME_SERIES_START_TIME.getKey(), "2021-04-28T00:00:00Z")
686+
.put(IndexSettings.TIME_SERIES_END_TIME.getKey(), "2021-04-29T00:00:00Z")
687+
.put(IndexSettings.USE_DOC_VALUES_SKIPPER.getKey(), false)
688+
.build();
689+
final MapperService mapperService = createMapperService(settings, timestampMapping(true, b -> {
690+
b.startObject(DataStreamTimestampFieldMapper.DEFAULT_PATH);
691+
b.field("type", "date");
692+
b.field("index", true);
693+
b.endObject();
694+
}));
695+
696+
final DateFieldMapper timestampMapper = (DateFieldMapper) mapperService.documentMapper()
697+
.mappers()
698+
.getMapper(DataStreamTimestampFieldMapper.DEFAULT_PATH);
699+
assumeFalse("doc_values_skipper feature flag enabled", IndexSettings.DOC_VALUES_SKIPPER.isEnabled() == false);
700+
assertTrue(timestampMapper.fieldType().hasDocValues());
701+
assertFalse(timestampMapper.fieldType().hasDocValuesSkipper());
702+
assertTrue(timestampMapper.fieldType().isIndexed());
703+
}
704+
705+
public void testFieldTypeWithDocValuesSkipper_TSDBModeWithoutDefaultMapping() throws IOException {
706+
final Settings settings = Settings.builder()
707+
.put(IndexSettings.MODE.getKey(), IndexMode.TIME_SERIES.name())
708+
.put(IndexMetadata.INDEX_ROUTING_PATH.getKey(), "dim")
709+
.put(IndexSettings.TIME_SERIES_START_TIME.getKey(), "2021-04-28T00:00:00Z")
710+
.put(IndexSettings.TIME_SERIES_END_TIME.getKey(), "2021-04-29T00:00:00Z")
711+
.build();
712+
final MapperService mapperService = withMapping(
713+
new TestMapperServiceBuilder().settings(settings).applyDefaultMapping(false).build(),
714+
timestampMapping(true, b -> {
715+
b.startObject(DataStreamTimestampFieldMapper.DEFAULT_PATH);
716+
b.field("type", "date");
717+
b.endObject();
718+
})
719+
);
720+
721+
final DateFieldMapper timestampMapper = (DateFieldMapper) mapperService.documentMapper()
722+
.mappers()
723+
.getMapper(DataStreamTimestampFieldMapper.DEFAULT_PATH);
724+
assertTrue(timestampMapper.fieldType().hasDocValues());
725+
if (IndexSettings.USE_DOC_VALUES_SKIPPER.get(settings)) {
726+
assumeTrue("doc_values_skipper feature flag enabled", IndexSettings.DOC_VALUES_SKIPPER.isEnabled());
727+
assertFalse(timestampMapper.fieldType().isIndexed());
728+
assertTrue(timestampMapper.fieldType().hasDocValuesSkipper());
729+
} else {
730+
// TODO: remove this 'else' branch when removing the `doc_values_skipper` feature flag
731+
assumeFalse("doc_values_skipper feature flag enabled", IndexSettings.DOC_VALUES_SKIPPER.isEnabled() == false);
732+
assertTrue(timestampMapper.fieldType().isIndexed());
733+
assertFalse(timestampMapper.fieldType().hasDocValuesSkipper());
734+
}
735+
}
540736
}

server/src/internalClusterTest/java/org/elasticsearch/index/shard/SearchIdleIT.java

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -242,16 +242,31 @@ public void testSearchIdleBoolQueryMatchOneIndex() throws InterruptedException {
242242
// are executed only if we have enough shards.
243243
int idleIndexShardsCount = 3;
244244
int activeIndexShardsCount = 3;
245+
246+
var idleIndexSettingsBuilder = Settings.builder()
247+
.put(IndexSettings.INDEX_SEARCH_IDLE_AFTER.getKey(), "500ms")
248+
.put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, idleIndexShardsCount)
249+
.put(IndexSettings.MODE.getKey(), IndexMode.TIME_SERIES)
250+
.put(IndexMetadata.INDEX_ROUTING_PATH.getKey(), "routing_field")
251+
.put(IndexSettings.TIME_SERIES_START_TIME.getKey(), "2021-05-10T00:00:00.000Z")
252+
.put(IndexSettings.TIME_SERIES_END_TIME.getKey(), "2021-05-11T00:00:00.000Z");
253+
254+
var activeIndexSettingsBuilder = Settings.builder()
255+
.put(IndexSettings.INDEX_SEARCH_IDLE_AFTER.getKey(), "500ms")
256+
.put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, activeIndexShardsCount)
257+
.put(IndexSettings.MODE.getKey(), IndexMode.TIME_SERIES)
258+
.put(IndexMetadata.INDEX_ROUTING_PATH.getKey(), "routing_field")
259+
.put(IndexSettings.TIME_SERIES_START_TIME.getKey(), "2021-05-12T00:00:00.000Z")
260+
.put(IndexSettings.TIME_SERIES_END_TIME.getKey(), "2021-05-13T23:59:59.999Z");
261+
262+
if (IndexSettings.DOC_VALUES_SKIPPER.isEnabled()) {
263+
idleIndexSettingsBuilder.put(IndexSettings.USE_DOC_VALUES_SKIPPER.getKey(), false);
264+
activeIndexSettingsBuilder.put(IndexSettings.USE_DOC_VALUES_SKIPPER.getKey(), false);
265+
}
266+
245267
createIndex(
246268
idleIndex,
247-
Settings.builder()
248-
.put(IndexSettings.INDEX_SEARCH_IDLE_AFTER.getKey(), "500ms")
249-
.put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, idleIndexShardsCount)
250-
.put(IndexSettings.MODE.getKey(), IndexMode.TIME_SERIES)
251-
.put(IndexMetadata.INDEX_ROUTING_PATH.getKey(), "routing_field")
252-
.put(IndexSettings.TIME_SERIES_START_TIME.getKey(), "2021-05-10T00:00:00.000Z")
253-
.put(IndexSettings.TIME_SERIES_END_TIME.getKey(), "2021-05-11T00:00:00.000Z")
254-
.build(),
269+
idleIndexSettingsBuilder.build(),
255270
"doc",
256271
"keyword",
257272
"type=keyword",
@@ -262,14 +277,7 @@ public void testSearchIdleBoolQueryMatchOneIndex() throws InterruptedException {
262277
);
263278
createIndex(
264279
activeIndex,
265-
Settings.builder()
266-
.put(IndexSettings.INDEX_SEARCH_IDLE_AFTER.getKey(), "500ms")
267-
.put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, activeIndexShardsCount)
268-
.put(IndexSettings.MODE.getKey(), IndexMode.TIME_SERIES)
269-
.put(IndexMetadata.INDEX_ROUTING_PATH.getKey(), "routing_field")
270-
.put(IndexSettings.TIME_SERIES_START_TIME.getKey(), "2021-05-12T00:00:00.000Z")
271-
.put(IndexSettings.TIME_SERIES_END_TIME.getKey(), "2021-05-13T23:59:59.999Z")
272-
.build(),
280+
activeIndexSettingsBuilder.build(),
273281
"doc",
274282
"keyword",
275283
"type=keyword",

server/src/main/java/org/elasticsearch/TransportVersions.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ static TransportVersion def(int id) {
181181
public static final TransportVersion ESQL_RETRY_ON_SHARD_LEVEL_FAILURE_BACKPORT_8_19 = def(8_841_0_03);
182182
public static final TransportVersion ESQL_SUPPORT_PARTIAL_RESULTS_BACKPORT_8_19 = def(8_841_0_04);
183183
public static final TransportVersion VOYAGE_AI_INTEGRATION_ADDED_BACKPORT_8_X = def(8_841_0_05);
184+
public static final TransportVersion JINA_AI_EMBEDDING_TYPE_SUPPORT_ADDED_BACKPORT_8_19 = def(8_841_0_06);
184185
public static final TransportVersion INITIAL_ELASTICSEARCH_9_0 = def(9_000_0_00);
185186
public static final TransportVersion REMOVE_SNAPSHOT_FAILURES_90 = def(9_000_0_01);
186187
public static final TransportVersion TRANSPORT_STATS_HANDLING_TIME_REQUIRED_90 = def(9_000_0_02);
@@ -207,6 +208,7 @@ static TransportVersion def(int id) {
207208
public static final TransportVersion ESQL_DRIVER_NODE_DESCRIPTION = def(9_017_0_00);
208209
public static final TransportVersion MULTI_PROJECT = def(9_018_0_00);
209210
public static final TransportVersion STORED_SCRIPT_CONTENT_LENGTH = def(9_019_0_00);
211+
public static final TransportVersion JINA_AI_EMBEDDING_TYPE_SUPPORT_ADDED = def(9_020_0_00);
210212

211213
/*
212214
* STOP! READ THIS FIRST! No, really,

server/src/main/java/org/elasticsearch/cluster/metadata/DataStream.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
package org.elasticsearch.cluster.metadata;
1010

1111
import org.apache.lucene.document.LongPoint;
12+
import org.apache.lucene.index.DocValuesSkipIndexType;
13+
import org.apache.lucene.index.DocValuesSkipper;
14+
import org.apache.lucene.index.FieldInfo;
1215
import org.apache.lucene.index.LeafReader;
1316
import org.apache.lucene.index.PointValues;
1417
import org.elasticsearch.ElasticsearchException;
@@ -84,6 +87,12 @@ public static boolean isFailureStoreFeatureFlagEnabled() {
8487
// Timeseries indices' leaf readers should be sorted by desc order of their timestamp field, as it allows search time optimizations
8588
public static final Comparator<LeafReader> TIMESERIES_LEAF_READERS_SORTER = Comparator.comparingLong((LeafReader r) -> {
8689
try {
90+
FieldInfo info = r.getFieldInfos().fieldInfo(TIMESTAMP_FIELD_NAME);
91+
if (info != null && info.docValuesSkipIndexType() == DocValuesSkipIndexType.RANGE) {
92+
DocValuesSkipper skipper = r.getDocValuesSkipper(TIMESTAMP_FIELD_NAME);
93+
return skipper.maxValue();
94+
}
95+
8796
PointValues points = r.getPointValues(TIMESTAMP_FIELD_NAME);
8897
if (points != null) {
8998
byte[] sortValue = points.getMaxPackedValue();

0 commit comments

Comments
 (0)