This is an automated email from the ASF dual-hosted git repository.
qingwzhao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/geaflow.git
The following commit(s) were added to refs/heads/master by this push:
new 2a0fd8e67 [Optimize] hard-coded optimize about cluster-constants/magic
num/temp… (#674)
2a0fd8e67 is described below
commit 2a0fd8e67a28d718841026c8a08a14e9a3b6e03e
Author: Tengting Xu <[email protected]>
AuthorDate: Tue Dec 23 14:33:07 2025 +0800
[Optimize] hard-coded optimize about cluster-constants/magic num/temp…
(#674)
* [Optimize] hard-coded optimize about cluster-constants/magic
num/template/hex array
* fix comments and add test cases
* minor fix
* fix comment 2
* fix comments 3
---
.../console/core/service/llm/LocalClient.java | 17 +--
.../geaflow/console/test/LocalClientTest.java | 132 ++++++++++++++++++
.../cluster/constants/ClusterConstantsTest.java | 74 ++++++++++
.../apache/geaflow/dsl/util/StringLiteralUtil.java | 31 ++++-
.../geaflow/dsl/util/StringLiteralUtilTest.java | 154 +++++++++++++++++++++
5 files changed, 393 insertions(+), 15 deletions(-)
diff --git
a/geaflow-console/app/core/service/src/main/java/org/apache/geaflow/console/core/service/llm/LocalClient.java
b/geaflow-console/app/core/service/src/main/java/org/apache/geaflow/console/core/service/llm/LocalClient.java
index 00e429d99..8f23d4c54 100644
---
a/geaflow-console/app/core/service/src/main/java/org/apache/geaflow/console/core/service/llm/LocalClient.java
+++
b/geaflow-console/app/core/service/src/main/java/org/apache/geaflow/console/core/service/llm/LocalClient.java
@@ -21,6 +21,7 @@ package org.apache.geaflow.console.core.service.llm;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
+import com.google.common.annotations.VisibleForTesting;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
@@ -33,16 +34,16 @@ public class LocalClient extends LLMClient {
private static final LLMClient INSTANCE = new LocalClient();
- private static final String DEFAULT_N_PREDICT = "128";
+ private static final int DEFAULT_N_PREDICT = 128;
- private static final String TEMPLATE = "{"
- + "\"prompt\": \"%s\","
- + "\"n_predict\": %s}";
-
- private String getJsonString(LocalConfigArgsClass llm, String prompt) {
+ @VisibleForTesting
+ public String getJsonString(LocalConfigArgsClass llm, String prompt) {
Integer predict = llm.getPredict();
- // trim() to replace the last \n
- return String.format(TEMPLATE, prompt.trim(), predict);
+ int nPredict = (predict != null) ? predict : DEFAULT_N_PREDICT;
+ JSONObject root = new JSONObject();
+ root.put("prompt", prompt.trim());
+ root.put("n_predict", nPredict);
+ return root.toJSONString();
}
private LocalClient() {
diff --git
a/geaflow-console/app/test/src/test/java/org/apache/geaflow/console/test/LocalClientTest.java
b/geaflow-console/app/test/src/test/java/org/apache/geaflow/console/test/LocalClientTest.java
new file mode 100644
index 000000000..5bfe8a15c
--- /dev/null
+++
b/geaflow-console/app/test/src/test/java/org/apache/geaflow/console/test/LocalClientTest.java
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.geaflow.console.test;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import org.apache.geaflow.console.core.model.llm.LocalConfigArgsClass;
+import org.apache.geaflow.console.core.service.llm.LocalClient;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+public class LocalClientTest {
+
+ @Test
+ public void testGetJsonString_WithPredictValue() {
+ LocalClient client = (LocalClient) LocalClient.getInstance();
+ LocalConfigArgsClass config = new LocalConfigArgsClass();
+ config.setPredict(256);
+
+ String prompt = "Test prompt";
+ String jsonString = client.getJsonString(config, prompt);
+
+ JSONObject json = JSON.parseObject(jsonString);
+ Assert.assertEquals(json.getString("prompt"), "Test prompt");
+ Assert.assertEquals(json.getInteger("n_predict").intValue(), 256);
+ }
+
+ @Test
+ public void testGetJsonString_WithNullPredict() {
+ LocalClient client = (LocalClient) LocalClient.getInstance();
+ LocalConfigArgsClass config = new LocalConfigArgsClass();
+ config.setPredict(null);
+
+ String prompt = "Test prompt";
+ String jsonString = client.getJsonString(config, prompt);
+
+ JSONObject json = JSON.parseObject(jsonString);
+ Assert.assertEquals(json.getString("prompt"), "Test prompt");
+ // Should use default value 128 when predict is null
+ Assert.assertEquals(json.getInteger("n_predict").intValue(), 128);
+ }
+
+ @Test
+ public void testGetJsonString_WithPromptContainingSpecialCharacters() {
+ LocalClient client = (LocalClient) LocalClient.getInstance();
+ LocalConfigArgsClass config = new LocalConfigArgsClass();
+ config.setPredict(100);
+
+ // Test with special characters that need JSON escaping
+ String prompt = "Test \"quoted\" prompt\nwith newline\tand tab";
+ String jsonString = client.getJsonString(config, prompt);
+
+ // Should be valid JSON and properly escaped
+ JSONObject json = JSON.parseObject(jsonString);
+ Assert.assertNotNull(json);
+ Assert.assertEquals(json.getInteger("n_predict").intValue(), 100);
+
+ // The prompt should be properly escaped in JSON string (check raw
JSON string)
+ // In the raw JSON string, quotes should be escaped as \"
+ Assert.assertTrue(jsonString.contains("\\\""),
+ "JSON string should contain escaped quotes");
+
+ // Verify the parsed prompt matches the original (special characters
preserved)
+ String parsedPrompt = json.getString("prompt");
+ Assert.assertNotNull(parsedPrompt);
+ Assert.assertEquals(parsedPrompt, prompt,
+ "Parsed prompt should match original prompt with special
characters");
+ }
+
+ @Test
+ public void testGetJsonString_WithPromptTrim() {
+ LocalClient client = (LocalClient) LocalClient.getInstance();
+ LocalConfigArgsClass config = new LocalConfigArgsClass();
+ config.setPredict(200);
+
+ // Test with trailing newline that should be trimmed
+ String prompt = "Test prompt\n";
+ String jsonString = client.getJsonString(config, prompt);
+
+ JSONObject json = JSON.parseObject(jsonString);
+ Assert.assertEquals(json.getString("prompt"), "Test prompt");
+ Assert.assertEquals(json.getInteger("n_predict").intValue(), 200);
+ }
+
+ @Test
+ public void testGetJsonString_WithZeroPredict() {
+ LocalClient client = (LocalClient) LocalClient.getInstance();
+ LocalConfigArgsClass config = new LocalConfigArgsClass();
+ config.setPredict(0);
+
+ String prompt = "Test prompt";
+ String jsonString = client.getJsonString(config, prompt);
+
+ JSONObject json = JSON.parseObject(jsonString);
+ Assert.assertEquals(json.getString("prompt"), "Test prompt");
+ Assert.assertEquals(json.getInteger("n_predict").intValue(), 0);
+ }
+
+ @Test
+ public void testGetJsonString_JsonStructure() {
+ LocalClient client = (LocalClient) LocalClient.getInstance();
+ LocalConfigArgsClass config = new LocalConfigArgsClass();
+ config.setPredict(128);
+
+ String prompt = "Test";
+ String jsonString = client.getJsonString(config, prompt);
+
+ // Verify JSON structure
+ JSONObject json = JSON.parseObject(jsonString);
+ Assert.assertTrue(json.containsKey("prompt"));
+ Assert.assertTrue(json.containsKey("n_predict"));
+ Assert.assertEquals(json.size(), 2); // Should only have these two
fields
+ }
+}
+
diff --git
a/geaflow/geaflow-core/geaflow-engine/geaflow-cluster/src/test/java/org/apache/geaflow/cluster/constants/ClusterConstantsTest.java
b/geaflow/geaflow-core/geaflow-engine/geaflow-cluster/src/test/java/org/apache/geaflow/cluster/constants/ClusterConstantsTest.java
new file mode 100644
index 000000000..1bc2cfad1
--- /dev/null
+++
b/geaflow/geaflow-core/geaflow-engine/geaflow-cluster/src/test/java/org/apache/geaflow/cluster/constants/ClusterConstantsTest.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.geaflow.cluster.constants;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+public class ClusterConstantsTest {
+
+ @Test
+ public void testDefaultValues() {
+ // Test default values
+ Assert.assertEquals(ClusterConstants.getMasterName(), "master-0");
+ Assert.assertEquals(ClusterConstants.getDriverName(1), "driver-1");
+ Assert.assertEquals(ClusterConstants.getContainerName(2),
"container-2");
+
+ Assert.assertEquals(ClusterConstants.MASTER_LOG_SUFFIX, "master.log");
+ Assert.assertEquals(ClusterConstants.DRIVER_LOG_SUFFIX, "driver.log");
+ Assert.assertEquals(ClusterConstants.CONTAINER_LOG_SUFFIX,
"container.log");
+
+ Assert.assertEquals(ClusterConstants.DEFAULT_MASTER_ID, 0);
+ }
+
+ @Test
+ public void testGetMasterName() {
+ String masterName = ClusterConstants.getMasterName();
+ Assert.assertEquals(masterName, "master-0");
+ }
+
+ @Test
+ public void testGetDriverName() {
+ Assert.assertEquals(ClusterConstants.getDriverName(0), "driver-0");
+ Assert.assertEquals(ClusterConstants.getDriverName(1), "driver-1");
+ Assert.assertEquals(ClusterConstants.getDriverName(10), "driver-10");
+ }
+
+ @Test
+ public void testGetContainerName() {
+ Assert.assertEquals(ClusterConstants.getContainerName(0),
"container-0");
+ Assert.assertEquals(ClusterConstants.getContainerName(1),
"container-1");
+ Assert.assertEquals(ClusterConstants.getContainerName(100),
"container-100");
+ }
+
+ @Test
+ public void testConstants() {
+ // Test all constants are properly defined
+ Assert.assertNotNull(ClusterConstants.MASTER_LOG_SUFFIX);
+ Assert.assertNotNull(ClusterConstants.DRIVER_LOG_SUFFIX);
+ Assert.assertNotNull(ClusterConstants.CONTAINER_LOG_SUFFIX);
+ Assert.assertNotNull(ClusterConstants.CLUSTER_TYPE);
+ Assert.assertNotNull(ClusterConstants.LOCAL_CLUSTER);
+ Assert.assertNotNull(ClusterConstants.MASTER_ID);
+ Assert.assertNotNull(ClusterConstants.CONTAINER_ID);
+ Assert.assertNotNull(ClusterConstants.CONTAINER_INDEX);
+ }
+}
+
diff --git
a/geaflow/geaflow-dsl/geaflow-dsl-parser/src/main/java/org/apache/geaflow/dsl/util/StringLiteralUtil.java
b/geaflow/geaflow-dsl/geaflow-dsl-parser/src/main/java/org/apache/geaflow/dsl/util/StringLiteralUtil.java
index 52122fe10..9f564758e 100644
---
a/geaflow/geaflow-dsl/geaflow-dsl-parser/src/main/java/org/apache/geaflow/dsl/util/StringLiteralUtil.java
+++
b/geaflow/geaflow-dsl/geaflow-dsl-parser/src/main/java/org/apache/geaflow/dsl/util/StringLiteralUtil.java
@@ -24,7 +24,8 @@ import org.apache.calcite.sql.SqlNode;
public class StringLiteralUtil {
- private static final int[] multiplier = new int[]{1000, 100, 10, 1};
+ // Unicode escape sequence hex weights: 16^3, 16^2, 16^1, 16^0 = 4096,
256, 16, 1
+ private static final int[] UNICODE_HEX_MULTIPLIER = new int[]{4096, 256,
16, 1};
public static String unescapeSQLString(String b) {
@@ -51,17 +52,33 @@ public class StringLiteralUtil {
}
- if (currentChar == '\\' && (i + 6 < b.length()) && b.charAt(i + 1)
== 'u') {
+ // Process Unicode escape sequence (backslash-u followed by 4 hex
digits)
+ // Need at least 6 characters: backslash-u + 4 hex digits
+ if (currentChar == '\\' && (i + 6 <= b.length()) && b.charAt(i +
1) == 'u') {
int code = 0;
int base = i + 2;
+ boolean validHex = true;
+
+ // Parse 4 hexadecimal digits with correct weights (16^3,
16^2, 16^1, 16^0)
for (int j = 0; j < 4; j++) {
int digit = Character.digit(b.charAt(j + base), 16);
- code += digit * multiplier[j];
+ if (digit < 0) {
+ // Invalid hex character encountered
+ validHex = false;
+ break;
+ }
+ code += digit * UNICODE_HEX_MULTIPLIER[j];
}
- sb.append((char) code);
- i += 5;
- continue;
- } else if (currentChar == '\\') { // process case for '\001'
+
+ if (validHex) {
+ sb.append((char) code);
+ i += 5; // Skip backslash-u-XXXX (5 characters total)
+ continue;
+ }
+ // If invalid hex, fall through to handle as regular backslash
escape
+ }
+
+ if (currentChar == '\\') { // process case for '\001'
int code = 0;
int base = i + 1;
int j;
diff --git
a/geaflow/geaflow-dsl/geaflow-dsl-parser/src/test/java/org/apache/geaflow/dsl/util/StringLiteralUtilTest.java
b/geaflow/geaflow-dsl/geaflow-dsl-parser/src/test/java/org/apache/geaflow/dsl/util/StringLiteralUtilTest.java
new file mode 100644
index 000000000..15669ef5b
--- /dev/null
+++
b/geaflow/geaflow-dsl/geaflow-dsl-parser/src/test/java/org/apache/geaflow/dsl/util/StringLiteralUtilTest.java
@@ -0,0 +1,154 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.geaflow.dsl.util;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+public class StringLiteralUtilTest {
+
+ @Test
+ public void testUnicodeEscapeSequence_Basic() {
+ // Test \u0041 => "A"
+ String input = "\"\\u0041\"";
+ String result = StringLiteralUtil.unescapeSQLString(input);
+ Assert.assertEquals(result, "A");
+ }
+
+ @Test
+ public void testUnicodeEscapeSequence_AccentedCharacter() {
+ // Test \u00e9 => "é"
+ String input = "\"\\u00e9\"";
+ String result = StringLiteralUtil.unescapeSQLString(input);
+ Assert.assertEquals(result, "é");
+ }
+
+ @Test
+ public void testUnicodeEscapeSequence_MultipleUnicode() {
+ // Test multiple Unicode characters
+ String input = "\"\\u0048\\u0065\\u006c\\u006c\\u006f\"";
+ String result = StringLiteralUtil.unescapeSQLString(input);
+ Assert.assertEquals(result, "Hello");
+ }
+
+ @Test
+ public void testUnicodeEscapeSequence_ChineseCharacter() {
+ // Test Chinese character \u4e2d => "中"
+ String input = "\"\\u4e2d\"";
+ String result = StringLiteralUtil.unescapeSQLString(input);
+ Assert.assertEquals(result, "中");
+ }
+
+ @Test
+ public void testUnicodeEscapeSequence_UpperCaseHex() {
+ // Test uppercase hex digits
+ String input = "\"\\u00FF\"";
+ String result = StringLiteralUtil.unescapeSQLString(input);
+ Assert.assertEquals(result, "\u00FF");
+ }
+
+ @Test
+ public void testUnicodeEscapeSequence_LowerCaseHex() {
+ // Test lowercase hex digits
+ String input = "\"\\u00ff\"";
+ String result = StringLiteralUtil.unescapeSQLString(input);
+ Assert.assertEquals(result, "\u00FF");
+ }
+
+ @Test
+ public void testUnicodeEscapeSequence_InvalidHexCharacter() {
+ // Test invalid hex character (should fall back to regular escape
handling)
+ String input = "\"\\u00g1\"";
+ String result = StringLiteralUtil.unescapeSQLString(input);
+ // Should not crash and should handle gracefully
+ Assert.assertNotNull(result);
+ }
+
+ @Test
+ public void testUnicodeEscapeSequence_IncompleteSequence() {
+ // Test incomplete sequence (less than 4 hex digits)
+ String input = "\"\\u00a\"";
+ String result = StringLiteralUtil.unescapeSQLString(input);
+ // Should handle gracefully without crashing
+ Assert.assertNotNull(result);
+ }
+
+ @Test
+ public void testCommonEscapeSequences() {
+ // Test common escape sequences
+ String input = "\"\\n\\t\\r\\b\"";
+ String result = StringLiteralUtil.unescapeSQLString(input);
+ Assert.assertEquals(result, "\n\t\r\b");
+ }
+
+ @Test
+ public void testMixedEscapeSequences() {
+ // Test mixing Unicode and common escape sequences
+ String input = "\"Hello\\u0020World\\n\"";
+ String result = StringLiteralUtil.unescapeSQLString(input);
+ Assert.assertEquals(result, "Hello World\n");
+ }
+
+ @Test
+ public void testUnicodeEscapeSequence_MaxValue() {
+ // Test maximum Unicode value \uFFFF
+ String input = "\"\\uFFFF\"";
+ String result = StringLiteralUtil.unescapeSQLString(input);
+ Assert.assertEquals(result, "\uFFFF");
+ }
+
+ @Test
+ public void testUnicodeEscapeSequence_ZeroValue() {
+ // Test zero value \u0000
+ String input = "\"\\u0000\"";
+ String result = StringLiteralUtil.unescapeSQLString(input);
+ Assert.assertEquals(result, "\u0000");
+ }
+
+ @Test
+ public void testUnicodeEscapeSequence_WithQuotes() {
+ // Test with single quotes enclosure
+ String input = "'\\u0041'";
+ String result = StringLiteralUtil.unescapeSQLString(input);
+ Assert.assertEquals(result, "A");
+ }
+
+ @Test
+ public void testEscapeSQLString_Basic() {
+ // Test escapeSQLString method
+ String input = "Hello\nWorld";
+ String result = StringLiteralUtil.escapeSQLString(input);
+ Assert.assertTrue(result.startsWith("'"));
+ Assert.assertTrue(result.endsWith("'"));
+ Assert.assertTrue(result.contains("\\n"));
+ }
+
+ @Test
+ public void testEscapeSQLString_WithUnicode() {
+ // Test escapeSQLString with Unicode characters
+ String input = "A";
+ String result = StringLiteralUtil.escapeSQLString(input);
+ // Should be properly escaped
+ Assert.assertNotNull(result);
+ Assert.assertTrue(result.startsWith("'"));
+ Assert.assertTrue(result.endsWith("'"));
+ }
+}
+
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]