From 8102dbc8b291fe85fb66bbc0563c6c20277a7bfd Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Mon, 16 Oct 2023 08:28:00 -0500 Subject: [PATCH 1/4] Add remove method to StateProviderInterface --- .../core/state/InMemoryStateProvider.java | 11 +++++++++++ .../core/state/StateProviderInterface.java | 6 ++++++ .../core/state/TempFileStateProvider.java | 16 ++++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/state/InMemoryStateProvider.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/state/InMemoryStateProvider.java index 60fc22ed..73f54d12 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/state/InMemoryStateProvider.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/state/InMemoryStateProvider.java @@ -90,4 +90,15 @@ public class InMemoryStateProvider implements StateProviderInterface } } + + + /******************************************************************************* + ** Remove a block of data, under a key, from the state store. + *******************************************************************************/ + @Override + public void remove(AbstractStateKey key) + { + map.remove(key); + } + } diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/state/StateProviderInterface.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/state/StateProviderInterface.java index b2196746..1c5415bf 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/state/StateProviderInterface.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/state/StateProviderInterface.java @@ -52,4 +52,10 @@ public interface StateProviderInterface ** Get a block of data, under a key, from the state store. *******************************************************************************/ Optional get(Class type, AbstractStateKey key); + + /******************************************************************************* + ** Remove a block of data, under a key, from the state store. + *******************************************************************************/ + void remove(AbstractStateKey key); + } diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/state/TempFileStateProvider.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/state/TempFileStateProvider.java index b7f23768..b9f6ed5e 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/state/TempFileStateProvider.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/state/TempFileStateProvider.java @@ -30,6 +30,7 @@ import java.util.Optional; import com.kingsrook.qqq.backend.core.logging.QLogger; import com.kingsrook.qqq.backend.core.utils.JsonUtils; import org.apache.commons.io.FileUtils; +import static com.kingsrook.qqq.backend.core.logging.LogUtils.logPair; /******************************************************************************* @@ -110,6 +111,21 @@ public class TempFileStateProvider implements StateProviderInterface + /******************************************************************************* + ** Remove a block of data, under a key, from the state store. + *******************************************************************************/ + @Override + public void remove(AbstractStateKey key) + { + File file = getFile(key); + if(!file.delete()) + { + LOG.warn("Error deleting state-providing tempFile", logPair("file", file.getAbsolutePath())); + } + } + + + /******************************************************************************* ** Get the file referenced by a key *******************************************************************************/ From 017addc188db496e9597d0b9b1efb864cc3c281f Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Mon, 16 Oct 2023 08:28:08 -0500 Subject: [PATCH 2/4] Initial checkin --- .../streamedwithfrontend/NoopLoadStep.java | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/etl/streamedwithfrontend/NoopLoadStep.java diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/etl/streamedwithfrontend/NoopLoadStep.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/etl/streamedwithfrontend/NoopLoadStep.java new file mode 100644 index 00000000..c1333edf --- /dev/null +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/etl/streamedwithfrontend/NoopLoadStep.java @@ -0,0 +1,50 @@ +/* + * QQQ - Low-code Application Framework for Engineers. + * Copyright (C) 2021-2022. Kingsrook, LLC + * 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States + * contact@kingsrook.com + * https://github.com/Kingsrook/ + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package com.kingsrook.qqq.backend.core.processes.implementations.etl.streamedwithfrontend; + + +import com.kingsrook.qqq.backend.core.exceptions.QException; +import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepInput; +import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepOutput; + + +/******************************************************************************* + ** Load step that does nothing. + ** + *******************************************************************************/ +public class NoopLoadStep extends AbstractLoadStep +{ + + + /******************************************************************************* + ** Execute the backend step - using the request as input, and the result as output. + ** + *******************************************************************************/ + @Override + public void run(RunBackendStepInput runBackendStepInput, RunBackendStepOutput runBackendStepOutput) throws QException + { + /////////// + // noop. // + /////////// + } + +} From caba27448ddf16e71e04b32edd9235b8f215da56 Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Mon, 16 Oct 2023 08:56:01 -0500 Subject: [PATCH 3/4] Bypass calling String.formatted for most common case: "%s" (seen to be a hotspot in huge exports) --- .../qqq/backend/core/actions/values/QValueFormatter.java | 9 +++++++++ .../backend/core/actions/values/QValueFormatterTest.java | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/values/QValueFormatter.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/values/QValueFormatter.java index 85691e74..0a0f0161 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/values/QValueFormatter.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/values/QValueFormatter.java @@ -119,6 +119,15 @@ public class QValueFormatter //////////////////////////////////////////////////////// if(StringUtils.hasContent(displayFormat)) { + ////////////////////////////////////////////////////////////////////////////////////////// + // if the format is %s (the default), just return value a string // + // this saves some overhead incurred by String.formatted when called millions of times. // + ////////////////////////////////////////////////////////////////////////////////////////// + if(displayFormat.equals("%s")) + { + return (ValueUtils.getValueAsString(value)); + } + try { return (displayFormat.formatted(value)); diff --git a/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/actions/values/QValueFormatterTest.java b/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/actions/values/QValueFormatterTest.java index e6e783ed..52b9db39 100644 --- a/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/actions/values/QValueFormatterTest.java +++ b/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/actions/values/QValueFormatterTest.java @@ -57,6 +57,10 @@ class QValueFormatterTest extends BaseTest { assertNull(QValueFormatter.formatValue(new QFieldMetaData().withDisplayFormat(DisplayFormat.COMMAS), null)); + assertEquals("1", QValueFormatter.formatValue(new QFieldMetaData(), 1)); + assertEquals("1", QValueFormatter.formatValue(new QFieldMetaData().withDisplayFormat("%s"), 1)); + assertEquals("Hello", QValueFormatter.formatValue(new QFieldMetaData().withDisplayFormat("%s"), "Hello")); + assertEquals("1", QValueFormatter.formatValue(new QFieldMetaData().withDisplayFormat(DisplayFormat.COMMAS), 1)); assertEquals("1,000", QValueFormatter.formatValue(new QFieldMetaData().withDisplayFormat(DisplayFormat.COMMAS), 1000)); assertEquals("1000", QValueFormatter.formatValue(new QFieldMetaData().withDisplayFormat(null), 1000)); From b1c287a4e296e620a317f1e7775c2015fe5191da Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Mon, 16 Oct 2023 08:59:36 -0500 Subject: [PATCH 4/4] Moved getValueAsString call from last commit into earlier check for "%s" --- .../core/actions/values/QValueFormatter.java | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/values/QValueFormatter.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/values/QValueFormatter.java index 0a0f0161..7dc51ca4 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/values/QValueFormatter.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/values/QValueFormatter.java @@ -112,6 +112,12 @@ public class QValueFormatter { return formatLocalTime(lt); } + + ////////////////////////////////////////////////////////////////////////////////////////// + // else, just return the value as a string, rather than going through String.formatted // + // this saves some overhead incurred by String.formatted when called millions of times. // + ////////////////////////////////////////////////////////////////////////////////////////// + return (ValueUtils.getValueAsString(value)); } //////////////////////////////////////////////////////// @@ -119,15 +125,6 @@ public class QValueFormatter //////////////////////////////////////////////////////// if(StringUtils.hasContent(displayFormat)) { - ////////////////////////////////////////////////////////////////////////////////////////// - // if the format is %s (the default), just return value a string // - // this saves some overhead incurred by String.formatted when called millions of times. // - ////////////////////////////////////////////////////////////////////////////////////////// - if(displayFormat.equals("%s")) - { - return (ValueUtils.getValueAsString(value)); - } - try { return (displayFormat.formatted(value));