This is an automated email from the ASF dual-hosted git repository.

cpoerschke pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/solr.git


The following commit(s) were added to refs/heads/main by this push:
     new ce9930338d2 SOLR-17050: Use compact JSON for Learning to Rank (LTR) 
feature and model storage. (#2030)
ce9930338d2 is described below

commit ce9930338d2d576a3f83fc17754366c0bc0ca845
Author: Florin Babes <[email protected]>
AuthorDate: Mon Dec 4 16:21:05 2023 +0200

    SOLR-17050: Use compact JSON for Learning to Rank (LTR) feature and model 
storage. (#2030)
    
    Co-authored-by: Florin Babes <[email protected]>
    Co-authored-by: Christine Poerschke <[email protected]>
---
 solr/CHANGES.txt                                   |  2 ++
 .../apache/solr/rest/ManagedResourceStorage.java   | 14 +++++++-
 .../src/test/org/apache/solr/util/TestUtils.java   | 40 ++++++++++++++++++++++
 .../solr/ltr/store/rest/ManagedFeatureStore.java   |  6 ++++
 .../solr/ltr/store/rest/ManagedModelStore.java     |  6 ++++
 .../store/rest/TestModelManagerPersistence.java    | 20 +++++++++++
 .../java/org/apache/solr/common/util/Utils.java    | 21 +++++++++++-
 solr/solrj/src/java/org/noggit/JSONWriter.java     |  4 ++-
 8 files changed, 110 insertions(+), 3 deletions(-)

diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index da916a6be6c..9e63d1ce42e 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -113,6 +113,8 @@ Improvements
 
 * SOLR-16959: Make the internal CoreSorter implementation configurable in 
solr.xml  (Vincent Primault)
 
+* SOLR-17050: Use compact JSON for Learning to Rank (LTR) feature and model 
storage. (Florin Babes, Christine Poerschke, Alessandro Benedetti)
+
 Optimizations
 ---------------------
 * SOLR-17084: LBSolrClient (used by CloudSolrClient) now returns the count of 
core tracked as not live AKA zombies
diff --git 
a/solr/core/src/java/org/apache/solr/rest/ManagedResourceStorage.java 
b/solr/core/src/java/org/apache/solr/rest/ManagedResourceStorage.java
index b28f4f57c36..af04c36eaab 100644
--- a/solr/core/src/java/org/apache/solr/rest/ManagedResourceStorage.java
+++ b/solr/core/src/java/org/apache/solr/rest/ManagedResourceStorage.java
@@ -47,6 +47,7 @@ import org.apache.solr.common.cloud.ZkStateReader;
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.common.util.Utils;
 import org.apache.solr.core.SolrResourceLoader;
+import org.noggit.JSONWriter;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -420,9 +421,20 @@ public abstract class ManagedResourceStorage {
 
   /** Default storage implementation that uses JSON as the storage format for 
managed data. */
   public static class JsonStorage extends ManagedResourceStorage {
+    private final int indentSize;
 
+    /** Uses {@link JSONWriter#DEFAULT_INDENT} space characters as an indent. 
*/
     public JsonStorage(StorageIO storageIO, SolrResourceLoader loader) {
+      this(storageIO, loader, JSONWriter.DEFAULT_INDENT);
+    }
+
+    /**
+     * @param indentSize The number of space characters to use as an indent. 
0=newlines but no
+     *     spaces, -1=no indent at all.
+     */
+    public JsonStorage(StorageIO storageIO, SolrResourceLoader loader, int 
indentSize) {
       super(storageIO, loader);
+      this.indentSize = indentSize;
     }
 
     /**
@@ -441,7 +453,7 @@ public abstract class ManagedResourceStorage {
 
     @Override
     public void store(String resourceId, Object toStore) throws IOException {
-      String json = toJSONString(toStore);
+      String json = toJSONString(toStore, indentSize);
       String storedResourceId = getStoredResourceId(resourceId);
       OutputStreamWriter writer = null;
       try {
diff --git a/solr/core/src/test/org/apache/solr/util/TestUtils.java 
b/solr/core/src/test/org/apache/solr/util/TestUtils.java
index e05f3130360..3e18f8e766c 100644
--- a/solr/core/src/test/org/apache/solr/util/TestUtils.java
+++ b/solr/core/src/test/org/apache/solr/util/TestUtils.java
@@ -294,4 +294,44 @@ public class TestUtils extends SolrTestCaseJ4 {
     assertEquals(
         2L, Utils.getObjectByPath(sink, true, List.of(DEFAULTS, 
COLLECTION_PROP, NRT_REPLICAS)));
   }
+
+  @SuppressWarnings({"unchecked"})
+  public void testToJson() {
+    Map<String, Object> object =
+        (Map<String, Object>) Utils.fromJSONString("{k2:v2, k1: {a:b, p:r, 
k21:{xx:yy}}}");
+
+    assertEquals(
+        "{\n"
+            + "  \"k2\":\"v2\",\n"
+            + "  \"k1\":{\n"
+            + "    \"a\":\"b\",\n"
+            + "    \"p\":\"r\",\n"
+            + "    \"k21\":{\"xx\":\"yy\"}}}",
+        new String(Utils.toJSON(object), UTF_8));
+  }
+
+  @SuppressWarnings({"unchecked"})
+  public void testToJsonCompacted() {
+    Map<String, Object> object =
+        (Map<String, Object>) Utils.fromJSONString("{k2:v2, k1: {a:b, p:r, 
k21:{xx:yy}}}");
+
+    assertEquals(
+        
"{\"k2\":\"v2\",\"k1\":{\"a\":\"b\",\"p\":\"r\",\"k21\":{\"xx\":\"yy\"}}}",
+        new String(Utils.toJSON(object, -1), UTF_8));
+  }
+
+  @SuppressWarnings({"unchecked"})
+  public void testToJsonNoIndent() {
+    Map<String, Object> object =
+        (Map<String, Object>) Utils.fromJSONString("{k2:v2, k1: {a:b, p:r, 
k21:{xx:yy}}}");
+
+    assertEquals(
+        "{\n"
+            + "\"k2\":\"v2\",\n"
+            + "\"k1\":{\n"
+            + "\"a\":\"b\",\n"
+            + "\"p\":\"r\",\n"
+            + "\"k21\":{\"xx\":\"yy\"}}}",
+        new String(Utils.toJSON(object, 0), UTF_8));
+  }
 }
diff --git 
a/solr/modules/ltr/src/java/org/apache/solr/ltr/store/rest/ManagedFeatureStore.java
 
b/solr/modules/ltr/src/java/org/apache/solr/ltr/store/rest/ManagedFeatureStore.java
index e867e7bbbad..96122f1604c 100644
--- 
a/solr/modules/ltr/src/java/org/apache/solr/ltr/store/rest/ManagedFeatureStore.java
+++ 
b/solr/modules/ltr/src/java/org/apache/solr/ltr/store/rest/ManagedFeatureStore.java
@@ -85,6 +85,12 @@ public class ManagedFeatureStore extends ManagedResource
     super(resourceId, loader, storageIO);
   }
 
+  @Override
+  protected ManagedResourceStorage createStorage(
+      ManagedResourceStorage.StorageIO storageIO, SolrResourceLoader loader) 
throws SolrException {
+    return new ManagedResourceStorage.JsonStorage(storageIO, loader, -1);
+  }
+
   public Map<String, FeatureStore> getStores() {
     return stores;
   }
diff --git 
a/solr/modules/ltr/src/java/org/apache/solr/ltr/store/rest/ManagedModelStore.java
 
b/solr/modules/ltr/src/java/org/apache/solr/ltr/store/rest/ManagedModelStore.java
index 918b06bd724..f6778e54425 100644
--- 
a/solr/modules/ltr/src/java/org/apache/solr/ltr/store/rest/ManagedModelStore.java
+++ 
b/solr/modules/ltr/src/java/org/apache/solr/ltr/store/rest/ManagedModelStore.java
@@ -93,6 +93,12 @@ public class ManagedModelStore extends ManagedResource
     store = new ModelStore();
   }
 
+  @Override
+  protected ManagedResourceStorage createStorage(
+      ManagedResourceStorage.StorageIO storageIO, SolrResourceLoader loader) 
throws SolrException {
+    return new ManagedResourceStorage.JsonStorage(storageIO, loader, -1);
+  }
+
   public void setManagedFeatureStore(ManagedFeatureStore managedFeatureStore) {
     log.info("INIT model store");
     this.managedFeatureStore = managedFeatureStore;
diff --git 
a/solr/modules/ltr/src/test/org/apache/solr/ltr/store/rest/TestModelManagerPersistence.java
 
b/solr/modules/ltr/src/test/org/apache/solr/ltr/store/rest/TestModelManagerPersistence.java
index 2adcc1f19f8..7b159e0e650 100644
--- 
a/solr/modules/ltr/src/test/org/apache/solr/ltr/store/rest/TestModelManagerPersistence.java
+++ 
b/solr/modules/ltr/src/test/org/apache/solr/ltr/store/rest/TestModelManagerPersistence.java
@@ -16,6 +16,8 @@
  */
 package org.apache.solr.ltr.store.rest;
 
+import static java.nio.charset.StandardCharsets.UTF_8;
+
 import java.io.BufferedWriter;
 import java.io.OutputStreamWriter;
 import java.nio.charset.StandardCharsets;
@@ -137,6 +139,24 @@ public class TestModelManagerPersistence extends 
TestRerankBase {
     assertJQ(ManagedModelStore.REST_END_POINT, "/models/==[]");
   }
 
+  @Test
+  public void testFeaturesAndModelAreStoredCompact() throws Exception {
+    loadFeature("feature", ValueFeature.class.getName(), "test", 
"{\"value\":2}");
+    loadModel(
+        "test-model",
+        LinearModel.class.getName(),
+        new String[] {"feature"},
+        "test",
+        "{\"weights\":{\"feature\":1.0}}");
+
+    final String fstorecontent = Files.readString(fstorefile, 
StandardCharsets.UTF_8);
+    final String mstorecontent = Files.readString(mstorefile, 
StandardCharsets.UTF_8);
+    Object fStoreObject = Utils.fromJSONString(fstorecontent);
+    Object mStoreObject = Utils.fromJSONString(mstorecontent);
+    assertEquals(new String(Utils.toJSON(fStoreObject, -1), UTF_8), 
fstorecontent);
+    assertEquals(new String(Utils.toJSON(mStoreObject, -1), UTF_8), 
mstorecontent);
+  }
+
   @Test
   public void testFilePersistence() throws Exception {
     // check whether models and features are empty
diff --git a/solr/solrj/src/java/org/apache/solr/common/util/Utils.java 
b/solr/solrj/src/java/org/apache/solr/common/util/Utils.java
index 0ae4886d670..2a3ea47b103 100644
--- a/solr/solrj/src/java/org/apache/solr/common/util/Utils.java
+++ b/solr/solrj/src/java/org/apache/solr/common/util/Utils.java
@@ -217,10 +217,29 @@ public class Utils {
   public static byte[] toJSON(Object o) {
     if (o == null) return new byte[0];
     CharArr out = new CharArr();
-    new JSONWriter(out, 2).write(o); // indentation by default
+    new JSONWriter(out, JSONWriter.DEFAULT_INDENT).write(o); // indentation by 
default
     return toUTF8(out);
   }
 
+  /**
+   * @param indentSize The number of space characters to use as an indent. 
0=newlines but no spaces,
+   *     -1=no indent at all.
+   */
+  public static byte[] toJSON(Object o, int indentSize) {
+    if (o == null) return new byte[0];
+    CharArr out = new CharArr();
+    new JSONWriter(out, indentSize).write(o);
+    return toUTF8(out);
+  }
+
+  /**
+   * @param indentSize The number of space characters to use as an indent. 
0=newlines but no spaces,
+   *     -1=no indent at all.
+   */
+  public static String toJSONString(Object o, int indentSize) {
+    return new String(toJSON(o, indentSize), StandardCharsets.UTF_8);
+  }
+
   public static String toJSONString(Object o) {
     return new String(toJSON(o), StandardCharsets.UTF_8);
   }
diff --git a/solr/solrj/src/java/org/noggit/JSONWriter.java 
b/solr/solrj/src/java/org/noggit/JSONWriter.java
index 349c1fecf02..9b1dd073c83 100644
--- a/solr/solrj/src/java/org/noggit/JSONWriter.java
+++ b/solr/solrj/src/java/org/noggit/JSONWriter.java
@@ -31,6 +31,8 @@ public class JSONWriter {
     public void write(JSONWriter writer);
   }
 
+  public static final int DEFAULT_INDENT = 2;
+
   protected int level;
   protected int indent;
   protected final CharArr out;
@@ -46,7 +48,7 @@ public class JSONWriter {
   }
 
   public JSONWriter(CharArr out) {
-    this(out, 2);
+    this(out, DEFAULT_INDENT);
   }
 
   public void setIndentSize(int indentSize) {

Reply via email to