in dubbo-common/src/main/java/org/apache/dubbo/common/url/component/URLParam.java [559:644]
private URLParam doAddParameters(Map<String, String> parameters, boolean skipIfPresent) {
// lazy init, null if no modify
BitSet newKey = null;
int[] newValueArray = null;
Map<Integer, Integer> newValueMap = null;
Map<String, String> newExtraParams = null;
Map<String, Map<String, String>> newMethodParams = null;
for (Map.Entry<String, String> entry : parameters.entrySet()) {
if (skipIfPresent && hasParameter(entry.getKey())) {
continue;
}
if (entry.getKey() == null || entry.getValue() == null) {
continue;
}
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);
}
newExtraParams.put(entry.getKey(), entry.getValue());
String[] methodSplit = entry.getKey().split("\\.");
if (methodSplit.length == 2) {
if (newMethodParams == null) {
newMethodParams = new HashMap<>(METHOD_PARAMETERS);
}
Map<String, String> methodMap =
newMethodParams.computeIfAbsent(methodSplit[1], (k) -> new HashMap<>());
methodMap.put(methodSplit[0], entry.getValue());
}
} else {
if (KEY.get(keyIndex)) {
// contains key, replace value
if (parameters.size() > ADD_PARAMETER_ON_MOVE_THRESHOLD) {
// recover VALUE back to Map, use map to replace key pair
if (newValueMap == null) {
newValueMap = recoverValue();
}
newValueMap.put(keyIndex, DynamicParamTable.getValueIndex(entry.getKey(), entry.getValue()));
} else {
newValueArray = replaceOffset(
VALUE,
keyIndexToIndex(KEY, keyIndex),
DynamicParamTable.getValueIndex(entry.getKey(), entry.getValue()));
}
} else {
// key is absent, add it
if (newKey == null) {
newKey = (BitSet) KEY.clone();
}
newKey.set(keyIndex);
if (parameters.size() > ADD_PARAMETER_ON_MOVE_THRESHOLD) {
// recover VALUE back to Map
if (newValueMap == null) {
newValueMap = recoverValue();
}
newValueMap.put(keyIndex, DynamicParamTable.getValueIndex(entry.getKey(), entry.getValue()));
} else {
// add parameter by moving array, only support for adding once
newValueArray = addByMove(
VALUE,
keyIndexToIndex(newKey, keyIndex),
DynamicParamTable.getValueIndex(entry.getKey(), entry.getValue()));
}
}
}
}
if (newKey == null) {
newKey = KEY;
}
if (newValueArray == null && newValueMap == null) {
newValueArray = VALUE;
}
if (newExtraParams == null) {
newExtraParams = EXTRA_PARAMS;
}
if (newMethodParams == null) {
newMethodParams = METHOD_PARAMETERS;
}
if (newValueMap == null) {
return new URLParam(newKey, newValueArray, newExtraParams, newMethodParams, null);
} else {
return new URLParam(newKey, newValueMap, newExtraParams, newMethodParams, null);
}
}