You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by li...@apache.org on 2022/06/13 06:23:34 UTC
[dubbo] branch 3.0 updated: [3.0] Improve compressed URL param performance (#10125)
This is an automated email from the ASF dual-hosted git repository.
liujun pushed a commit to branch 3.0
in repository https://gitbox.apache.org/repos/asf/dubbo.git
The following commit(s) were added to refs/heads/3.0 by this push:
new 67e36cdd27 [3.0] Improve compressed URL param performance (#10125)
67e36cdd27 is described below
commit 67e36cdd27b9ae988c1d0d50a459545be07387b1
Author: Albumen Kevin <jh...@gmail.com>
AuthorDate: Mon Jun 13 14:23:27 2022 +0800
[3.0] Improve compressed URL param performance (#10125)
---
.../dubbo/common/url/component/URLParam.java | 211 +++++++--------------
.../dubbo/common/url/component/URLPlainParam.java | 6 +-
.../url/component/param/DynamicParamTable.java | 77 +++++---
.../common/url/component/param/DynamicValues.java | 28 ++-
.../url/component/param/FixedParamValue.java | 9 +-
.../common/url/component/param/ParamValue.java | 11 +-
6 files changed, 136 insertions(+), 206 deletions(-)
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/url/component/URLParam.java b/dubbo-common/src/main/java/org/apache/dubbo/common/url/component/URLParam.java
index 01434ac8e4..05deabe572 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/url/component/URLParam.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/url/component/URLParam.java
@@ -49,10 +49,11 @@ import static org.apache.dubbo.common.constants.CommonConstants.TIMESTAMP_KEY;
* <br/>
* URLParam should operate as Copy-On-Write, each modify actions will return a new Object
* <br/>
- *
+ * <p>
* NOTE: URLParam is not support serialization! {@link DynamicParamTable} is related with
* current running environment. If you want to make URL as a parameter, please call
* {@link URL#toSerializableURL()} to create {@link URLPlainParam} instead.
+ *
* @since 3.0
*/
public class URLParam {
@@ -77,14 +78,9 @@ public class URLParam {
private final BitSet KEY;
/**
- * using bit to save if value is default value (reduce VALUE size)
- */
- private final BitSet DEFAULT_KEY;
-
- /**
- * a compressed (those key not exist or value is default value are bring removed in this array) array which contains value-offset
+ * an array which contains value-offset
*/
- private final Integer[] VALUE;
+ private final int[] VALUE;
/**
* store extra parameters which key not match in {@link DynamicParamTable}
@@ -115,7 +111,6 @@ public class URLParam {
protected URLParam() {
this.rawParam = null;
this.KEY = null;
- this.DEFAULT_KEY = null;
this.VALUE = null;
this.EXTRA_PARAMS = null;
this.METHOD_PARAMETERS = null;
@@ -124,18 +119,14 @@ public class URLParam {
protected URLParam(BitSet key, Map<Integer, Integer> value, Map<String, String> extraParams, Map<String, Map<String, String>> methodParameters, String rawParam) {
this.KEY = key;
- this.DEFAULT_KEY = new BitSet(KEY.size());
- this.VALUE = new Integer[value.size()];
-
- // compress VALUE
+ this.VALUE = new int[value.size()];
for (int i = key.nextSetBit(0), offset = 0; i >= 0; i = key.nextSetBit(i + 1)) {
if (value.containsKey(i)) {
VALUE[offset++] = value.get(i);
} else {
- DEFAULT_KEY.set(i);
+ throw new IllegalArgumentException();
}
}
-
this.EXTRA_PARAMS = Collections.unmodifiableMap((extraParams == null ? new HashMap<>() : new HashMap<>(extraParams)));
this.METHOD_PARAMETERS = Collections.unmodifiableMap((methodParameters == null) ? Collections.emptyMap() : new LinkedHashMap<>(methodParameters));
this.rawParam = rawParam;
@@ -144,16 +135,12 @@ public class URLParam {
this.enableCompressed = true;
}
- protected URLParam(BitSet key, BitSet defaultKey, Integer[] value, Map<String, String> extraParams, Map<String, Map<String, String>> methodParameters, String rawParam) {
+ protected URLParam(BitSet key, int[] value, Map<String, String> extraParams, Map<String, Map<String, String>> methodParameters, String rawParam) {
this.KEY = key;
- this.DEFAULT_KEY = defaultKey;
-
this.VALUE = value;
-
this.EXTRA_PARAMS = Collections.unmodifiableMap((extraParams == null ? new HashMap<>() : new HashMap<>(extraParams)));
this.METHOD_PARAMETERS = Collections.unmodifiableMap((methodParameters == null) ? Collections.emptyMap() : new LinkedHashMap<>(methodParameters));
this.rawParam = rawParam;
-
this.timestamp = System.currentTimeMillis();
this.enableCompressed = true;
}
@@ -387,12 +374,8 @@ public class URLParam {
Set<String> set = new LinkedHashSet<>((int) ((urlParam.VALUE.length + urlParam.EXTRA_PARAMS.size()) / 0.75) + 1);
for (int i = urlParam.KEY.nextSetBit(0); i >= 0; i = urlParam.KEY.nextSetBit(i + 1)) {
String value;
- if (urlParam.DEFAULT_KEY.get(i)) {
- value = DynamicParamTable.getDefaultValue(i);
- } else {
- Integer offset = urlParam.keyIndexToOffset(i);
- value = DynamicParamTable.getValue(i, offset);
- }
+ int offset = urlParam.keyIndexToOffset(i);
+ value = DynamicParamTable.getValue(i, offset);
set.add(value);
}
@@ -407,12 +390,8 @@ public class URLParam {
Set<Entry<String, String>> set = new LinkedHashSet<>((int) ((urlParam.KEY.cardinality() + urlParam.EXTRA_PARAMS.size()) / 0.75) + 1);
for (int i = urlParam.KEY.nextSetBit(0); i >= 0; i = urlParam.KEY.nextSetBit(i + 1)) {
String value;
- if (urlParam.DEFAULT_KEY.get(i)) {
- value = DynamicParamTable.getDefaultValue(i);
- } else {
- Integer offset = urlParam.keyIndexToOffset(i);
- value = DynamicParamTable.getValue(i, offset);
- }
+ int offset = urlParam.keyIndexToOffset(i);
+ value = DynamicParamTable.getValue(i, offset);
set.add(new Node(DynamicParamTable.getKey(i), value));
}
@@ -561,8 +540,7 @@ public class URLParam {
private URLParam doAddParameters(Map<String, String> parameters, boolean skipIfPresent) {
// lazy init, null if no modify
BitSet newKey = null;
- BitSet defaultKey = null;
- Integer[] newValueArray = null;
+ int[] newValueArray = null;
Map<Integer, Integer> newValueMap = null;
Map<String, String> newExtraParams = null;
Map<String, Map<String, String>> newMethodParams = null;
@@ -573,8 +551,8 @@ public class URLParam {
if (entry.getKey() == null || entry.getValue() == null) {
continue;
}
- Integer keyIndex = DynamicParamTable.getKeyIndex(enableCompressed, entry.getKey());
- if (keyIndex == null) {
+ int keyIndex = DynamicParamTable.getKeyIndex(enableCompressed, entry.getKey());
+ if (keyIndex < 0) {
// entry key is not present in DynamicParamTable, add it to EXTRA_PARAMS
if (newExtraParams == null) {
newExtraParams = new HashMap<>(EXTRA_PARAMS);
@@ -594,29 +572,11 @@ public class URLParam {
if (parameters.size() > ADD_PARAMETER_ON_MOVE_THRESHOLD) {
// recover VALUE back to Map, use map to replace key pair
if (newValueMap == null) {
- newValueMap = recoverCompressedValue();
+ newValueMap = recoverValue();
}
newValueMap.put(keyIndex, DynamicParamTable.getValueIndex(entry.getKey(), entry.getValue()));
- } else if (!DynamicParamTable.isDefaultValue(entry.getKey(), entry.getValue())) {
- // new value is not the default key
- if (DEFAULT_KEY.get(keyIndex)) {
- // old value is the default value
- // value is default value, add to defaultKey directly
- if (defaultKey == null) {
- defaultKey = (BitSet) DEFAULT_KEY.clone();
- }
- defaultKey.set(keyIndex, false);
- newValueArray = addByMove(VALUE, keyIndexToCompressIndex(KEY, DEFAULT_KEY, keyIndex), DynamicParamTable.getValueIndex(entry.getKey(), entry.getValue()));
- } else {
- // old value is not the default key, replace offset in VALUE array
- newValueArray = replaceOffset(VALUE, keyIndexToCompressIndex(KEY, DEFAULT_KEY, keyIndex), DynamicParamTable.getValueIndex(entry.getKey(), entry.getValue()));
- }
} else {
- // value is default value, add to defaultKey directly
- if (defaultKey == null) {
- defaultKey = (BitSet) DEFAULT_KEY.clone();
- }
- defaultKey.set(keyIndex);
+ newValueArray = replaceOffset(VALUE, keyIndexToIndex(KEY, keyIndex), DynamicParamTable.getValueIndex(entry.getKey(), entry.getValue()));
}
} else {
// key is absent, add it
@@ -628,18 +588,12 @@ public class URLParam {
if (parameters.size() > ADD_PARAMETER_ON_MOVE_THRESHOLD) {
// recover VALUE back to Map
if (newValueMap == null) {
- newValueMap = recoverCompressedValue();
+ newValueMap = recoverValue();
}
newValueMap.put(keyIndex, DynamicParamTable.getValueIndex(entry.getKey(), entry.getValue()));
- } else if (!DynamicParamTable.isDefaultValue(entry.getKey(), entry.getValue())) {
- // add parameter by moving array, only support for adding once
- newValueArray = addByMove(VALUE, keyIndexToCompressIndex(newKey, DEFAULT_KEY, keyIndex), DynamicParamTable.getValueIndex(entry.getKey(), entry.getValue()));
} else {
- // value is default value, add to defaultKey directly
- if (defaultKey == null) {
- defaultKey = (BitSet) DEFAULT_KEY.clone();
- }
- defaultKey.set(keyIndex);
+ // add parameter by moving array, only support for adding once
+ newValueArray = addByMove(VALUE, keyIndexToIndex(newKey, keyIndex), DynamicParamTable.getValueIndex(entry.getKey(), entry.getValue()));
}
}
}
@@ -647,9 +601,6 @@ public class URLParam {
if (newKey == null) {
newKey = KEY;
}
- if (defaultKey == null) {
- defaultKey = DEFAULT_KEY;
- }
if (newValueArray == null && newValueMap == null) {
newValueArray = VALUE;
}
@@ -660,28 +611,26 @@ public class URLParam {
newMethodParams = METHOD_PARAMETERS;
}
if (newValueMap == null) {
- return new URLParam(newKey, defaultKey, newValueArray, newExtraParams, newMethodParams, null);
+ return new URLParam(newKey, newValueArray, newExtraParams, newMethodParams, null);
} else {
return new URLParam(newKey, newValueMap, newExtraParams, newMethodParams, null);
}
}
- private Map<Integer, Integer> recoverCompressedValue() {
+ private Map<Integer, Integer> recoverValue() {
Map<Integer, Integer> map = new HashMap<>((int) (KEY.size() / 0.75) + 1);
for (int i = KEY.nextSetBit(0), offset = 0; i >= 0; i = KEY.nextSetBit(i + 1)) {
- if (!DEFAULT_KEY.get(i)) {
- map.put(i, VALUE[offset++]);
- }
+ map.put(i, VALUE[offset++]);
}
return map;
}
- private Integer[] addByMove(Integer[] array, int index, Integer value) {
+ private int[] addByMove(int[] array, int index, Integer value) {
if (index < 0 || index > array.length) {
throw new IllegalArgumentException();
}
// copy-on-write
- Integer[] result = new Integer[array.length + 1];
+ int[] result = new int[array.length + 1];
System.arraycopy(array, 0, result, 0, index);
result[index] = value;
@@ -690,12 +639,12 @@ public class URLParam {
return result;
}
- private Integer[] replaceOffset(Integer[] array, int index, Integer value) {
+ private int[] replaceOffset(int[] array, int index, Integer value) {
if (index < 0 || index > array.length) {
throw new IllegalArgumentException();
}
// copy-on-write
- Integer[] result = new Integer[array.length];
+ int[] result = new int[array.length];
System.arraycopy(array, 0, result, 0, array.length);
result[index] = value;
@@ -715,32 +664,23 @@ public class URLParam {
}
// lazy init, null if no modify
BitSet newKey = null;
- BitSet defaultKey = null;
- Integer[] newValueArray = null;
+ int[] newValueArray = null;
Map<String, String> newExtraParams = null;
Map<String, Map<String, String>> newMethodParams = null;
for (String key : keys) {
- Integer keyIndex = DynamicParamTable.getKeyIndex(enableCompressed, key);
- if (keyIndex != null && KEY.get(keyIndex)) {
+ int keyIndex = DynamicParamTable.getKeyIndex(enableCompressed, key);
+ if (keyIndex >= 0 && KEY.get(keyIndex)) {
if (newKey == null) {
newKey = (BitSet) KEY.clone();
}
newKey.clear(keyIndex);
- if (DEFAULT_KEY.get(keyIndex)) {
- // is default value, remove in DEFAULT_KEY
- if (defaultKey == null) {
- defaultKey = (BitSet) DEFAULT_KEY.clone();
- }
- defaultKey.clear(keyIndex);
- } else {
- // which offset is in VALUE array, set value as -1, compress in the end
- if (newValueArray == null) {
- newValueArray = new Integer[VALUE.length];
- System.arraycopy(VALUE, 0, newValueArray, 0, VALUE.length);
- }
- // KEY is immutable
- newValueArray[keyIndexToCompressIndex(KEY, DEFAULT_KEY, keyIndex)] = -1;
+ // which offset is in VALUE array, set value as -1, compress in the end
+ if (newValueArray == null) {
+ newValueArray = new int[VALUE.length];
+ System.arraycopy(VALUE, 0, newValueArray, 0, VALUE.length);
}
+ // KEY is immutable
+ newValueArray[keyIndexToIndex(KEY, keyIndex)] = -1;
}
if (EXTRA_PARAMS.containsKey(key)) {
if (newExtraParams == null) {
@@ -764,9 +704,6 @@ public class URLParam {
if (newKey == null) {
newKey = KEY;
}
- if (defaultKey == null) {
- defaultKey = DEFAULT_KEY;
- }
if (newValueArray == null) {
newValueArray = VALUE;
} else {
@@ -783,11 +720,11 @@ public class URLParam {
// empty, directly return cache
return EMPTY_PARAM;
} else {
- return new URLParam(newKey, defaultKey, newValueArray, newExtraParams, newMethodParams, null);
+ return new URLParam(newKey, newValueArray, newExtraParams, newMethodParams, null);
}
}
- private Integer[] compressArray(Integer[] array) {
+ private int[] compressArray(int[] array) {
int total = 0;
for (int i : array) {
if (i > -1) {
@@ -795,10 +732,10 @@ public class URLParam {
}
}
if (total == 0) {
- return new Integer[0];
+ return new int[0];
}
- Integer[] result = new Integer[total];
+ int[] result = new int[total];
for (int i = 0, offset = 0; i < array.length; i++) {
// skip if value if less than 0
if (array[i] > -1) {
@@ -824,8 +761,8 @@ public class URLParam {
* @return present or not
*/
public boolean hasParameter(String key) {
- Integer keyIndex = DynamicParamTable.getKeyIndex(enableCompressed, key);
- if (keyIndex == null) {
+ int keyIndex = DynamicParamTable.getKeyIndex(enableCompressed, key);
+ if (keyIndex < 0) {
return EXTRA_PARAMS.containsKey(key);
}
return KEY.get(keyIndex);
@@ -838,47 +775,34 @@ public class URLParam {
* @return value, null if key is absent
*/
public String getParameter(String key) {
- Integer keyIndex = DynamicParamTable.getKeyIndex(enableCompressed, key);
- if (keyIndex == null) {
- if (EXTRA_PARAMS.containsKey(key)) {
- return EXTRA_PARAMS.get(key);
- }
- return null;
+ int keyIndex = DynamicParamTable.getKeyIndex(enableCompressed, key);
+ if (keyIndex < 0) {
+ return EXTRA_PARAMS.get(key);
}
if (KEY.get(keyIndex)) {
String value;
- if (DEFAULT_KEY.get(keyIndex)) {
- value = DynamicParamTable.getDefaultValue(keyIndex);
- } else {
- Integer offset = keyIndexToOffset(keyIndex);
- value = DynamicParamTable.getValue(keyIndex, offset);
- }
- if (StringUtils.isEmpty(value)) {
- // Forward compatible, make sure key dynamic increment can work.
- // In that case, some values which are proceed before increment will set in EXTRA_PARAMS.
- return EXTRA_PARAMS.get(key);
- } else {
- return value;
- }
+ int offset = keyIndexToOffset(keyIndex);
+ value = DynamicParamTable.getValue(keyIndex, offset);
+
+ return value;
+// if (StringUtils.isEmpty(value)) {
+// // Forward compatible, make sure key dynamic increment can work.
+// // In that case, some values which are proceed before increment will set in EXTRA_PARAMS.
+// return EXTRA_PARAMS.get(key);
+// } else {
+// return value;
+// }
}
return null;
}
- private int keyIndexToCompressIndex(BitSet key, BitSet defaultKey, int keyIndex) {
- int index = 0;
- for (int i = 0; i < keyIndex; i++) {
- if (key.get(i)) {
- if (!defaultKey.get(i)) {
- index++;
- }
- }
- }
- return index;
+ private int keyIndexToIndex(BitSet key, int keyIndex) {
+ return key.get(0, keyIndex).cardinality();
}
- private Integer keyIndexToOffset(int keyIndex) {
- int arrayOffset = keyIndexToCompressIndex(KEY, DEFAULT_KEY, keyIndex);
+ private int keyIndexToOffset(int keyIndex) {
+ int arrayOffset = keyIndexToIndex(KEY, keyIndex);
return VALUE[arrayOffset];
}
@@ -919,8 +843,7 @@ public class URLParam {
URLParam urlParam = (URLParam) o;
if (Objects.equals(KEY, urlParam.KEY)
- && Objects.equals(DEFAULT_KEY, urlParam.DEFAULT_KEY)
- && Arrays.equals(VALUE, urlParam.VALUE)) {
+ && Arrays.equals(VALUE, urlParam.VALUE)) {
if (CollectionUtils.isNotEmptyMap(EXTRA_PARAMS)) {
if (CollectionUtils.isEmptyMap(urlParam.EXTRA_PARAMS) || EXTRA_PARAMS.size() != urlParam.EXTRA_PARAMS.size()) {
return false;
@@ -954,7 +877,6 @@ public class URLParam {
hashCodeCache = hashCodeCache * 31 + value;
}
hashCodeCache = hashCodeCache * 31 + ((KEY == null) ? 0 : KEY.hashCode());
- hashCodeCache = hashCodeCache * 31 + ((DEFAULT_KEY == null) ? 0 : DEFAULT_KEY.hashCode());
}
return hashCodeCache;
}
@@ -971,8 +893,7 @@ public class URLParam {
StringJoiner stringJoiner = new StringJoiner("&");
for (int i = KEY.nextSetBit(0); i >= 0; i = KEY.nextSetBit(i + 1)) {
String key = DynamicParamTable.getKey(i);
- String value = DEFAULT_KEY.get(i) ?
- DynamicParamTable.getDefaultValue(i) : DynamicParamTable.getValue(i, keyIndexToOffset(i));
+ String value = DynamicParamTable.getValue(i, keyIndexToOffset(i));
value = value == null ? "" : value.trim();
stringJoiner.add(String.format("%s=%s", key, value));
}
@@ -1083,9 +1004,9 @@ public class URLParam {
private static void addParameter(BitSet keyBit, Map<Integer, Integer> valueMap, Map<String, String> extraParam,
Map<String, Map<String, String>> methodParameters, String key, String value, boolean skipIfPresent) {
- Integer keyIndex = DynamicParamTable.getKeyIndex(true, key);
+ int keyIndex = DynamicParamTable.getKeyIndex(true, key);
if (skipIfPresent) {
- if (keyIndex == null) {
+ if (keyIndex < 0) {
if (extraParam.containsKey(key)) {
return;
}
@@ -1096,7 +1017,7 @@ public class URLParam {
}
}
- if (keyIndex == null) {
+ if (keyIndex < 0) {
extraParam.put(key, value);
String[] methodSplit = key.split("\\.", 2);
if (methodSplit.length == 2) {
@@ -1104,9 +1025,7 @@ public class URLParam {
methodMap.put(methodSplit[0], value);
}
} else {
- if (!DynamicParamTable.isDefaultValue(key, value)) {
- valueMap.put(keyIndex, DynamicParamTable.getValueIndex(key, value));
- }
+ valueMap.put(keyIndex, DynamicParamTable.getValueIndex(key, value));
keyBit.set(keyIndex);
}
}
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/url/component/URLPlainParam.java b/dubbo-common/src/main/java/org/apache/dubbo/common/url/component/URLPlainParam.java
index 011fe2c7bd..b4fc76e10c 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/url/component/URLPlainParam.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/url/component/URLPlainParam.java
@@ -31,14 +31,14 @@ public class URLPlainParam extends URLParam implements Serializable {
private static final long serialVersionUID = 4722019979665434393L;
- protected URLPlainParam(BitSet key, BitSet defaultKey, Integer[] value, Map<String, String> extraParams, Map<String, Map<String, String>> methodParameters, String rawParam) {
- super(key, defaultKey, value, extraParams, methodParameters, rawParam);
+ protected URLPlainParam(BitSet key, int[] value, Map<String, String> extraParams, Map<String, Map<String, String>> methodParameters, String rawParam) {
+ super(key, value, extraParams, methodParameters, rawParam);
this.enableCompressed = false;
}
public static URLPlainParam toURLPlainParam(URLParam urlParam) {
Map<String, String> params = Collections.unmodifiableMap(new HashMap<>(urlParam.getParameters()));
- return new URLPlainParam(new BitSet(), new BitSet(), new Integer[0], params, urlParam.getMethodParameters(), urlParam.getRawParam());
+ return new URLPlainParam(new BitSet(), new int[0], params, urlParam.getMethodParameters(), urlParam.getRawParam());
}
}
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/url/component/param/DynamicParamTable.java b/dubbo-common/src/main/java/org/apache/dubbo/common/url/component/param/DynamicParamTable.java
index 7abac950aa..a86919ff94 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/url/component/param/DynamicParamTable.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/url/component/param/DynamicParamTable.java
@@ -18,20 +18,28 @@ package org.apache.dubbo.common.url.component.param;
import org.apache.dubbo.common.extension.ExtensionLoader;
+import java.util.Arrays;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
-import java.util.Objects;
-import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.TreeMap;
/**
* Global Param Cache Table
* Not support method parameters
*/
public final class DynamicParamTable {
- private static final List<String> KEYS = new CopyOnWriteArrayList<>();
- private static final List<ParamValue> VALUES = new CopyOnWriteArrayList<>();
+ /**
+ * Keys array, value is key's identity hashcode ( assume key is in constant pool )
+ */
+ private static int[] KEYS;
+ /**
+ * Keys array, value is string
+ */
+ private static String[] ORIGIN_KEYS;
+ private static ParamValue[] VALUES;
private static final Map<String, Integer> KEY2INDEX = new HashMap<>(64);
private DynamicParamTable() {
@@ -42,36 +50,36 @@ public final class DynamicParamTable {
init();
}
- public static Integer getKeyIndex(boolean enabled, String key) {
+ public static int getKeyIndex(boolean enabled, String key) {
if (!enabled) {
- return null;
+ return -1;
}
- return KEY2INDEX.get(key);
+ // assume key is in constant pool
+ int identityHashCode = System.identityHashCode(key);
+ int index = Arrays.binarySearch(KEYS, identityHashCode);
+ if (index >= 0) {
+ return index;
+ }
+ // fallback to key2index map
+ Integer indexFromMap = KEY2INDEX.get(key);
+ return indexFromMap == null ? -1 : indexFromMap;
}
- public static Integer getValueIndex(String key, String value) {
- Integer idx = getKeyIndex(true, key);
- if (idx == null) {
+ public static int getValueIndex(String key, String value) {
+ int idx = getKeyIndex(true, key);
+ if (idx < 0) {
throw new IllegalArgumentException("Cannot found key in url param:" + key);
}
- ParamValue paramValue = VALUES.get(idx);
+ ParamValue paramValue = VALUES[idx];
return paramValue.getIndex(value);
}
public static String getKey(int offset) {
- return KEYS.get(offset);
- }
-
- public static boolean isDefaultValue(String key, String value) {
- return Objects.equals(value, VALUES.get(getKeyIndex(true, key)).defaultVal());
- }
-
- public static String getValue(int vi, Integer offset) {
- return VALUES.get(vi).getN(offset);
+ return ORIGIN_KEYS[offset];
}
- public static String getDefaultValue(int vi) {
- return VALUES.get(vi).defaultVal();
+ public static String getValue(int vi, int offset) {
+ return VALUES[vi].getN(offset);
}
private static void init() {
@@ -82,19 +90,26 @@ public final class DynamicParamTable {
values.add(new DynamicValues(null));
ExtensionLoader.getExtensionLoader(DynamicParamSource.class)
- .getSupportedExtensionInstances().forEach(source -> source.init(keys, values));
+ .getSupportedExtensionInstances().forEach(source -> source.init(keys, values));
+ TreeMap<String, ParamValue> resultMap = new TreeMap<>(Comparator.comparingInt(System::identityHashCode));
for (int i = 0; i < keys.size(); i++) {
- if (!KEYS.contains(keys.get(i))) {
- KEYS.add(keys.get(i));
- VALUES.add(values.get(i));
- }
+ resultMap.put(keys.get(i), values.get(i));
}
- for (int i = 0; i < KEYS.size(); i++) {
- if (!KEYS.get(i).isEmpty()) {
- key2Index.put(KEYS.get(i), i);
- }
+ // assume key is in constant pool, store identity hashCode as index
+ KEYS = resultMap.keySet()
+ .stream()
+ .map(System::identityHashCode)
+ .mapToInt(x -> x)
+ .toArray();
+
+ ORIGIN_KEYS = resultMap.keySet().toArray(new String[0]);
+
+ VALUES = resultMap.values().toArray(new ParamValue[0]);
+
+ for (int i = 0; i < ORIGIN_KEYS.length; i++) {
+ key2Index.put(ORIGIN_KEYS[i], i);
}
KEY2INDEX.putAll(key2Index);
}
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/url/component/param/DynamicValues.java b/dubbo-common/src/main/java/org/apache/dubbo/common/url/component/param/DynamicValues.java
index 6b025e9d29..2d710dd6e2 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/url/component/param/DynamicValues.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/url/component/param/DynamicValues.java
@@ -20,7 +20,7 @@ import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class DynamicValues implements ParamValue {
- private final Map<Integer, String> index2Value = new ConcurrentHashMap<>();
+ private volatile String[] index2Value = new String[1];
private final Map<String, Integer> value2Index = new ConcurrentHashMap<>();
private int indexSeq = 0;
@@ -40,8 +40,15 @@ public class DynamicValues implements ParamValue {
synchronized (this) {
// thread safe
if (!value2Index.containsKey(value)) {
+ if (indexSeq == Integer.MAX_VALUE) {
+ throw new IllegalStateException("URL Param Cache is full.");
+ }
+ // copy on write, only support append now
+ String[] newValues = new String[indexSeq + 1];
+ System.arraycopy(index2Value, 0, newValues, 0, indexSeq);
+ newValues[indexSeq] = value;
+ index2Value = newValues;
value2Index.put(value, indexSeq);
- index2Value.put(indexSeq, value);
indexSeq += 1;
}
}
@@ -50,21 +57,22 @@ public class DynamicValues implements ParamValue {
}
@Override
- public String getN(Integer n) {
- return index2Value.get(n);
+ public String getN(int n) {
+ if (n == -1) {
+ return null;
+ }
+ return index2Value[n];
}
@Override
- public Integer getIndex(String value) {
+ public int getIndex(String value) {
+ if (value == null) {
+ return -1;
+ }
Integer index = value2Index.get(value);
if (index == null) {
return add(value);
}
return index;
}
-
- @Override
- public String defaultVal() {
- return getN(0);
- }
}
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/url/component/param/FixedParamValue.java b/dubbo-common/src/main/java/org/apache/dubbo/common/url/component/param/FixedParamValue.java
index d9a3bec900..6d6de7f459 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/url/component/param/FixedParamValue.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/url/component/param/FixedParamValue.java
@@ -48,12 +48,12 @@ public class FixedParamValue implements ParamValue {
* @param n
*/
@Override
- public String getN(Integer n) {
+ public String getN(int n) {
return values[n];
}
@Override
- public Integer getIndex(String value) {
+ public int getIndex(String value) {
Integer offset = val2Index.get(value.toLowerCase(Locale.ROOT));
if (offset == null) {
throw new IllegalArgumentException("unrecognized value " + value
@@ -62,9 +62,4 @@ public class FixedParamValue implements ParamValue {
}
return offset;
}
-
- @Override
- public String defaultVal() {
- return values[0];
- }
}
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/url/component/param/ParamValue.java b/dubbo-common/src/main/java/org/apache/dubbo/common/url/component/param/ParamValue.java
index 54271cccf6..60c41e5e4a 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/url/component/param/ParamValue.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/url/component/param/ParamValue.java
@@ -23,7 +23,7 @@ public interface ParamValue {
* @param n the nth value
* @return the value stored at index = n
*/
- String getN(Integer n);
+ String getN(int n);
/**
@@ -32,12 +32,5 @@ public interface ParamValue {
* @param value the stored value
* @return the index of value
*/
- Integer getIndex(String value);
-
- /**
- * get default value
- *
- * @return the default value stored at index = 0
- */
- String defaultVal();
+ int getIndex(String value);
}