55
66package org .opensearch .knn .index .engine ;
77
8+ import com .google .common .annotations .VisibleForTesting ;
89import org .apache .logging .log4j .LogManager ;
910import org .apache .logging .log4j .Logger ;
11+ import org .opensearch .Version ;
1012import org .opensearch .knn .index .mapper .CompressionLevel ;
1113import org .opensearch .knn .index .mapper .Mode ;
1214
@@ -22,47 +24,83 @@ public final class EngineResolver {
2224
2325 private EngineResolver () {}
2426
27+ @ VisibleForTesting
28+ KNNEngine resolveEngine (KNNMethodConfigContext knnMethodConfigContext , KNNMethodContext knnMethodContext , boolean requiresTraining ) {
29+ return logAndReturnEngine (resolveKNNEngine (knnMethodConfigContext , knnMethodContext , requiresTraining , Version .CURRENT ));
30+ }
31+
2532 /**
2633 * Based on the provided {@link Mode} and {@link CompressionLevel}, resolve to a {@link KNNEngine}.
2734 *
2835 * @param knnMethodConfigContext configuration context
2936 * @param knnMethodContext KNNMethodContext
3037 * @param requiresTraining whether config requires training
38+ * @param version opensearch index version
3139 * @return {@link KNNEngine}
3240 */
3341 public KNNEngine resolveEngine (
3442 KNNMethodConfigContext knnMethodConfigContext ,
3543 KNNMethodContext knnMethodContext ,
36- boolean requiresTraining
44+ boolean requiresTraining ,
45+ Version version
3746 ) {
38- // User configuration gets precedence
39- if (knnMethodContext != null && knnMethodContext .isEngineConfigured ()) {
40- return logAndReturnEngine (knnMethodContext .getKnnEngine ());
47+ return logAndReturnEngine (resolveKNNEngine (knnMethodConfigContext , knnMethodContext , requiresTraining , version ));
48+ }
49+
50+ /**
51+ * Based on the provided {@link Mode} and {@link CompressionLevel}, resolve to a {@link KNNEngine}.
52+ *
53+ * @param knnMethodConfigContext configuration context
54+ * @param knnMethodContext KNNMethodContext
55+ * @param requiresTraining whether config requires training
56+ * @param version opensearch index version
57+ * @return {@link KNNEngine}
58+ */
59+ private KNNEngine resolveKNNEngine (
60+ KNNMethodConfigContext knnMethodConfigContext ,
61+ KNNMethodContext knnMethodContext ,
62+ boolean requiresTraining ,
63+ Version version
64+ ) {
65+ // Check user configuration first
66+ if (hasUserConfiguredEngine (knnMethodContext )) {
67+ return knnMethodContext .getKnnEngine ();
4168 }
4269
43- // Faiss is the only engine that supports training, so we default to faiss here for now
70+ // Handle training case
4471 if (requiresTraining ) {
45- return logAndReturnEngine (KNNEngine .FAISS );
72+ // Faiss is the only engine that supports training, so we default to faiss here for now
73+ return KNNEngine .FAISS ;
4674 }
4775
4876 Mode mode = knnMethodConfigContext .getMode ();
4977 CompressionLevel compressionLevel = knnMethodConfigContext .getCompressionLevel ();
78+
5079 // If both mode and compression are not specified, we can just default
5180 if (Mode .isConfigured (mode ) == false && CompressionLevel .isConfigured (compressionLevel ) == false ) {
52- return logAndReturnEngine ( KNNEngine .DEFAULT ) ;
81+ return KNNEngine .DEFAULT ;
5382 }
5483
55- // For 1x, we need to default to faiss if mode is provided and use nmslib otherwise
84+ if (compressionLevel == CompressionLevel .x4 ) {
85+ // Lucene is only engine that supports 4x - so we have to default to it here.
86+ return KNNEngine .LUCENE ;
87+ }
5688 if (CompressionLevel .isConfigured (compressionLevel ) == false || compressionLevel == CompressionLevel .x1 ) {
57- return logAndReturnEngine (mode == Mode .ON_DISK ? KNNEngine .FAISS : KNNEngine .NMSLIB );
89+ // For 1x or no compression, we need to default to faiss if mode is provided and use nmslib otherwise based on version check
90+ return resolveEngineForX1OrNoCompression (mode , version );
5891 }
92+ return KNNEngine .FAISS ;
93+ }
5994
60- // Lucene is only engine that supports 4x - so we have to default to it here.
61- if (compressionLevel == CompressionLevel .x4 ) {
62- return logAndReturnEngine (KNNEngine .LUCENE );
63- }
95+ private boolean hasUserConfiguredEngine (KNNMethodContext knnMethodContext ) {
96+ return knnMethodContext != null && knnMethodContext .isEngineConfigured ();
97+ }
6498
65- return logAndReturnEngine (KNNEngine .FAISS );
99+ private KNNEngine resolveEngineForX1OrNoCompression (Mode mode , Version version ) {
100+ if (version != null && version .onOrAfter (Version .V_2_19_0 )) {
101+ return KNNEngine .FAISS ;
102+ }
103+ return mode == Mode .ON_DISK ? KNNEngine .FAISS : KNNEngine .NMSLIB ;
66104 }
67105
68106 private KNNEngine logAndReturnEngine (KNNEngine knnEngine ) {
0 commit comments