moving to tiny map instead of LinkedHashMap because of memory hogging, update to gradle 6.6.1

This commit is contained in:
Jörg Prante 2020-09-12 23:24:42 +02:00
parent 7fb5d52466
commit 2e19c8829a
16 changed files with 75 additions and 59 deletions

View file

@ -55,13 +55,15 @@ public class ConfigLoader {
return settings; return settings;
} }
} }
throw new IllegalArgumentException("no config found for " + applicationName + " "+ Arrays.asList(fileNamesWithoutSuffix)); throw new IllegalArgumentException("no config found for " + applicationName + " " +
Arrays.asList(fileNamesWithoutSuffix));
} }
private Settings.Builder createClasspathSettings(ClassLoader classLoader, String applicationName, String fileNameWithoutSuffix) private Settings.Builder createClasspathSettings(ClassLoader classLoader, String applicationName, String fileNameWithoutSuffix)
throws IOException { throws IOException {
for (String suffix : List.of(YML, YAML, JSON)) { for (String suffix : List.of(YML, YAML, JSON)) {
InputStream inputStream = classLoader.getResourceAsStream(applicationName + '-' + fileNameWithoutSuffix + suffix); InputStream inputStream = classLoader.getResourceAsStream(applicationName + '-' +
fileNameWithoutSuffix + suffix);
if (inputStream != null) { if (inputStream != null) {
logger.info("found resource: " + applicationName + '-' + fileNameWithoutSuffix + suffix); logger.info("found resource: " + applicationName + '-' + fileNameWithoutSuffix + suffix);
Settings.Builder settings = createSettingsFromStream(inputStream, suffix); Settings.Builder settings = createSettingsFromStream(inputStream, suffix);

View file

@ -0,0 +1,4 @@
/**
* Classes for configurations.
*/
package org.xbib.content.config;

View file

@ -1,3 +1,4 @@
dependencies { dependencies {
api "com.fasterxml.jackson.core:jackson-core:${project.property('jackson.version')}" api "com.fasterxml.jackson.core:jackson-core:${project.property('jackson.version')}"
api "org.xbib:datastructures-tiny:${project.property('xbib-datastructures-tiny.version')}"
} }

View file

@ -5,6 +5,7 @@ module org.xbib.content.core {
exports org.xbib.content.settings; exports org.xbib.content.settings;
exports org.xbib.content.util.geo; exports org.xbib.content.util.geo;
exports org.xbib.content.util.unit; exports org.xbib.content.util.unit;
requires org.xbib.datastructures.tiny;
requires transitive com.fasterxml.jackson.core; requires transitive com.fasterxml.jackson.core;
provides org.xbib.content.XContent with provides org.xbib.content.XContent with
org.xbib.content.json.JsonXContent; org.xbib.content.json.JsonXContent;

View file

@ -1,9 +1,9 @@
package org.xbib.content; package org.xbib.content;
import org.xbib.datastructures.tiny.TinyMap;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -13,8 +13,11 @@ import java.util.Map;
public abstract class AbstractXContentParser implements XContentParser { public abstract class AbstractXContentParser implements XContentParser {
private static final MapFactory SIMPLE_MAP_FACTORY = HashMap::new; private static final MapFactory SIMPLE_MAP_FACTORY = HashMap::new;
private static final MapFactory ORDERED_MAP_FACTORY = LinkedHashMap::new;
private static final MapFactory TINY_MAP_FACTORY = TinyMap::builder;
private boolean losslessDecimals; private boolean losslessDecimals;
private boolean base16Checks; private boolean base16Checks;
private static Map<String, Object> readMap(XContentParser parser) throws IOException { private static Map<String, Object> readMap(XContentParser parser) throws IOException {
@ -22,7 +25,7 @@ public abstract class AbstractXContentParser implements XContentParser {
} }
private static Map<String, Object> readOrderedMap(XContentParser parser) throws IOException { private static Map<String, Object> readOrderedMap(XContentParser parser) throws IOException {
return readMap(parser, ORDERED_MAP_FACTORY); return readMap(parser, TINY_MAP_FACTORY);
} }
private static Map<String, Object> readMap(XContentParser parser, MapFactory mapFactory) throws IOException { private static Map<String, Object> readMap(XContentParser parser, MapFactory mapFactory) throws IOException {

View file

@ -6,16 +6,15 @@ import org.xbib.content.XContentGenerator;
import org.xbib.content.XContentParser; import org.xbib.content.XContentParser;
import org.xbib.content.io.BytesReference; import org.xbib.content.io.BytesReference;
import org.xbib.content.io.BytesStreamOutput; import org.xbib.content.io.BytesStreamOutput;
import org.xbib.datastructures.tiny.TinyMap;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
* Settings loader that loads (parses) the settings in a XContent format by flattening them * Settings loader that loads (parses) the settings in a XContent format
* into a map. * by flattening them into a map.
*/ */
public abstract class AbstractSettingsLoader implements SettingsLoader { public abstract class AbstractSettingsLoader implements SettingsLoader {
@ -43,14 +42,14 @@ public abstract class AbstractSettingsLoader implements SettingsLoader {
public Map<String, String> load(XContentParser xContentParser) throws IOException { public Map<String, String> load(XContentParser xContentParser) throws IOException {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
Map<String, String> map = new LinkedHashMap<>(); TinyMap.Builder<String, String> map = TinyMap.builder();
List<String> path = new ArrayList<>(); List<String> path = new ArrayList<>();
XContentParser.Token token = xContentParser.nextToken(); XContentParser.Token token = xContentParser.nextToken();
if (token == null) { if (token == null) {
return map; return map.build();
} }
parseObject(map, sb, path, xContentParser, null); parseObject(map, sb, path, xContentParser, null);
return map; return map.build();
} }
public String flatMapAsString(BytesReference bytesReference) throws IOException { public String flatMapAsString(BytesReference bytesReference) throws IOException {

View file

@ -2,11 +2,10 @@ package org.xbib.content.settings;
import static org.xbib.content.util.unit.ByteSizeValue.parseBytesSizeValue; import static org.xbib.content.util.unit.ByteSizeValue.parseBytesSizeValue;
import static org.xbib.content.util.unit.TimeValue.parseTimeValue; import static org.xbib.content.util.unit.TimeValue.parseTimeValue;
import org.xbib.content.json.JsonSettingsLoader; import org.xbib.content.json.JsonSettingsLoader;
import org.xbib.datastructures.tiny.TinyMap;
import org.xbib.content.util.unit.ByteSizeValue; import org.xbib.content.util.unit.ByteSizeValue;
import org.xbib.content.util.unit.TimeValue; import org.xbib.content.util.unit.TimeValue;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
@ -21,9 +20,6 @@ import java.time.DateTimeException;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
@ -51,13 +47,15 @@ public class Settings implements AutoCloseable {
} }
private Settings(Map<String, String> map, Path path, long initialDelay, long period, TimeUnit timeUnit) { private Settings(Map<String, String> map, Path path, long initialDelay, long period, TimeUnit timeUnit) {
this.map = new LinkedHashMap<>(map); TinyMap.Builder<String, String> builder = TinyMap.builder();
builder.putAll(map);
this.map = builder.build();
if (path != null && initialDelay >= 0L && period > 0L) { if (path != null && initialDelay >= 0L && period > 0L) {
this.refresher = new DefaultSettingsRefresher(path, initialDelay, period, timeUnit); this.refresher = new DefaultSettingsRefresher(path, initialDelay, period, timeUnit);
} }
} }
public static Settings readSettingsFromMap(Map<String, Object> map) throws IOException { public static Settings readSettingsFromMap(Map<String, Object> map) {
Builder builder = new Builder(); Builder builder = new Builder();
for (Map.Entry<String, Object> entry : map.entrySet()) { for (Map.Entry<String, Object> entry : map.entrySet()) {
builder.put(entry.getKey(), entry.getValue() != null ? entry.getValue().toString() : null); builder.put(entry.getKey(), entry.getValue() != null ? entry.getValue().toString() : null);
@ -65,7 +63,7 @@ public class Settings implements AutoCloseable {
return builder.build(); return builder.build();
} }
public static void writeSettingsToMap(Settings settings, Map<String, Object> map) throws IOException { public static void writeSettingsToMap(Settings settings, Map<String, Object> map) {
for (String key : settings.getAsMap().keySet()) { for (String key : settings.getAsMap().keySet()) {
map.put(key, settings.get(key)); map.put(key, settings.get(key));
} }
@ -145,7 +143,7 @@ public class Settings implements AutoCloseable {
} }
public Map<String, Object> getAsStructuredMap() { public Map<String, Object> getAsStructuredMap() {
Map<String, Object> stringObjectMap = new HashMap<>(2); TinyMap.Builder<String, Object> stringObjectMap = TinyMap.builder();
for (Map.Entry<String, String> entry : this.map.entrySet()) { for (Map.Entry<String, String> entry : this.map.entrySet()) {
processSetting(stringObjectMap, "", entry.getKey(), entry.getValue()); processSetting(stringObjectMap, "", entry.getKey(), entry.getValue());
} }
@ -156,7 +154,7 @@ public class Settings implements AutoCloseable {
entry.setValue(convertMapsToArrays(valMap)); entry.setValue(convertMapsToArrays(valMap));
} }
} }
return stringObjectMap; return stringObjectMap.build();
} }
public Settings getByPrefix(String prefix) { public Settings getByPrefix(String prefix) {
@ -295,7 +293,7 @@ public class Settings implements AutoCloseable {
settingPrefix = settingPrefix + "."; settingPrefix = settingPrefix + ".";
} }
// we don't really care that it might happen twice // we don't really care that it might happen twice
Map<String, Map<String, String>> hashMap = new LinkedHashMap<>(); TinyMap.Builder<String, Map<String, String>> hashMap = TinyMap.builder();
for (Object o : this.map.keySet()) { for (Object o : this.map.keySet()) {
String setting = (String) o; String setting = (String) o;
if (setting.startsWith(settingPrefix)) { if (setting.startsWith(settingPrefix)) {
@ -308,15 +306,15 @@ public class Settings implements AutoCloseable {
} }
String name = nameValue.substring(0, dotIndex); String name = nameValue.substring(0, dotIndex);
String value = nameValue.substring(dotIndex + 1); String value = nameValue.substring(dotIndex + 1);
Map<String, String> groupSettings = hashMap.computeIfAbsent(name, k -> new LinkedHashMap<>()); Map<String, String> groupSettings = hashMap.computeIfAbsent(name, k -> TinyMap.builder());
groupSettings.put(value, get(setting)); groupSettings.put(value, get(setting));
} }
} }
Map<String, Settings> retVal = new LinkedHashMap<>(); TinyMap.Builder<String, Settings> retVal = TinyMap.builder();
for (Map.Entry<String, Map<String, String>> entry : hashMap.entrySet()) { for (Map.Entry<String, Map<String, String>> entry : hashMap.entrySet()) {
retVal.put(entry.getKey(), new Settings(Collections.unmodifiableMap(entry.getValue()))); retVal.put(entry.getKey(), new Settings(entry.getValue()));
} }
return Collections.unmodifiableMap(retVal); return retVal.build();
} }
@Override @Override
@ -345,7 +343,7 @@ public class Settings implements AutoCloseable {
String rest = setting.substring(prefixLength + 1); String rest = setting.substring(prefixLength + 1);
Object existingValue = map.get(prefix + key); Object existingValue = map.get(prefix + key);
if (existingValue == null) { if (existingValue == null) {
Map<String, Object> newMap = new HashMap<>(2); Map<String, Object> newMap = TinyMap.builder();
processSetting(newMap, "", rest, value); processSetting(newMap, "", rest, value);
map.put(key, newMap); map.put(key, newMap);
} else { } else {
@ -412,7 +410,7 @@ public class Settings implements AutoCloseable {
*/ */
public static class Builder { public static class Builder {
private final Map<String, String> map = new LinkedHashMap<>(); private final Map<String, String> map;
private Path path; private Path path;
@ -423,10 +421,7 @@ public class Settings implements AutoCloseable {
private TimeUnit timeUnit; private TimeUnit timeUnit;
private Builder() { private Builder() {
} map = TinyMap.builder();
public Map<String, String> internalMap() {
return this.map;
} }
public String remove(String key) { public String remove(String key) {

View file

@ -0,0 +1,25 @@
package org.xbib.content;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
import org.xbib.content.json.JsonXContent;
import java.io.IOException;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
public class XContentParserTest {
private static final Logger logger = Logger.getLogger(XContentParserTest.class.getName());
@Test
public void simpleParse() throws IOException {
XContentParser parser = JsonXContent.jsonContent().createParser("{\"a\":1,\"b\":2,\"c\":3}");
Map<String, Object> map = parser.mapOrderedAndClose();
logger.log(Level.INFO, map.getClass().getName().toString());
assertEquals("{a=1, b=2, c=3}", map.toString());
parser = JsonXContent.jsonContent().createParser("{\"a\":1,\"b\":2,\"c\":3}");
map = parser.mapAndClose();
logger.log(Level.INFO, map.getClass().getName().toString());
}
}

View file

@ -2,7 +2,6 @@ package org.xbib.content.settings;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.xbib.content.XContentHelper; import org.xbib.content.XContentHelper;
@ -10,7 +9,6 @@ import org.xbib.content.io.BytesArray;
import org.xbib.content.io.BytesReference; import org.xbib.content.io.BytesReference;
import org.xbib.content.json.JsonSettingsLoader; import org.xbib.content.json.JsonSettingsLoader;
import org.xbib.content.json.JsonXContent; import org.xbib.content.json.JsonXContent;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.StringReader; import java.io.StringReader;
@ -60,7 +58,7 @@ public class SettingsTest {
for (Map.Entry<String, Object> entry : map.entrySet()) { for (Map.Entry<String, Object> entry : map.entrySet()) {
list.add((Map<String, Object>) entry.getValue()); list.add((Map<String, Object>) entry.getValue());
} }
assertEquals("[{name=Name 0, code=Code 0}, {name=Name 1, code=Code 1}]", list.toString()); assertEquals("[{code=Code 0, name=Name 0}, {code=Code 1, name=Name 1}]", list.toString());
} }
@Test @Test

View file

@ -0,0 +1,2 @@
public class YamlTest {
}

View file

@ -1,12 +1,13 @@
group = org.xbib group = org.xbib
name = content name = content
version = 2.4.0 version = 2.5.0
gradle.wrapper.version = 6.4.1 gradle.wrapper.version = 6.6.1
xbib.net.version = 2.1.0 xbib.net.version = 2.1.0
jackson.version = 2.11.1 jackson.version = 2.11.1
jackson.databind.version = 2.11.1 jackson.databind.version = 2.11.1
woodstox.version = 6.2.1 woodstox.version = 6.2.1
snakeyaml.version = 1.26 snakeyaml.version = 1.26
xbib-datastructures-tiny.version = 0.0.1
mockito.version = 3.3.3 mockito.version = 3.3.3
asciidoclet.version = 1.5.6 asciidoclet.version = 1.5.6

View file

@ -11,7 +11,7 @@ dependencies {
test { test {
useJUnitPlatform() useJUnitPlatform()
failFast = true failFast = false
testLogging { testLogging {
events 'STARTED', 'PASSED', 'FAILED', 'SKIPPED' events 'STARTED', 'PASSED', 'FAILED', 'SKIPPED'
} }

Binary file not shown.

View file

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.4.1-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-all.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

21
gradlew.bat vendored
View file

@ -40,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1 %JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init if "%ERRORLEVEL%" == "0" goto execute
echo. echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@ -54,7 +54,7 @@ goto fail
set JAVA_HOME=%JAVA_HOME:"=% set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init if exist "%JAVA_EXE%" goto execute
echo. echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@ -64,21 +64,6 @@ echo location of your Java installation.
goto fail goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute :execute
@rem Setup the command line @rem Setup the command line
@ -86,7 +71,7 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle @rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end :end
@rem End local scope for the variables with windows NT shell @rem End local scope for the variables with windows NT shell