diff --git a/changelog/unreleased/SOLR-17600.yml b/changelog/unreleased/SOLR-17600.yml new file mode 100644 index 000000000000..53f8be54dbf4 --- /dev/null +++ b/changelog/unreleased/SOLR-17600.yml @@ -0,0 +1,7 @@ +title: SOLR 17600 - Replace MapSerializable with MapWriter +type: changed +authors: + - name: Ivan Šarić +links: + - name: SOLR-17600 + url: https://issues.apache.org/jira/browse/SOLR-17600 diff --git a/solr/core/src/java/org/apache/solr/api/NodeConfigClusterPluginsSource.java b/solr/core/src/java/org/apache/solr/api/NodeConfigClusterPluginsSource.java index 4282cce69b24..360ef8c3e96c 100644 --- a/solr/core/src/java/org/apache/solr/api/NodeConfigClusterPluginsSource.java +++ b/solr/core/src/java/org/apache/solr/api/NodeConfigClusterPluginsSource.java @@ -79,8 +79,7 @@ private static Map readPlugins(final NodeConfig cfg) { pluginMap.put("class", p.className); if (p.initArgs.size() > 0) { - Map config = p.initArgs.toMap(new HashMap<>()); - pluginMap.put("config", config); + pluginMap.put("config", p.initArgs.asMap(0)); } pluginInfos.put(pluginName, pluginMap); diff --git a/solr/core/src/java/org/apache/solr/cloud/api/collections/InstallShardDataCmd.java b/solr/core/src/java/org/apache/solr/cloud/api/collections/InstallShardDataCmd.java index 18ce5aa40716..403f22fff5d9 100644 --- a/solr/core/src/java/org/apache/solr/cloud/api/collections/InstallShardDataCmd.java +++ b/solr/core/src/java/org/apache/solr/cloud/api/collections/InstallShardDataCmd.java @@ -23,7 +23,6 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.ObjectMapper; import java.lang.invoke.MethodHandles; -import java.util.HashMap; import java.util.Locale; import org.apache.solr.common.SolrException; import org.apache.solr.common.cloud.ClusterState; @@ -80,8 +79,7 @@ public void call(ClusterState state, ZkNodeProps message, NamedList resu final ModifiableSolrParams coreApiParams = new ModifiableSolrParams(); coreApiParams.set( CoreAdminParams.ACTION, CoreAdminParams.CoreAdminAction.INSTALLCOREDATA.toString()); - typedMessage.toMap(new HashMap<>()).forEach((k, v) -> coreApiParams.set(k, v.toString())); - + typedMessage._forEachEntry((k, v) -> coreApiParams.set(String.valueOf(k), String.valueOf(v))); // Send the core-admin request to each replica in the slice final ShardHandler shardHandler = ccc.newShardHandler(); shardRequestTracker.sliceCmd(clusterState, coreApiParams, null, installSlice, shardHandler); diff --git a/solr/core/src/java/org/apache/solr/core/ConfigOverlay.java b/solr/core/src/java/org/apache/solr/core/ConfigOverlay.java index 811ea865cd60..d6edc8441e56 100644 --- a/solr/core/src/java/org/apache/solr/core/ConfigOverlay.java +++ b/solr/core/src/java/org/apache/solr/core/ConfigOverlay.java @@ -18,12 +18,13 @@ import static org.apache.solr.common.util.Utils.toJSONString; +import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import org.apache.solr.common.MapSerializable; +import org.apache.solr.common.MapWriter; import org.apache.solr.common.SolrException; import org.apache.solr.common.params.CoreAdminParams; import org.apache.solr.common.util.StrUtils; @@ -33,7 +34,7 @@ * This class encapsulates the config overlay json file. It is immutable and any edit operations * performed on this gives a new copy of the object with the changed value */ -public class ConfigOverlay implements MapSerializable { +public class ConfigOverlay implements MapWriter { private final int version; private final Map data; private Map props; @@ -233,10 +234,9 @@ public Map getUserProps() { } @Override - public Map toMap(Map map) { - map.put(ZNODEVER, version); - map.putAll(data); - return map; + public void writeMap(EntryWriter ew) throws IOException { + ew.put(ZNODEVER, version); + data.forEach(ew::putNoEx); } @SuppressWarnings({"unchecked"}) diff --git a/solr/core/src/java/org/apache/solr/core/PluginInfo.java b/solr/core/src/java/org/apache/solr/core/PluginInfo.java index 6ad137b0e09a..b953ebaae632 100644 --- a/solr/core/src/java/org/apache/solr/core/PluginInfo.java +++ b/solr/core/src/java/org/apache/solr/core/PluginInfo.java @@ -23,6 +23,7 @@ import static org.apache.solr.schema.FieldType.CLASS_NAME; import com.google.common.annotations.VisibleForTesting; +import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; @@ -30,13 +31,14 @@ import java.util.List; import java.util.Map; import org.apache.solr.common.ConfigNode; -import org.apache.solr.common.MapSerializable; +import org.apache.solr.common.MapWriter; import org.apache.solr.common.util.NamedList; +import org.apache.solr.common.util.SimpleOrderedMap; import org.apache.solr.util.DOMConfigNode; import org.w3c.dom.Node; /** An Object which represents a Plugin of any type */ -public class PluginInfo implements MapSerializable { +public class PluginInfo implements MapWriter { public final String name, className, type, pkgName; public final ClassName cName; public final NamedList initArgs; @@ -193,27 +195,18 @@ public PluginInfo getChild(String type) { } @Override - @SuppressWarnings({"unchecked", "rawtypes"}) - public Map toMap(Map map) { - map.putAll(attributes); - Map m = map; - if (initArgs != null) m.putAll(initArgs.asMap(3)); - if (children != null) { - for (PluginInfo child : children) { - Object old = m.get(child.name); - if (old == null) { - m.put(child.name, child.toMap(new LinkedHashMap<>())); - } else if (old instanceof List list) { - list.add(child.toMap(new LinkedHashMap<>())); - } else { - ArrayList l = new ArrayList(); - l.add(old); - l.add(child.toMap(new LinkedHashMap<>())); - m.put(child.name, l); - } - } + public void writeMap(EntryWriter ew) throws IOException { + new NamedList<>(attributes).writeMap(ew); + if (initArgs != null) { + new SimpleOrderedMap<>(initArgs).writeMap(ew); + } + if (children == null || children.isEmpty()) { + return; + } + + for (PluginInfo child : children) { + child.writeMap(ew); } - return m; } /** diff --git a/solr/core/src/java/org/apache/solr/core/RequestParams.java b/solr/core/src/java/org/apache/solr/core/RequestParams.java index c5b37d197683..9bed88a0362c 100644 --- a/solr/core/src/java/org/apache/solr/core/RequestParams.java +++ b/solr/core/src/java/org/apache/solr/core/RequestParams.java @@ -25,10 +25,11 @@ import java.util.List; import java.util.Map; import org.apache.solr.cloud.ZkSolrResourceLoader; -import org.apache.solr.common.MapSerializable; +import org.apache.solr.common.MapWriter; import org.apache.solr.common.SolrException; import org.apache.solr.common.cloud.SolrZkClient; import org.apache.solr.common.params.MultiMapSolrParams; +import org.apache.solr.common.util.SimpleOrderedMap; import org.apache.solr.common.util.Utils; import org.apache.zookeeper.KeeperException; import org.apache.zookeeper.data.Stat; @@ -39,7 +40,7 @@ * The class encapsulates the request time parameters . This is immutable and any changes performed * returns a copy of the Object with the changed values */ -public class RequestParams implements MapSerializable { +public class RequestParams implements MapWriter { private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); private final Map data; @@ -113,8 +114,9 @@ public int getZnodeVersion() { } @Override - public Map toMap(Map map) { - return getMapWithVersion(data, znodeVersion); + public void writeMap(EntryWriter ew) throws IOException { + ew.put(ConfigOverlay.ZNODEVER, znodeVersion); + data.forEach(ew::putNoEx); } public static Map getMapWithVersion(Map data, int znodeVersion) { @@ -130,7 +132,9 @@ public RequestParams setParams(String name, ParamSet paramSet) { Map p = (Map) deepCopy.get(NAME); if (p == null) deepCopy.put(NAME, p = new LinkedHashMap<>()); if (paramSet == null) p.remove(name); - else p.put(name, paramSet.toMap(new LinkedHashMap<>())); + else { + p.put(name, new SimpleOrderedMap<>(paramSet)); + } return new RequestParams(deepCopy, znodeVersion); } @@ -208,7 +212,7 @@ public byte[] toByteArray() { public static final String INVARIANTS = "_invariants_"; @SuppressWarnings({"unchecked"}) - public static class ParamSet implements MapSerializable { + public static class ParamSet implements MapWriter { private final Map defaults, appends, invariants; Map paramsMap; public final Map meta; @@ -235,12 +239,11 @@ public Long getVersion() { } @Override - public Map toMap(Map result) { - result.putAll(defaults); - if (appends != null) result.put(APPENDS, appends); - if (invariants != null) result.put(INVARIANTS, invariants); - if (meta != null) result.put("", meta); - return result; + public void writeMap(EntryWriter ew) throws IOException { + defaults.forEach(ew::putNoEx); + if (appends != null) ew.put(APPENDS, appends); + if (invariants != null) ew.put(INVARIANTS, invariants); + if (meta != null) ew.put("", meta); } @SuppressWarnings({"rawtypes"}) diff --git a/solr/core/src/java/org/apache/solr/core/SolrConfig.java b/solr/core/src/java/org/apache/solr/core/SolrConfig.java index 0bea68e114ee..52bedacc95fb 100644 --- a/solr/core/src/java/org/apache/solr/core/SolrConfig.java +++ b/solr/core/src/java/org/apache/solr/core/SolrConfig.java @@ -59,10 +59,12 @@ import org.apache.solr.cloud.RecoveryStrategy; import org.apache.solr.cloud.ZkSolrResourceLoader; import org.apache.solr.common.ConfigNode; -import org.apache.solr.common.MapSerializable; +import org.apache.solr.common.MapWriter; import org.apache.solr.common.SolrException; import org.apache.solr.common.SolrException.ErrorCode; import org.apache.solr.common.util.IOUtils; +import org.apache.solr.common.util.NamedList; +import org.apache.solr.common.util.SimpleOrderedMap; import org.apache.solr.common.util.Utils; import org.apache.solr.handler.component.SearchComponent; import org.apache.solr.pkg.PackageListeners; @@ -95,7 +97,7 @@ * Provides a static reference to a Config object modeling the main configuration data for a Solr * core -- typically found in "solrconfig.xml". */ -public class SolrConfig implements MapSerializable { +public class SolrConfig implements MapWriter { private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); @@ -684,23 +686,17 @@ public HttpCachingConfig getHttpCachingConfig() { return httpCachingConfig; } - public static class HttpCachingConfig implements MapSerializable { + public static class HttpCachingConfig implements MapWriter { /** For extracting Expires "ttl" from config */ private static final Pattern MAX_AGE = Pattern.compile("\\bmax-age=(\\d+)"); @Override - public Map toMap(Map map) { - // Could have nulls - return Utils.makeMap( - "never304", - never304, - "etagSeed", - etagSeed, - "lastModFrom", - lastModFrom.name().toLowerCase(Locale.ROOT), - "cacheControl", - cacheControlHeader); + public void writeMap(EntryWriter ew) throws IOException { + ew.put("never304", never304) + .put("etagSeed", etagSeed) + .put("lastModFrom", lastModFrom.name().toLowerCase(Locale.ROOT)) + .put("cacheControl", cacheControlHeader); } public enum LastModFrom { @@ -782,7 +778,7 @@ public LastModFrom getLastModFrom() { } } - public static class UpdateHandlerInfo implements MapSerializable { + public static class UpdateHandlerInfo implements MapWriter { public final String className; public final int autoCommmitMaxDocs, autoCommmitMaxTime, @@ -841,19 +837,18 @@ public UpdateHandlerInfo(ConfigNode updateHandler) { } @Override - public Map toMap(Map map) { - map.put("commitWithin", Map.of("softCommit", commitWithinSoftCommit)); - map.put( + public void writeMap(EntryWriter ew) throws IOException { + ew.put("commitWithin", Map.of("softCommit", commitWithinSoftCommit)); + ew.put( "autoCommit", Map.of( "maxDocs", autoCommmitMaxDocs, "maxTime", autoCommmitMaxTime, "openSearcher", openSearcher)); - map.put( + ew.put( "autoSoftCommit", Map.of("maxDocs", autoSoftCommmitMaxDocs, "maxTime", autoSoftCommmitMaxTime)); - map.put("commitPollInterval", commitPollInterval); - return map; + ew.put("commitPollInterval", commitPollInterval); } } @@ -951,20 +946,35 @@ public int getFormUploadLimitKB() { } @Override - public Map toMap(Map result) { - if (znodeVersion > -1) result.put(ZNODEVER, znodeVersion); - if (luceneMatchVersion != null) - result.put(IndexSchema.LUCENE_MATCH_VERSION_PARAM, luceneMatchVersion.toString()); - result.put("updateHandler", getUpdateHandlerInfo()); - Map m = new LinkedHashMap<>(); - result.put("query", m); - m.put("useFilterForSortedQuery", useFilterForSortedQuery); - m.put("queryResultWindowSize", queryResultWindowSize); - m.put("queryResultMaxDocsCached", queryResultMaxDocsCached); - m.put("enableLazyFieldLoading", enableLazyFieldLoading); - m.put("maxBooleanClauses", booleanQueryMaxClauseCount); - m.put(MIN_PREFIX_QUERY_TERM_LENGTH, prefixQueryMinPrefixLength); + public void writeMap(EntryWriter ew) throws IOException { + if (znodeVersion > -1) { + ew.put(ZNODEVER, znodeVersion); + } + if (luceneMatchVersion != null) { + ew.put(IndexSchema.LUCENE_MATCH_VERSION_PARAM, luceneMatchVersion.toString()); + } + ew.put("updateHandler", new SimpleOrderedMap<>(getUpdateHandlerInfo())); + ew.put( + "query", + new SimpleOrderedMap<>( + (MapWriter) + m -> { + m.put("useFilterForSortedQuery", useFilterForSortedQuery); + m.put("queryResultWindowSize", queryResultWindowSize); + m.put("queryResultMaxDocsCached", queryResultMaxDocsCached); + m.put("enableLazyFieldLoading", enableLazyFieldLoading); + m.put("maxBooleanClauses", booleanQueryMaxClauseCount); + m.put(MIN_PREFIX_QUERY_TERM_LENGTH, prefixQueryMinPrefixLength); + + addCacheConfig( + m, + filterCacheConfig, + queryResultCacheConfig, + documentCacheConfig, + fieldValueCacheConfig, + featureVectorCacheConfig); + })); for (SolrPluginInfo plugin : plugins) { List infos = getPluginInfos(plugin.clazz.getName()); if (infos == null || infos.isEmpty()) continue; @@ -981,45 +991,47 @@ public Map toMap(Map result) { overlay.getNamedPlugins(plugin.tag).entrySet()) { items.put(e.getKey(), e.getValue()); } - result.put(tag, items); + ew.put( + tag, + new SimpleOrderedMap<>( + m -> { + new NamedList<>(items).writeMap(m); + })); } else { if (plugin.options.contains(MULTI_OK)) { - ArrayList l = new ArrayList<>(); - for (PluginInfo info : infos) l.add(info); - result.put(tag, l); + ArrayList writers = new ArrayList<>(); + infos.forEach(info -> writers.add(new SimpleOrderedMap<>(info))); + ew.put(tag, writers); } else { - result.put(tag, infos.get(0)); + ew.put(tag, new SimpleOrderedMap<>(m -> infos.getFirst().writeMap(m))); } } } - addCacheConfig( - m, - filterCacheConfig, - queryResultCacheConfig, - documentCacheConfig, - fieldValueCacheConfig, - featureVectorCacheConfig); - m = new LinkedHashMap<>(); - result.put("requestDispatcher", m); - if (httpCachingConfig != null) m.put("httpCaching", httpCachingConfig); - m.put( - "requestParsers", - Map.of( - "multipartUploadLimitKB", - multipartUploadLimitKB, - "formUploadLimitKB", - formUploadLimitKB)); - if (indexConfig != null) result.put("indexConfig", indexConfig); - - // TODO there is more to add - - return result; + ew.put( + "requestDispatcher", + new SimpleOrderedMap<>( + (MapWriter) + m -> { + if (httpCachingConfig != null) m.put("httpCaching", httpCachingConfig); + m.put( + "requestParsers", + Map.of( + "multipartUploadLimitKB", + multipartUploadLimitKB, + "formUploadLimitKB", + formUploadLimitKB)); + })); + if (indexConfig != null) ew.put("indexConfig", new SimpleOrderedMap<>(indexConfig)); } - private void addCacheConfig(Map queryMap, CacheConfig... cache) { + private void addCacheConfig(EntryWriter queryMap, CacheConfig... cache) throws IOException { if (cache == null) return; - for (CacheConfig config : cache) if (config != null) queryMap.put(config.getNodeName(), config); + for (CacheConfig cc : cache) { + if (cc != null) { + queryMap.put(cc.getNodeName(), new SimpleOrderedMap<>((MapWriter) cc)); + } + } } public Properties getSubstituteProperties() { diff --git a/solr/core/src/java/org/apache/solr/filestore/ClusterFileStore.java b/solr/core/src/java/org/apache/solr/filestore/ClusterFileStore.java index 9eb61fd58227..8125522988ca 100644 --- a/solr/core/src/java/org/apache/solr/filestore/ClusterFileStore.java +++ b/solr/core/src/java/org/apache/solr/filestore/ClusterFileStore.java @@ -42,6 +42,7 @@ import org.apache.solr.common.params.CommonParams; import org.apache.solr.common.params.ModifiableSolrParams; import org.apache.solr.common.params.SolrParams; +import org.apache.solr.common.util.SimpleOrderedMap; import org.apache.solr.common.util.StrUtils; import org.apache.solr.core.CoreContainer; import org.apache.solr.core.SolrCore; @@ -254,7 +255,7 @@ private static FileStoreEntryMetadata convertToResponse(FileStore.FileDetails de entryMetadata.size = details.size(); entryMetadata.timestamp = details.getTimeStamp(); if (details.getMetaData() != null) { - details.getMetaData().toMap(entryMetadata.unknownProperties()); + entryMetadata.unknownProperties().putAll(new SimpleOrderedMap<>(details.getMetaData())); } return entryMetadata; diff --git a/solr/core/src/java/org/apache/solr/handler/ClusterAPI.java b/solr/core/src/java/org/apache/solr/handler/ClusterAPI.java index 4807e19aca24..2bb9b19c6b40 100644 --- a/solr/core/src/java/org/apache/solr/handler/ClusterAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/ClusterAPI.java @@ -52,6 +52,7 @@ import org.apache.solr.common.params.DefaultSolrParams; import org.apache.solr.common.params.ModifiableSolrParams; import org.apache.solr.common.util.ReflectMapWriter; +import org.apache.solr.common.util.SimpleOrderedMap; import org.apache.solr.common.util.Utils; import org.apache.solr.core.CoreContainer; import org.apache.solr.core.NodeRoles; @@ -260,7 +261,7 @@ public class Commands { @Command(name = "add-role") public void addRole(PayloadObj obj) throws Exception { RoleInfo info = obj.get(); - Map m = info.toMap(new HashMap<>()); + Map m = new SimpleOrderedMap<>(info); m.put("action", ADDROLE.toString()); collectionsHandler.handleRequestBody(wrapParams(obj.getRequest(), m), obj.getResponse()); } @@ -268,7 +269,7 @@ public void addRole(PayloadObj obj) throws Exception { @Command(name = "remove-role") public void removeRole(PayloadObj obj) throws Exception { RoleInfo info = obj.get(); - Map m = info.toMap(new HashMap<>()); + Map m = new SimpleOrderedMap<>(info); m.put("action", REMOVEROLE.toString()); collectionsHandler.handleRequestBody(wrapParams(obj.getRequest(), m), obj.getResponse()); } diff --git a/solr/core/src/java/org/apache/solr/handler/SolrConfigHandler.java b/solr/core/src/java/org/apache/solr/handler/SolrConfigHandler.java index 652649e36698..e1e4feac4cf8 100644 --- a/solr/core/src/java/org/apache/solr/handler/SolrConfigHandler.java +++ b/solr/core/src/java/org/apache/solr/handler/SolrConfigHandler.java @@ -60,7 +60,7 @@ import org.apache.solr.client.solrj.response.SimpleSolrResponse; import org.apache.solr.cloud.ZkController; import org.apache.solr.cloud.ZkSolrResourceLoader; -import org.apache.solr.common.MapSerializable; +import org.apache.solr.common.MapWriter; import org.apache.solr.common.SolrErrorWrappingException; import org.apache.solr.common.SolrException; import org.apache.solr.common.cloud.ClusterState; @@ -75,6 +75,7 @@ import org.apache.solr.common.util.EnvUtils; import org.apache.solr.common.util.ExecutorUtil; import org.apache.solr.common.util.NamedList; +import org.apache.solr.common.util.SimpleOrderedMap; import org.apache.solr.common.util.SolrNamedThreadFactory; import org.apache.solr.common.util.StrUtils; import org.apache.solr.common.util.Utils; @@ -199,7 +200,7 @@ private void handleGET() { Map m = new LinkedHashMap<>(); m.put(ZNODEVER, params.getZnodeVersion()); if (p != null) { - m.put(RequestParams.NAME, Map.of(parts.get(2), p.toMap(new LinkedHashMap<>()))); + m.put(RequestParams.NAME, Map.of(parts.get(2), new SimpleOrderedMap<>(p))); } resp.add(SolrQueryResponse.NAME, m); } else { @@ -278,16 +279,16 @@ private void handleGET() { Map pluginNameVsPluginInfo = (Map) val.get(parts.get(1)); if (pluginNameVsPluginInfo != null) { Object o = - pluginNameVsPluginInfo instanceof MapSerializable + pluginNameVsPluginInfo instanceof MapWriter ? pluginNameVsPluginInfo : pluginNameVsPluginInfo.get(componentName); Map pluginInfo = - o instanceof MapSerializable - ? ((MapSerializable) o).toMap(new LinkedHashMap<>()) + o instanceof MapWriter + ? new SimpleOrderedMap<>((MapWriter) o) : (Map) o; val.put( parts.get(1), - pluginNameVsPluginInfo instanceof PluginInfo + pluginNameVsPluginInfo instanceof MapWriter ? pluginInfo : Map.of(componentName, pluginInfo)); if (req.getParams().getBool("meta", false)) { @@ -301,8 +302,10 @@ private void handleGET() { if (infos == null || infos.isEmpty()) continue; infos.forEach( (s, mapWriter) -> { - if (s.equals(pluginInfo.get("class"))) { - (pluginInfo).put("_packageinfo_", mapWriter); + Map componentInfo = + getComponentInfo(pluginInfo, componentName); + if (s.equals(componentInfo.get("class"))) { + (componentInfo).put("_packageinfo_", mapWriter); } }); } @@ -315,10 +318,18 @@ private void handleGET() { } } + @SuppressWarnings({"unchecked"}) + private Map getComponentInfo( + Map pluginInfo, String componentName) { + return pluginInfo.containsKey("class") + ? pluginInfo + : (Map) pluginInfo.getOrDefault(componentName, new HashMap<>()); + } + private Map getConfigDetails(String componentType, SolrQueryRequest req) { String componentName = componentType == null ? null : req.getParams().get("componentName"); boolean showParams = req.getParams().getBool("expandParams", false); - Map map = this.req.getCore().getSolrConfig().toMap(new LinkedHashMap<>()); + Map map = new SimpleOrderedMap<>(this.req.getCore().getSolrConfig()); if (componentType != null && !SolrRequestHandler.TYPE.equals(componentType)) return map; @SuppressWarnings({"unchecked"}) @@ -351,7 +362,7 @@ private Map expandUseParams(SolrQueryRequest req, Object plugin) if (plugin instanceof Map) { pluginInfo = (Map) plugin; } else if (plugin instanceof PluginInfo) { - pluginInfo = ((PluginInfo) plugin).toMap(new LinkedHashMap<>()); + pluginInfo = new SimpleOrderedMap<>((PluginInfo) plugin); } String useParams = (String) pluginInfo.get(USEPARAM); String useParamsInReq = req.getOriginalParams().get(USEPARAM); @@ -505,9 +516,7 @@ private void handleParams(ArrayList ops, RequestParams params) ZkController.touchConfDir(zkLoader); } else { if (log.isDebugEnabled()) { - log.debug( - "persisting params data : {}", - Utils.toJSONString(params.toMap(new LinkedHashMap<>()))); + log.debug("persisting params data : {}", Utils.toJSONString(params)); } int latestVersion = ZkController.persistConfigResourceToZooKeeper( diff --git a/solr/core/src/java/org/apache/solr/handler/admin/BaseHandlerApiSupport.java b/solr/core/src/java/org/apache/solr/handler/admin/BaseHandlerApiSupport.java index 459f04864419..475156bf102f 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/BaseHandlerApiSupport.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/BaseHandlerApiSupport.java @@ -21,6 +21,7 @@ import static org.apache.solr.common.SolrException.ErrorCode.BAD_REQUEST; import static org.apache.solr.common.util.StrUtils.splitSmart; +import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -183,7 +184,7 @@ public Iterator getParameterNamesIterator() { } @Override - public Map toMap(Map suppliedMap) { + public void writeMap(EntryWriter ew) throws IOException { for (Iterator it = getParameterNamesIterator(); it.hasNext(); ) { final String param = it.next(); String key = cmd.meta().getParamSubstitute(param); @@ -193,6 +194,7 @@ public Map toMap(Map suppliedMap) { : map.get(key); if (o == null) o = pathValues.get(key); if (o == null && useRequestParams) o = origParams.getParams(key); + if (o == null) continue; // make strings out of as many things as we can now to minimize differences from // the standard impls that pass through a NamedList/SimpleOrderedMap... Class oClass = o.getClass(); @@ -200,19 +202,19 @@ public Map toMap(Map suppliedMap) { || Number.class.isAssignableFrom(oClass) || Character.class.isAssignableFrom(oClass) || Boolean.class.isAssignableFrom(oClass)) { - suppliedMap.put(param, String.valueOf(o)); + ew.put(param, String.valueOf(o)); } else if (List.class.isAssignableFrom(oClass) + && !((List) o).isEmpty() && ((List) o).get(0) instanceof String) { @SuppressWarnings({"unchecked"}) List l = (List) o; - suppliedMap.put(param, l.toArray(new String[0])); + ew.put(param, l.toArray(new String[0])); } else { // Lists pass through but will require special handling downstream // if they contain non-string elements. - suppliedMap.put(param, o); + ew.put(param, o); } } - return suppliedMap; } }); } diff --git a/solr/core/src/java/org/apache/solr/handler/admin/IndexSizeEstimator.java b/solr/core/src/java/org/apache/solr/handler/admin/IndexSizeEstimator.java index b88ae352e527..38eb8a464cfd 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/IndexSizeEstimator.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/IndexSizeEstimator.java @@ -59,6 +59,7 @@ import org.apache.lucene.util.SuppressForbidden; import org.apache.lucene.util.UnicodeUtil; import org.apache.solr.common.MapWriter; +import org.apache.solr.common.util.SimpleOrderedMap; import org.apache.solr.common.util.Utils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -277,12 +278,10 @@ private void convert(Map result) { for (Map.Entry entry : result.entrySet()) { Object value = entry.getValue(); if (value instanceof ItemPriorityQueue queue) { - Map map = new LinkedHashMap<>(); - queue.toMap(map); + Map map = new SimpleOrderedMap<>(queue); entry.setValue(map); } else if (value instanceof MapWriterSummaryStatistics stats) { - Map map = new LinkedHashMap<>(); - stats.toMap(map); + Map map = new SimpleOrderedMap<>(stats); entry.setValue(map); } else if (value instanceof AtomicLong) { entry.setValue(((AtomicLong) value).longValue()); diff --git a/solr/core/src/java/org/apache/solr/handler/admin/ZookeeperInfoHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/ZookeeperInfoHandler.java index 45d6ea65ce4e..506a8498611f 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/ZookeeperInfoHandler.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/ZookeeperInfoHandler.java @@ -529,7 +529,7 @@ void printPaginatedCollections() throws IOException { if (dc != null) { // TODO: for collections with perReplicaState, a ser/deser to JSON was needed to get the // state to render correctly for the UI? - Map collectionState = dc.toMap(new LinkedHashMap<>()); + Map collectionState = Utils.convertToMap(dc, new LinkedHashMap<>()); if (applyStatusFilter) { // verify this collection matches the filtered state if (page.matchesStatusFilter(collectionState, liveNodes)) { diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/CreateCore.java b/solr/core/src/java/org/apache/solr/handler/admin/api/CreateCore.java index 289d51d68c4c..99602b9e5980 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/CreateCore.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/CreateCore.java @@ -158,7 +158,7 @@ private Map buildCoreParams(CreateCoreParams createParams) { } public static CreateCoreParams createRequestBodyFromV1Params(SolrParams solrParams) { - final var v1ParamMap = solrParams.toMap(new HashMap<>()); + final var v1ParamMap = Utils.convertToMap(solrParams, new HashMap<>()); v1ParamMap.remove(ACTION); v1ParamMap.remove(ASYNC); diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/InstallShardData.java b/solr/core/src/java/org/apache/solr/handler/admin/api/InstallShardData.java index 98623f7d2091..272189930b30 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/InstallShardData.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/InstallShardData.java @@ -21,7 +21,7 @@ import static org.apache.solr.security.PermissionNameProvider.Name.COLL_EDIT_PERM; import jakarta.inject.Inject; -import java.util.HashMap; +import java.util.Map; import org.apache.solr.client.api.endpoint.InstallShardDataApi; import org.apache.solr.client.api.model.AsyncJerseyResponse; import org.apache.solr.client.api.model.InstallShardDataRequestBody; @@ -33,6 +33,7 @@ import org.apache.solr.common.cloud.Slice; import org.apache.solr.common.cloud.ZkNodeProps; import org.apache.solr.common.params.CollectionParams; +import org.apache.solr.common.util.SimpleOrderedMap; import org.apache.solr.common.util.StrUtils; import org.apache.solr.core.CoreContainer; import org.apache.solr.handler.admin.CollectionsHandler; @@ -129,6 +130,6 @@ public static ZkNodeProps createRemoteMessage( } messageTyped.validate(); - return new ZkNodeProps(messageTyped.toMap(new HashMap<>())); + return new ZkNodeProps((Map) new SimpleOrderedMap<>(messageTyped)); } } diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/MigrateDocsAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/MigrateDocsAPI.java index 7e3898c8a899..2bd44ced52db 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/MigrateDocsAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/MigrateDocsAPI.java @@ -22,13 +22,13 @@ import static org.apache.solr.handler.ClusterAPI.wrapParams; import static org.apache.solr.security.PermissionNameProvider.Name.COLL_EDIT_PERM; -import java.util.HashMap; import java.util.Map; import org.apache.solr.api.Command; import org.apache.solr.api.EndPoint; import org.apache.solr.api.PayloadObj; import org.apache.solr.client.solrj.request.beans.MigrateDocsPayload; import org.apache.solr.common.params.CollectionParams; +import org.apache.solr.common.util.SimpleOrderedMap; import org.apache.solr.handler.admin.CollectionsHandler; /** @@ -55,7 +55,7 @@ public MigrateDocsAPI(CollectionsHandler collectionsHandler) { @Command(name = V2_MIGRATE_DOCS_CMD) public void migrateDocs(PayloadObj obj) throws Exception { final MigrateDocsPayload v2Body = obj.get(); - final Map v1Params = v2Body.toMap(new HashMap<>()); + final Map v1Params = new SimpleOrderedMap<>(v2Body); v1Params.put(ACTION, CollectionParams.CollectionAction.MIGRATE.toLower()); v1Params.put(COLLECTION, obj.getRequest().getPathTemplateValues().get(COLLECTION)); diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/ModifyCollectionAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/ModifyCollectionAPI.java index 93d11d0c4283..c51f66fed8a2 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/ModifyCollectionAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/ModifyCollectionAPI.java @@ -24,13 +24,13 @@ import static org.apache.solr.handler.api.V2ApiUtils.flattenMapWithPrefix; import static org.apache.solr.security.PermissionNameProvider.Name.COLL_EDIT_PERM; -import java.util.HashMap; import java.util.Map; import org.apache.solr.api.Command; import org.apache.solr.api.EndPoint; import org.apache.solr.api.PayloadObj; import org.apache.solr.client.solrj.request.beans.ModifyCollectionPayload; import org.apache.solr.common.params.CollectionParams; +import org.apache.solr.common.util.SimpleOrderedMap; import org.apache.solr.handler.admin.CollectionsHandler; /** @@ -58,7 +58,7 @@ public ModifyCollectionAPI(CollectionsHandler collectionsHandler) { public void modifyCollection(PayloadObj obj) throws Exception { final ModifyCollectionPayload v2Body = obj.get(); - final Map v1Params = v2Body.toMap(new HashMap<>()); + final Map v1Params = new SimpleOrderedMap<>(v2Body); v1Params.put(ACTION, CollectionParams.CollectionAction.MODIFYCOLLECTION.toLower()); v1Params.put(COLLECTION, obj.getRequest().getPathTemplateValues().get(COLLECTION)); if (v2Body.config != null) { diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/MoveReplicaAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/MoveReplicaAPI.java index 3c0d701de302..3bc759fd4418 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/MoveReplicaAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/MoveReplicaAPI.java @@ -22,13 +22,13 @@ import static org.apache.solr.handler.ClusterAPI.wrapParams; import static org.apache.solr.security.PermissionNameProvider.Name.COLL_EDIT_PERM; -import java.util.HashMap; import java.util.Map; import org.apache.solr.api.Command; import org.apache.solr.api.EndPoint; import org.apache.solr.api.PayloadObj; import org.apache.solr.client.solrj.request.beans.MoveReplicaPayload; import org.apache.solr.common.params.CollectionParams; +import org.apache.solr.common.util.SimpleOrderedMap; import org.apache.solr.handler.admin.CollectionsHandler; /** @@ -55,7 +55,7 @@ public MoveReplicaAPI(CollectionsHandler collectionsHandler) { @Command(name = V2_MOVE_REPLICA_CMD) public void moveReplica(PayloadObj obj) throws Exception { final MoveReplicaPayload v2Body = obj.get(); - final Map v1Params = v2Body.toMap(new HashMap<>()); + final Map v1Params = new SimpleOrderedMap<>(v2Body); v1Params.put(ACTION, CollectionParams.CollectionAction.MOVEREPLICA.toLower()); v1Params.put(COLLECTION, obj.getRequest().getPathTemplateValues().get(COLLECTION)); diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/OverseerOperationAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/OverseerOperationAPI.java index 1c566a8c610a..69b633799045 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/OverseerOperationAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/OverseerOperationAPI.java @@ -22,7 +22,6 @@ import static org.apache.solr.handler.ClusterAPI.wrapParams; import static org.apache.solr.security.PermissionNameProvider.Name.CORE_EDIT_PERM; -import java.util.HashMap; import java.util.Locale; import java.util.Map; import org.apache.solr.api.Command; @@ -30,6 +29,7 @@ import org.apache.solr.api.PayloadObj; import org.apache.solr.client.solrj.request.beans.OverseerOperationPayload; import org.apache.solr.common.params.CoreAdminParams; +import org.apache.solr.common.util.SimpleOrderedMap; import org.apache.solr.handler.admin.CoreAdminHandler; /** @@ -59,7 +59,7 @@ public OverseerOperationAPI(CoreAdminHandler coreAdminHandler) { @Command(name = OVERSEER_OP_CMD) public void joinOverseerLeaderElection(PayloadObj payload) throws Exception { - final Map v1Params = payload.get().toMap(new HashMap<>()); + final Map v1Params = new SimpleOrderedMap<>(payload.get()); v1Params.put( ACTION, CoreAdminParams.CoreAdminAction.OVERSEEROP.name().toLowerCase(Locale.ROOT)); coreAdminHandler.handleRequestBody( diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/PrepareCoreRecoveryAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/PrepareCoreRecoveryAPI.java index c5b830498158..983440af3d82 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/PrepareCoreRecoveryAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/PrepareCoreRecoveryAPI.java @@ -24,13 +24,13 @@ import static org.apache.solr.handler.ClusterAPI.wrapParams; import static org.apache.solr.security.PermissionNameProvider.Name.CORE_EDIT_PERM; -import java.util.HashMap; import java.util.Locale; import java.util.Map; import org.apache.solr.api.Command; import org.apache.solr.api.EndPoint; import org.apache.solr.api.PayloadObj; import org.apache.solr.client.solrj.request.beans.PrepareCoreRecoveryPayload; +import org.apache.solr.common.util.SimpleOrderedMap; import org.apache.solr.handler.admin.CoreAdminHandler; /** @@ -57,7 +57,7 @@ public PrepareCoreRecoveryAPI(CoreAdminHandler coreAdminHandler) { @Command(name = V2_PREP_RECOVERY_CMD) public void prepareCoreForRecovery(PayloadObj obj) throws Exception { final PrepareCoreRecoveryPayload v2Body = obj.get(); - final Map v1Params = v2Body.toMap(new HashMap<>()); + final Map v1Params = new SimpleOrderedMap<>(v2Body); v1Params.put(ACTION, PREPRECOVERY.name().toLowerCase(Locale.ROOT)); v1Params.put(CORE, obj.getRequest().getPathTemplateValues().get("core")); diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/RebalanceLeadersAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/RebalanceLeadersAPI.java index e9127817732f..47d29bcbfca2 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/RebalanceLeadersAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/RebalanceLeadersAPI.java @@ -22,13 +22,13 @@ import static org.apache.solr.handler.ClusterAPI.wrapParams; import static org.apache.solr.security.PermissionNameProvider.Name.COLL_EDIT_PERM; -import java.util.HashMap; import java.util.Map; import org.apache.solr.api.Command; import org.apache.solr.api.EndPoint; import org.apache.solr.api.PayloadObj; import org.apache.solr.client.solrj.request.beans.RebalanceLeadersPayload; import org.apache.solr.common.params.CollectionParams; +import org.apache.solr.common.util.SimpleOrderedMap; import org.apache.solr.handler.admin.CollectionsHandler; /** @@ -55,7 +55,7 @@ public RebalanceLeadersAPI(CollectionsHandler collectionsHandler) { @Command(name = V2_REBALANCE_LEADERS_CMD) public void rebalanceLeaders(PayloadObj obj) throws Exception { final RebalanceLeadersPayload v2Body = obj.get(); - final Map v1Params = v2Body.toMap(new HashMap<>()); + final Map v1Params = new SimpleOrderedMap<>(v2Body); v1Params.put(ACTION, CollectionParams.CollectionAction.REBALANCELEADERS.toLower()); v1Params.put(COLLECTION, obj.getRequest().getPathTemplateValues().get(COLLECTION)); diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/RejoinLeaderElectionAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/RejoinLeaderElectionAPI.java index 7558ea822ec9..951c2815b778 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/RejoinLeaderElectionAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/RejoinLeaderElectionAPI.java @@ -24,13 +24,13 @@ import static org.apache.solr.handler.ClusterAPI.wrapParams; import static org.apache.solr.security.PermissionNameProvider.Name.CORE_EDIT_PERM; -import java.util.HashMap; import java.util.Locale; import java.util.Map; import org.apache.solr.api.Command; import org.apache.solr.api.EndPoint; import org.apache.solr.api.PayloadObj; import org.apache.solr.client.solrj.request.beans.RejoinLeaderElectionPayload; +import org.apache.solr.common.util.SimpleOrderedMap; import org.apache.solr.handler.admin.CoreAdminHandler; /** @@ -56,7 +56,7 @@ public RejoinLeaderElectionAPI(CoreAdminHandler coreAdminHandler) { public void rejoinLeaderElection(PayloadObj payload) throws Exception { final RejoinLeaderElectionPayload v2Body = payload.get(); - final Map v1Params = v2Body.toMap(new HashMap<>()); + final Map v1Params = new SimpleOrderedMap<>(v2Body); v1Params.put(ACTION, REJOINLEADERELECTION.name().toLowerCase(Locale.ROOT)); if (v2Body.coreNodeName != null) { v1Params.remove("coreNodeName"); diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/RenameCoreAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/RenameCoreAPI.java index c2235af6894e..fb7dffccb0a8 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/RenameCoreAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/RenameCoreAPI.java @@ -21,7 +21,6 @@ import static org.apache.solr.handler.ClusterAPI.wrapParams; import static org.apache.solr.security.PermissionNameProvider.Name.CORE_EDIT_PERM; -import java.util.HashMap; import java.util.Locale; import java.util.Map; import org.apache.solr.api.Command; @@ -30,6 +29,7 @@ import org.apache.solr.common.annotation.JsonProperty; import org.apache.solr.common.params.CoreAdminParams; import org.apache.solr.common.util.ReflectMapWriter; +import org.apache.solr.common.util.SimpleOrderedMap; import org.apache.solr.handler.admin.CoreAdminHandler; /** @@ -54,7 +54,7 @@ public RenameCoreAPI(CoreAdminHandler coreHandler) { @Command(name = V2_RENAME_CORE_CMD) public void renameCore(PayloadObj obj) throws Exception { final RenameCorePayload v2Body = obj.get(); - final Map v1Params = v2Body.toMap(new HashMap<>()); + final Map v1Params = new SimpleOrderedMap<>(v2Body); v1Params.put( CoreAdminParams.ACTION, CoreAdminParams.CoreAdminAction.RENAME.name().toLowerCase(Locale.ROOT)); diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/RequestApplyCoreUpdatesAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/RequestApplyCoreUpdatesAPI.java index 51c20fb545f6..460e23497597 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/RequestApplyCoreUpdatesAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/RequestApplyCoreUpdatesAPI.java @@ -24,13 +24,13 @@ import static org.apache.solr.handler.ClusterAPI.wrapParams; import static org.apache.solr.security.PermissionNameProvider.Name.CORE_EDIT_PERM; -import java.util.HashMap; import java.util.Locale; import java.util.Map; import org.apache.solr.api.Command; import org.apache.solr.api.EndPoint; import org.apache.solr.api.PayloadObj; import org.apache.solr.client.solrj.request.beans.RequestApplyCoreUpdatesPayload; +import org.apache.solr.common.util.SimpleOrderedMap; import org.apache.solr.handler.admin.CoreAdminHandler; /** @@ -58,7 +58,7 @@ public RequestApplyCoreUpdatesAPI(CoreAdminHandler coreAdminHandler) { public void requestApplyCoreUpdates(PayloadObj obj) throws Exception { final RequestApplyCoreUpdatesPayload v2Body = obj.get(); - final Map v1Params = v2Body.toMap(new HashMap<>()); + final Map v1Params = new SimpleOrderedMap<>(v2Body); v1Params.put(ACTION, REQUESTAPPLYUPDATES.name().toLowerCase(Locale.ROOT)); v1Params.put(NAME, obj.getRequest().getPathTemplateValues().get("core")); diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/RequestBufferUpdatesAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/RequestBufferUpdatesAPI.java index 8625bfc9b72d..50d68cb92c03 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/RequestBufferUpdatesAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/RequestBufferUpdatesAPI.java @@ -23,7 +23,6 @@ import static org.apache.solr.handler.ClusterAPI.wrapParams; import static org.apache.solr.security.PermissionNameProvider.Name.CORE_EDIT_PERM; -import java.util.HashMap; import java.util.Locale; import java.util.Map; import org.apache.solr.api.Command; @@ -31,6 +30,7 @@ import org.apache.solr.api.PayloadObj; import org.apache.solr.client.solrj.request.beans.RequestBufferUpdatesPayload; import org.apache.solr.common.params.CoreAdminParams; +import org.apache.solr.common.util.SimpleOrderedMap; import org.apache.solr.handler.admin.CoreAdminHandler; /** @@ -57,7 +57,7 @@ public RequestBufferUpdatesAPI(CoreAdminHandler coreAdminHandler) { @Command(name = V2_REQUEST_BUFFER_UPDATES_CMD) public void requestBufferUpdates(PayloadObj obj) throws Exception { final RequestBufferUpdatesPayload v2Body = obj.get(); - final Map v1Params = v2Body.toMap(new HashMap<>()); + final Map v1Params = new SimpleOrderedMap<>(v2Body); v1Params.put(ACTION, REQUESTBUFFERUPDATES.name().toLowerCase(Locale.ROOT)); v1Params.put(CoreAdminParams.NAME, obj.getRequest().getPathTemplateValues().get("core")); diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/RequestCoreRecoveryAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/RequestCoreRecoveryAPI.java index a259c6084306..b86a19197629 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/RequestCoreRecoveryAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/RequestCoreRecoveryAPI.java @@ -24,13 +24,13 @@ import static org.apache.solr.handler.ClusterAPI.wrapParams; import static org.apache.solr.security.PermissionNameProvider.Name.CORE_EDIT_PERM; -import java.util.HashMap; import java.util.Locale; import java.util.Map; import org.apache.solr.api.Command; import org.apache.solr.api.EndPoint; import org.apache.solr.api.PayloadObj; import org.apache.solr.client.solrj.request.beans.RequestCoreRecoveryPayload; +import org.apache.solr.common.util.SimpleOrderedMap; import org.apache.solr.handler.admin.CoreAdminHandler; /** @@ -57,7 +57,7 @@ public RequestCoreRecoveryAPI(CoreAdminHandler coreAdminHandler) { @Command(name = V2_REQUEST_RECOVERY_CMD) public void requestCoreRecovery(PayloadObj obj) throws Exception { final RequestCoreRecoveryPayload v2Body = obj.get(); - final Map v1Params = v2Body.toMap(new HashMap<>()); + final Map v1Params = new SimpleOrderedMap<>(v2Body); v1Params.put(ACTION, REQUESTRECOVERY.name().toLowerCase(Locale.ROOT)); v1Params.put(CORE, obj.getRequest().getPathTemplateValues().get("core")); diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/RequestSyncShardAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/RequestSyncShardAPI.java index c36a99ce5450..5bf4f13a2fb9 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/RequestSyncShardAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/RequestSyncShardAPI.java @@ -24,13 +24,13 @@ import static org.apache.solr.handler.ClusterAPI.wrapParams; import static org.apache.solr.security.PermissionNameProvider.Name.CORE_EDIT_PERM; -import java.util.HashMap; import java.util.Locale; import java.util.Map; import org.apache.solr.api.Command; import org.apache.solr.api.EndPoint; import org.apache.solr.api.PayloadObj; import org.apache.solr.client.solrj.request.beans.RequestSyncShardPayload; +import org.apache.solr.common.util.SimpleOrderedMap; import org.apache.solr.handler.admin.CoreAdminHandler; /** @@ -57,7 +57,7 @@ public RequestSyncShardAPI(CoreAdminHandler coreAdminHandler) { @Command(name = V2_REQUEST_SYNC_SHARD_CMD) public void requestSyncShard(PayloadObj obj) throws Exception { final RequestSyncShardPayload v2Body = obj.get(); - final Map v1Params = v2Body.toMap(new HashMap<>()); + final Map v1Params = new SimpleOrderedMap<>(v2Body); v1Params.put(ACTION, REQUESTSYNCSHARD.name().toLowerCase(Locale.ROOT)); v1Params.put(CORE, obj.getRequest().getPathTemplateValues().get("core")); diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/SplitCoreAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/SplitCoreAPI.java index d846caea34bd..112b438aad52 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/SplitCoreAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/SplitCoreAPI.java @@ -24,7 +24,6 @@ import static org.apache.solr.handler.ClusterAPI.wrapParams; import static org.apache.solr.security.PermissionNameProvider.Name.CORE_EDIT_PERM; -import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; @@ -34,6 +33,7 @@ import org.apache.solr.common.annotation.JsonProperty; import org.apache.solr.common.params.CoreAdminParams; import org.apache.solr.common.util.ReflectMapWriter; +import org.apache.solr.common.util.SimpleOrderedMap; import org.apache.solr.handler.admin.CoreAdminHandler; /** @@ -58,7 +58,7 @@ public SplitCoreAPI(CoreAdminHandler coreHandler) { @Command(name = V2_SPLIT_CORE_CMD) public void splitCore(PayloadObj obj) throws Exception { final SplitCorePayload v2Body = obj.get(); - final Map v1Params = v2Body.toMap(new HashMap<>()); + final Map v1Params = new SimpleOrderedMap<>(v2Body); v1Params.put( CoreAdminParams.ACTION, CoreAdminParams.CoreAdminAction.SPLIT.name().toLowerCase(Locale.ROOT)); diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/SplitShardAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/SplitShardAPI.java index 0c75f053cae8..8e4513a9d67a 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/SplitShardAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/SplitShardAPI.java @@ -25,7 +25,6 @@ import static org.apache.solr.handler.api.V2ApiUtils.flattenMapWithPrefix; import static org.apache.solr.security.PermissionNameProvider.Name.COLL_EDIT_PERM; -import java.util.HashMap; import java.util.Map; import org.apache.solr.api.Command; import org.apache.solr.api.EndPoint; @@ -33,6 +32,7 @@ import org.apache.solr.client.solrj.request.beans.SplitShardPayload; import org.apache.solr.common.params.CollectionParams; import org.apache.solr.common.params.CommonAdminParams; +import org.apache.solr.common.util.SimpleOrderedMap; import org.apache.solr.common.util.StrUtils; import org.apache.solr.handler.admin.CollectionsHandler; @@ -60,7 +60,7 @@ public SplitShardAPI(CollectionsHandler collectionsHandler) { @Command(name = V2_SPLIT_CMD) public void splitShard(PayloadObj obj) throws Exception { final SplitShardPayload v2Body = obj.get(); - final Map v1Params = v2Body.toMap(new HashMap<>()); + final Map v1Params = new SimpleOrderedMap<>(v2Body); v1Params.put(ACTION, CollectionParams.CollectionAction.SPLITSHARD.toLower()); v1Params.put(COLLECTION, obj.getRequest().getPathTemplateValues().get(COLLECTION)); diff --git a/solr/core/src/java/org/apache/solr/handler/designer/ManagedSchemaDiff.java b/solr/core/src/java/org/apache/solr/handler/designer/ManagedSchemaDiff.java index 17e26923c2ea..f34576ac7b80 100644 --- a/solr/core/src/java/org/apache/solr/handler/designer/ManagedSchemaDiff.java +++ b/solr/core/src/java/org/apache/solr/handler/designer/ManagedSchemaDiff.java @@ -29,6 +29,7 @@ import java.util.stream.Stream; import org.apache.solr.common.util.SimpleOrderedMap; import org.apache.solr.common.util.SuppressForbidden; +import org.apache.solr.common.util.Utils; import org.apache.solr.schema.FieldType; import org.apache.solr.schema.IndexSchema; import org.apache.solr.schema.ManagedIndexSchema; @@ -219,8 +220,8 @@ protected static Map diff( @SuppressForbidden(reason = "Maps.difference") private static List> getMapDifference( SimpleOrderedMap simpleOrderedMap1, SimpleOrderedMap simpleOrderedMap2) { - Map map1 = simpleOrderedMap1.toMap(new HashMap<>()); - Map map2 = simpleOrderedMap2.toMap(new HashMap<>()); + Map map1 = Utils.convertToMap(simpleOrderedMap1, new HashMap<>()); + Map map2 = Utils.convertToMap(simpleOrderedMap2, new HashMap<>()); Map> mapDiff = Maps.difference(map1, map2).entriesDiffering(); if (mapDiff.isEmpty()) { diff --git a/solr/core/src/java/org/apache/solr/handler/export/ExportWriterStream.java b/solr/core/src/java/org/apache/solr/handler/export/ExportWriterStream.java index 8700064bba70..86bbefb8e37d 100644 --- a/solr/core/src/java/org/apache/solr/handler/export/ExportWriterStream.java +++ b/solr/core/src/java/org/apache/solr/handler/export/ExportWriterStream.java @@ -19,9 +19,7 @@ import java.io.IOException; import java.lang.invoke.MethodHandles; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.TimeoutException; import org.apache.solr.client.solrj.io.Tuple; @@ -39,6 +37,7 @@ import org.apache.solr.client.solrj.io.stream.expr.StreamFactory; import org.apache.solr.common.IteratorWriter; import org.apache.solr.common.MapWriter; +import org.apache.solr.common.util.SimpleOrderedMap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -71,9 +70,7 @@ public EntryWriter put(CharSequence k, Object v) throws IOException { ((IteratorWriter) v).toList(lst); v = lst; } else if (v instanceof MapWriter) { - Map map = new HashMap<>(); - ((MapWriter) v).toMap(map); - v = map; + v = new SimpleOrderedMap<>((MapWriter) v); } tuple.put(k.toString(), v); return this; diff --git a/solr/core/src/java/org/apache/solr/schema/IndexSchema.java b/solr/core/src/java/org/apache/solr/schema/IndexSchema.java index 3372bcae0650..62db45d2d01d 100644 --- a/solr/core/src/java/org/apache/solr/schema/IndexSchema.java +++ b/solr/core/src/java/org/apache/solr/schema/IndexSchema.java @@ -29,7 +29,6 @@ import java.util.Collections; import java.util.HashMap; import java.util.HashSet; -import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Locale; @@ -57,7 +56,7 @@ import org.apache.lucene.util.Version; import org.apache.solr.analysis.TokenizerChain; import org.apache.solr.common.ConfigNode; -import org.apache.solr.common.MapSerializable; +import org.apache.solr.common.MapWriter; import org.apache.solr.common.SolrDocument; import org.apache.solr.common.SolrException; import org.apache.solr.common.SolrException.ErrorCode; @@ -69,7 +68,6 @@ import org.apache.solr.common.params.SolrParams; import org.apache.solr.common.util.Cache; import org.apache.solr.common.util.NamedList; -import org.apache.solr.common.util.Pair; import org.apache.solr.common.util.SimpleOrderedMap; import org.apache.solr.core.ConfigSetService; import org.apache.solr.core.SolrCore; @@ -1557,7 +1555,7 @@ public Map getNamedPropertyValues() { return getNamedPropertyValues(null, new MapSolrParams(Collections.emptyMap())); } - public static class SchemaProps implements MapSerializable { + public static class SchemaProps implements MapWriter { private static final String SOURCE_FIELD_LIST = IndexSchema.SOURCE + "." + CommonParams.FL; private static final String DESTINATION_FIELD_LIST = IndexSchema.DESTINATION + "." + CommonParams.FL; @@ -1683,12 +1681,13 @@ SimpleOrderedMap getProperties(SchemaField sf) { } @Override - public Map toMap(Map map) { - return Stream.of(Handler.values()) - .filter(it -> name == null || it.nameLower.equals(name)) - .map(it -> new Pair<>(it.realName, it.fun.apply(this))) - .filter(it -> it.second() != null) - .collect(Collectors.toMap(Pair::first, Pair::second, (v1, v2) -> v2, LinkedHashMap::new)); + public void writeMap(EntryWriter ew) throws IOException { + for (Handler it : Handler.values()) { + if (name == null || it.nameLower.equals(name)) { + Object val = it.fun.apply(this); + if (val != null) ew.put(it.realName, val); + } + } } } @@ -1699,7 +1698,7 @@ public Map toMap(Map map) { SchemaProps.Handler::getNameLower, SchemaProps.Handler::getRealName)); public Map getNamedPropertyValues(String name, SolrParams params) { - return new SchemaProps(name, params, this).toMap(new LinkedHashMap<>()); + return new SimpleOrderedMap<>(new SchemaProps(name, params, this)); } /** diff --git a/solr/core/src/java/org/apache/solr/search/CacheConfig.java b/solr/core/src/java/org/apache/solr/search/CacheConfig.java index da05152a86d3..2009b000a9f2 100644 --- a/solr/core/src/java/org/apache/solr/search/CacheConfig.java +++ b/solr/core/src/java/org/apache/solr/search/CacheConfig.java @@ -18,6 +18,7 @@ import static org.apache.solr.common.params.CommonParams.NAME; +import java.io.IOException; import java.lang.invoke.MethodHandles; import java.util.Collections; import java.util.HashMap; @@ -26,8 +27,9 @@ import java.util.Map; import java.util.function.Supplier; import org.apache.solr.common.ConfigNode; -import org.apache.solr.common.MapSerializable; +import org.apache.solr.common.MapWriter; import org.apache.solr.common.util.CollectionUtil; +import org.apache.solr.common.util.NamedList; import org.apache.solr.core.PluginInfo; import org.apache.solr.core.SolrConfig; import org.apache.solr.core.SolrResourceLoader; @@ -38,7 +40,7 @@ * Contains the knowledge of how cache config is stored in the solrconfig.xml file, and implements a * factory to create caches. */ -public class CacheConfig implements MapSerializable { +public class CacheConfig implements MapWriter { private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); private String nodeName; @@ -176,9 +178,8 @@ public SolrCache newInstance() { } @Override - public Map toMap(Map argsMap) { - // TODO: Should not create new HashMap? - return new HashMap<>(args); + public void writeMap(EntryWriter ew) throws IOException { + new NamedList<>(args).writeMap(ew); } public String getNodeName() { diff --git a/solr/core/src/java/org/apache/solr/update/IndexFingerprint.java b/solr/core/src/java/org/apache/solr/update/IndexFingerprint.java index 8a62ce299b1a..1323c9eb083c 100644 --- a/solr/core/src/java/org/apache/solr/update/IndexFingerprint.java +++ b/solr/core/src/java/org/apache/solr/update/IndexFingerprint.java @@ -19,17 +19,17 @@ import java.io.IOException; import java.lang.invoke.MethodHandles; -import java.util.LinkedHashMap; import java.util.Map; import java.util.Objects; import org.apache.lucene.index.LeafReaderContext; import org.apache.lucene.queries.function.FunctionValues; import org.apache.lucene.queries.function.ValueSource; import org.apache.lucene.util.Bits; -import org.apache.solr.common.MapSerializable; +import org.apache.solr.common.MapWriter; import org.apache.solr.common.SolrException; import org.apache.solr.common.util.Hash; import org.apache.solr.common.util.NamedList; +import org.apache.solr.common.util.SimpleOrderedMap; import org.apache.solr.core.SolrCore; import org.apache.solr.schema.SchemaField; import org.apache.solr.search.SolrIndexSearcher; @@ -41,7 +41,7 @@ /** * @lucene.internal */ -public class IndexFingerprint implements MapSerializable { +public class IndexFingerprint implements MapWriter { private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); private long maxVersionSpecified; @@ -177,15 +177,14 @@ public static int compare(IndexFingerprint f1, IndexFingerprint f2) { } @Override - public Map toMap(Map map) { - map.put("maxVersionSpecified", maxVersionSpecified); - map.put("maxVersionEncountered", maxVersionEncountered); - map.put("maxInHash", maxInHash); - map.put("versionsHash", versionsHash); - map.put("numVersions", numVersions); - map.put("numDocs", numDocs); - map.put("maxDoc", maxDoc); - return map; + public void writeMap(EntryWriter ew) throws IOException { + ew.put("maxVersionSpecified", maxVersionSpecified) + .put("maxVersionEncountered", maxVersionEncountered) + .put("maxInHash", maxInHash) + .put("versionsHash", versionsHash) + .put("numVersions", numVersions) + .put("numDocs", numDocs) + .put("maxDoc", maxDoc); } private static long getLong(Map m, String key, long def) { @@ -218,7 +217,7 @@ public static IndexFingerprint fromObject(Object o) { @Override public String toString() { - return toMap(new LinkedHashMap<>()).toString(); + return new SimpleOrderedMap<>(this).toString(); } @Override diff --git a/solr/core/src/java/org/apache/solr/update/SolrIndexConfig.java b/solr/core/src/java/org/apache/solr/update/SolrIndexConfig.java index 19a8e0135b93..069f0174ccb8 100644 --- a/solr/core/src/java/org/apache/solr/update/SolrIndexConfig.java +++ b/solr/core/src/java/org/apache/solr/update/SolrIndexConfig.java @@ -22,7 +22,6 @@ import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.util.Collections; -import java.util.Map; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.DelegatingAnalyzerWrapper; import org.apache.lucene.index.ConcurrentMergeScheduler; @@ -33,7 +32,7 @@ import org.apache.lucene.search.Sort; import org.apache.lucene.util.InfoStream; import org.apache.solr.common.ConfigNode; -import org.apache.solr.common.MapSerializable; +import org.apache.solr.common.MapWriter; import org.apache.solr.common.util.NamedList; import org.apache.solr.common.util.SuppressForbidden; import org.apache.solr.core.DirectoryFactory; @@ -54,7 +53,7 @@ * This config object encapsulates IndexWriter config params, defined in the <indexConfig> * section of solrconfig.xml */ -public class SolrIndexConfig implements MapSerializable { +public class SolrIndexConfig implements MapWriter { private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); private static final String NO_SUB_PACKAGES[] = new String[0]; @@ -196,28 +195,19 @@ public SolrIndexConfig(ConfigNode cfg, SolrIndexConfig def) { } @Override - public Map toMap(Map map) { - map.put("useCompoundFile", useCompoundFile); - map.put("maxBufferedDocs", maxBufferedDocs); - map.put("ramBufferSizeMB", ramBufferSizeMB); - map.put("ramPerThreadHardLimitMB", ramPerThreadHardLimitMB); - map.put("maxCommitMergeWaitTime", maxCommitMergeWaitMillis); - map.put("writeLockTimeout", writeLockTimeout); - map.put("lockType", lockType); - map.put("infoStreamEnabled", infoStream != InfoStream.NO_OUTPUT); - if (mergeSchedulerInfo != null) { - map.put("mergeScheduler", mergeSchedulerInfo); - } - if (metricsInfo != null) { - map.put("metrics", metricsInfo); - } - if (mergePolicyFactoryInfo != null) { - map.put("mergePolicyFactory", mergePolicyFactoryInfo); - } - if (mergedSegmentWarmerInfo != null) { - map.put("mergedSegmentWarmer", mergedSegmentWarmerInfo); - } - return map; + public void writeMap(EntryWriter ew) throws IOException { + ew.put("useCompoundFile", useCompoundFile) + .put("maxBufferedDocs", maxBufferedDocs) + .put("ramBufferSizeMB", ramBufferSizeMB) + .put("ramPerThreadHardLimitMB", ramPerThreadHardLimitMB) + .put("maxCommitMergeWaitTime", maxCommitMergeWaitMillis) + .put("writeLockTimeout", writeLockTimeout) + .put("lockType", lockType) + .put("infoStreamEnabled", infoStream != InfoStream.NO_OUTPUT) + .putIfNotNull("mergeScheduler", mergeSchedulerInfo) + .putIfNotNull("metrics", metricsInfo) + .putIfNotNull("mergePolicyFactory", mergePolicyFactoryInfo) + .putIfNotNull("mergedSegmentWarmer", mergedSegmentWarmerInfo); } private PluginInfo getPluginInfo(ConfigNode node, PluginInfo def) { diff --git a/solr/core/src/test/org/apache/solr/api/NodeConfigClusterPluginsSourceTest.java b/solr/core/src/test/org/apache/solr/api/NodeConfigClusterPluginsSourceTest.java index a50979b34186..da7d017e6732 100644 --- a/solr/core/src/test/org/apache/solr/api/NodeConfigClusterPluginsSourceTest.java +++ b/solr/core/src/test/org/apache/solr/api/NodeConfigClusterPluginsSourceTest.java @@ -18,7 +18,6 @@ package org.apache.solr.api; import java.util.Collections; -import java.util.HashMap; import java.util.Map; import org.apache.solr.client.solrj.RemoteSolrException; import org.apache.solr.client.solrj.request.V2Request; @@ -30,6 +29,7 @@ import org.apache.solr.common.MapWriter; import org.apache.solr.common.annotation.JsonProperty; import org.apache.solr.common.util.ReflectMapWriter; +import org.apache.solr.common.util.SimpleOrderedMap; import org.apache.solr.core.CoreContainer; import org.junit.BeforeClass; import org.junit.Test; @@ -90,8 +90,7 @@ public void testClusterSingletonsRegistered() { apiInfo.getInfo().klass); MapWriter config = apiInfo.getInfo().config; assertNotNull("config should be set for " + SingletonWithConfig.NAME, config); - Map configMap = new HashMap<>(); - config.toMap(configMap); + Map configMap = new SimpleOrderedMap<>(config); assertEquals("incorrect config val for cfgInt parameter", CFG_VAL, configMap.get("cfgInt")); } diff --git a/solr/core/src/test/org/apache/solr/core/CacheConfigTest.java b/solr/core/src/test/org/apache/solr/core/CacheConfigTest.java index f8825a7f1085..8eb503dbaf72 100644 --- a/solr/core/src/test/org/apache/solr/core/CacheConfigTest.java +++ b/solr/core/src/test/org/apache/solr/core/CacheConfigTest.java @@ -20,7 +20,6 @@ import static org.mockito.Mockito.when; import java.util.Arrays; -import java.util.HashMap; import java.util.Map; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; @@ -28,6 +27,7 @@ import org.apache.solr.SolrTestCaseJ4; import org.apache.solr.common.ConfigNode; import org.apache.solr.common.SolrException; +import org.apache.solr.common.util.SimpleOrderedMap; import org.apache.solr.search.CacheConfig; import org.apache.solr.util.DOMConfigNode; import org.junit.Before; @@ -91,7 +91,7 @@ public void testSolrConfigPropsForCache() { final CacheConfig cacheConfig = CacheConfig.getConfig(mockSolrConfig, domConfigNode, XPATH_DOCUMENT_CACHE); assertNotNull(cacheConfig); - final Map args = cacheConfig.toMap(new HashMap<>()); + final Map args = new SimpleOrderedMap<>(cacheConfig); assertNotNull(args); assertEquals("99", args.get("initialSize")); assertEquals("999", args.get("size")); @@ -119,7 +119,7 @@ public void testOverlayPropsOverridingSolrConfigProps() { final CacheConfig cacheConfig = CacheConfig.getConfig(mockSolrConfig, domConfigNode, XPATH_DOCUMENT_CACHE); assertNotNull(cacheConfig); - final Map args = cacheConfig.toMap(new HashMap<>()); + final Map args = new SimpleOrderedMap<>(cacheConfig); assertNotNull(args); assertEquals(overlaidSize, args.get("size")); } @@ -146,7 +146,7 @@ public void testOverlaidEnabledSolrConfigDisabledCache() { final CacheConfig cacheConfig = CacheConfig.getConfig(mockSolrConfig, overlayConfigNode, XPATH_QUERY_RESULT_CACHE); assertNotNull(cacheConfig); - final Map args = cacheConfig.toMap(new HashMap<>()); + final Map args = new SimpleOrderedMap<>(cacheConfig); assertNotNull(args); assertEquals("99", args.get("initialSize")); assertEquals("queryResultCache", cacheConfig.getNodeName()); diff --git a/solr/core/src/test/org/apache/solr/core/TestConfig.java b/solr/core/src/test/org/apache/solr/core/TestConfig.java index a785b3c731bc..d8d6a76f6fcd 100644 --- a/solr/core/src/test/org/apache/solr/core/TestConfig.java +++ b/solr/core/src/test/org/apache/solr/core/TestConfig.java @@ -19,12 +19,12 @@ import java.io.IOException; import java.io.InputStream; import java.util.Collections; -import java.util.LinkedHashMap; import org.apache.lucene.index.ConcurrentMergeScheduler; import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.index.TieredMergePolicy; import org.apache.lucene.util.InfoStream; import org.apache.solr.SolrTestCaseJ4; +import org.apache.solr.common.util.SimpleOrderedMap; import org.apache.solr.schema.IndexSchema; import org.apache.solr.schema.IndexSchemaFactory; import org.apache.solr.search.CacheConfig; @@ -168,10 +168,10 @@ public void testDefaults() throws Exception { assertNull("non-null mergedSegmentWarmer", iwc.getMergedSegmentWarmer()); - final int numDefaultsMapped = sic.toMap(new LinkedHashMap<>()).size(); + final int numDefaultsMapped = new SimpleOrderedMap<>(sic).size(); assertEquals( "numDefaultsTested vs. numDefaultsMapped+numNullDefaults =" - + sic.toMap(new LinkedHashMap<>()).keySet(), + + new SimpleOrderedMap<>(sic).keySet(), numDefaultsTested, numDefaultsMapped + numNullDefaults); } diff --git a/solr/core/src/test/org/apache/solr/handler/designer/TestSchemaDesignerAPI.java b/solr/core/src/test/org/apache/solr/handler/designer/TestSchemaDesignerAPI.java index 0822693db8d7..e624cfcb9927 100644 --- a/solr/core/src/test/org/apache/solr/handler/designer/TestSchemaDesignerAPI.java +++ b/solr/core/src/test/org/apache/solr/handler/designer/TestSchemaDesignerAPI.java @@ -29,7 +29,6 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; @@ -850,7 +849,7 @@ public void testSchemaDiffEndpoint() throws Exception { idFieldMapUpdated.indexOf("omitTermFreqAndPositions", 0), Boolean.FALSE); SolrParams solrParams = idFieldMapUpdated.toSolrParams(); - Map mapParams = solrParams.toMap(new HashMap<>()); + Map mapParams = new SimpleOrderedMap<>(solrParams); mapParams.put("termVectors", Boolean.FALSE); reqParams.set( SCHEMA_VERSION_PARAM, rsp.getValues().toSolrParams().getInt(SCHEMA_VERSION_PARAM)); diff --git a/solr/core/src/test/org/apache/solr/update/SolrIndexConfigTest.java b/solr/core/src/test/org/apache/solr/update/SolrIndexConfigTest.java index 79f936ddd2fa..888ff1c470da 100644 --- a/solr/core/src/test/org/apache/solr/update/SolrIndexConfigTest.java +++ b/solr/core/src/test/org/apache/solr/update/SolrIndexConfigTest.java @@ -17,7 +17,6 @@ package org.apache.solr.update; import java.nio.file.Path; -import java.util.LinkedHashMap; import java.util.Map; import org.apache.lucene.index.ConcurrentMergeScheduler; import org.apache.lucene.index.IndexWriterConfig; @@ -29,8 +28,9 @@ import org.apache.lucene.search.Sort; import org.apache.lucene.search.SortField; import org.apache.solr.SolrTestCaseJ4; -import org.apache.solr.common.MapSerializable; +import org.apache.solr.common.MapWriter; import org.apache.solr.common.SolrException; +import org.apache.solr.common.util.SimpleOrderedMap; import org.apache.solr.core.DirectoryFactory; import org.apache.solr.core.SolrConfig; import org.apache.solr.core.TestMergePolicyConfig; @@ -265,7 +265,7 @@ public void testToMap() throws Exception { } assertNotNull(solrIndexConfig.mergeSchedulerInfo); - Map m = solrIndexConfig.toMap(new LinkedHashMap<>()); + Map m = new SimpleOrderedMap<>(solrIndexConfig); int mSizeExpected = 0; ++mSizeExpected; @@ -304,12 +304,12 @@ public void testToMap() throws Exception { } ++mSizeExpected; - assertTrue(m.get("mergeScheduler") instanceof MapSerializable); + assertTrue(m.get("mergeScheduler") instanceof MapWriter); ++mSizeExpected; - assertTrue(m.get("mergePolicyFactory") instanceof MapSerializable); + assertTrue(m.get("mergePolicyFactory") instanceof MapWriter); if (solrConfigFileName.equals(solrConfigFileNameWarmerRandomMergePolicyFactory)) { ++mSizeExpected; - assertTrue(m.get("mergedSegmentWarmer") instanceof MapSerializable); + assertTrue(m.get("mergedSegmentWarmer") instanceof MapWriter); } else { assertNull(m.get("mergedSegmentWarmer")); } diff --git a/solr/modules/extraction/src/java/org/apache/solr/handler/extraction/TikaServerExtractionBackend.java b/solr/modules/extraction/src/java/org/apache/solr/handler/extraction/TikaServerExtractionBackend.java index c21a0c01e093..d783775c7be1 100644 --- a/solr/modules/extraction/src/java/org/apache/solr/handler/extraction/TikaServerExtractionBackend.java +++ b/solr/modules/extraction/src/java/org/apache/solr/handler/extraction/TikaServerExtractionBackend.java @@ -33,6 +33,7 @@ import org.apache.solr.common.SolrException; import org.apache.solr.common.util.ExecutorUtil; import org.apache.solr.common.util.NamedList; +import org.apache.solr.common.util.SimpleOrderedMap; import org.apache.solr.common.util.SolrNamedThreadFactory; import org.apache.solr.util.RefCounted; import org.apache.tika.sax.BodyContentHandler; @@ -96,7 +97,7 @@ public TikaServerExtractionBackend( this.maxCharsLimit = maxCharsLimit; if (initArgs != null) { - initArgs.toMap(this.initArgsMap); + initArgsMap.putAll(new SimpleOrderedMap<>(initArgs)); } Object metaCompatObh = this.initArgsMap.get(ExtractingParams.TIKASERVER_METADATA_COMPATIBILITY); if (metaCompatObh != null) { diff --git a/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/stream/expr/Explanation.java b/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/stream/expr/Explanation.java index 259c02ab5e50..bee23cc4acfe 100644 --- a/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/stream/expr/Explanation.java +++ b/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/stream/expr/Explanation.java @@ -16,14 +16,13 @@ */ package org.apache.solr.client.solrj.io.stream.expr; +import java.io.IOException; import java.util.ArrayList; -import java.util.LinkedHashMap; import java.util.List; -import java.util.Map; -import org.apache.solr.common.MapSerializable; +import org.apache.solr.common.MapWriter; /** Explanation containing details about a expression */ -public class Explanation implements MapSerializable { +public class Explanation implements MapWriter { private String expressionNodeId; private String expressionType; @@ -139,35 +138,14 @@ public void addHelper(Explanation helper) { } @Override - public Map toMap(Map map) { - if (null != expressionNodeId) { - map.put("expressionNodeId", expressionNodeId); - } - if (null != expressionType) { - map.put("expressionType", expressionType); - } - if (null != functionName) { - map.put("functionName", functionName); - } - if (null != implementingClass) { - map.put("implementingClass", implementingClass); - } - if (null != expression) { - map.put("expression", expression); - } - if (null != note) { - map.put("note", note); - } - - if (null != helpers && 0 != helpers.size()) { - List> helperMaps = new ArrayList<>(); - for (Explanation helper : helpers) { - helperMaps.add(helper.toMap(new LinkedHashMap<>())); - } - map.put("helpers", helperMaps); - } - - return map; + public void writeMap(EntryWriter ew) throws IOException { + ew.putIfNotNull("expressionNodeId", expressionNodeId) + .putIfNotNull("expressionType", expressionType) + .putIfNotNull("functionName", functionName) + .putIfNotNull("implementingClass", implementingClass) + .putIfNotNull("expression", expression) + .putIfNotNull("note", note) + .putIfNotNull("helpers", helpers); } public static interface ExpressionType { diff --git a/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/stream/expr/StreamExplanation.java b/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/stream/expr/StreamExplanation.java index 027a1b94878c..c76eeece7e68 100644 --- a/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/stream/expr/StreamExplanation.java +++ b/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/stream/expr/StreamExplanation.java @@ -16,10 +16,9 @@ */ package org.apache.solr.client.solrj.io.stream.expr; +import java.io.IOException; import java.util.ArrayList; -import java.util.LinkedHashMap; import java.util.List; -import java.util.Map; /** Explanation containing details about a stream expression */ public class StreamExplanation extends Explanation { @@ -58,17 +57,12 @@ public void addChild(Explanation child) { } @Override - public Map toMap(Map map) { - map = super.toMap(map); - - if (null != children && 0 != children.size()) { - List> childrenMaps = new ArrayList<>(); + public void writeMap(EntryWriter ew) throws IOException { + super.writeMap(ew); + if (children != null) { for (Explanation child : children) { - childrenMaps.add(child.toMap(new LinkedHashMap<>())); + child.writeMap(ew); } - map.put("children", childrenMaps); } - - return map; } } diff --git a/solr/solrj/src/java/org/apache/solr/common/IteratorWriter.java b/solr/solrj/src/java/org/apache/solr/common/IteratorWriter.java index 1c2274b7c0f4..631a2f8677d9 100644 --- a/solr/solrj/src/java/org/apache/solr/common/IteratorWriter.java +++ b/solr/solrj/src/java/org/apache/solr/common/IteratorWriter.java @@ -19,8 +19,8 @@ import java.io.IOException; import java.util.ArrayList; -import java.util.LinkedHashMap; import java.util.List; +import org.apache.solr.common.util.SimpleOrderedMap; import org.noggit.JSONWriter; /** Interface to help do push writing to an array */ @@ -76,7 +76,7 @@ default List toList(List l) { new ItemWriter() { @Override public ItemWriter add(Object o) throws IOException { - if (o instanceof MapWriter) o = ((MapWriter) o).toMap(new LinkedHashMap<>()); + if (o instanceof MapWriter) o = new SimpleOrderedMap<>((MapWriter) o); if (o instanceof IteratorWriter) o = ((IteratorWriter) o).toList(new ArrayList<>()); l.add(o); return this; diff --git a/solr/solrj/src/java/org/apache/solr/common/MapSerializable.java b/solr/solrj/src/java/org/apache/solr/common/MapSerializable.java deleted file mode 100644 index e5d6ebafa92d..000000000000 --- a/solr/solrj/src/java/org/apache/solr/common/MapSerializable.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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.solr.common; - -import java.util.Map; - -/** - * This is to facilitate just in time creation of objects before writing it to the response. - * - * @deprecated Use {@link MapWriter} instead - */ -@Deprecated -public interface MapSerializable { - /** - * Use the passed map to minimize object creation. Do not keep a reference to the passed map and - * reuse it. it may be reused by the framework - */ - Map toMap(Map map); -} diff --git a/solr/solrj/src/java/org/apache/solr/common/MapWriter.java b/solr/solrj/src/java/org/apache/solr/common/MapWriter.java index d0e52f6892f7..165517c467e4 100644 --- a/solr/solrj/src/java/org/apache/solr/common/MapWriter.java +++ b/solr/solrj/src/java/org/apache/solr/common/MapWriter.java @@ -19,7 +19,6 @@ import java.io.IOException; import java.util.Collections; -import java.util.Map; import java.util.function.BiConsumer; import java.util.function.BiPredicate; import java.util.function.Supplier; @@ -31,7 +30,7 @@ * and is supposed to be memory efficient. If the entries are primitives, unnecessary boxing is also * avoided. */ -public interface MapWriter extends MapSerializable, NavigableObject, JSONWriter.Writable { +public interface MapWriter extends NavigableObject, JSONWriter.Writable { /** Writes this object's entries out to {@code ew}. */ void writeMap(EntryWriter ew) throws IOException; @@ -40,11 +39,6 @@ default String jsonStr() { return Utils.toJSONString(this); } - @Override - default Map toMap(Map map) { - return Utils.convertToMap(this, map); - } - /** For implementing Noggit {@link org.noggit.JSONWriter.Writable}. */ @Override default void write(JSONWriter writer) { @@ -148,7 +142,7 @@ default EntryWriter put(CharSequence k, CharSequence v) throws IOException { } default BiConsumer getBiConsumer() { - return (k, v) -> putNoEx(k, v); + return this::putNoEx; } } diff --git a/solr/solrj/src/java/org/apache/solr/common/MapWriterMap.java b/solr/solrj/src/java/org/apache/solr/common/MapWriterMap.java index 44385d849f53..454898afc112 100644 --- a/solr/solrj/src/java/org/apache/solr/common/MapWriterMap.java +++ b/solr/solrj/src/java/org/apache/solr/common/MapWriterMap.java @@ -50,9 +50,4 @@ public Object _get(List path, Object def) { public int _size() { return delegate.size(); } - - @Override - public Map toMap(Map map) { - return delegate; - } } diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/ZkNodeProps.java b/solr/solrj/src/java/org/apache/solr/common/cloud/ZkNodeProps.java index 1e44d700342a..0f1040915872 100644 --- a/solr/solrj/src/java/org/apache/solr/common/cloud/ZkNodeProps.java +++ b/solr/solrj/src/java/org/apache/solr/common/cloud/ZkNodeProps.java @@ -27,6 +27,7 @@ import java.util.Set; import org.apache.solr.common.MapWriter; import org.apache.solr.common.util.JavaBinCodec; +import org.apache.solr.common.util.SimpleOrderedMap; import org.apache.solr.common.util.Utils; /** ZkNodeProps contains generic immutable properties. */ @@ -43,7 +44,7 @@ public ZkNodeProps(Map propMap) { } public ZkNodeProps(MapWriter mw) { - propMap = mw.toMap(new HashMap<>()); + propMap = new SimpleOrderedMap<>(mw); } public ZkNodeProps plus(String key, Object val) { diff --git a/solr/solrj/src/java/org/apache/solr/common/util/JavaBinCodec.java b/solr/solrj/src/java/org/apache/solr/common/util/JavaBinCodec.java index a19896ff2b3a..53b63fb5fb4a 100644 --- a/solr/solrj/src/java/org/apache/solr/common/util/JavaBinCodec.java +++ b/solr/solrj/src/java/org/apache/solr/common/util/JavaBinCodec.java @@ -47,7 +47,6 @@ import org.apache.solr.common.EnumFieldValue; import org.apache.solr.common.IteratorWriter; import org.apache.solr.common.IteratorWriter.ItemWriter; -import org.apache.solr.common.MapSerializable; import org.apache.solr.common.MapWriter; import org.apache.solr.common.PushWriter; import org.apache.solr.common.SolrDocument; @@ -427,11 +426,6 @@ public boolean writeKnownType(Object val) throws IOException { writeMapEntry((Map.Entry) val); return true; } - if (val instanceof MapSerializable) { - // todo find a better way to reuse the map more efficiently - writeMap(((MapSerializable) val).toMap(new NamedList().asShallowMap())); - return true; - } if (val instanceof AtomicInteger) { writeInt(((AtomicInteger) val).get()); return true; diff --git a/solr/solrj/src/java/org/apache/solr/common/util/TextWriter.java b/solr/solrj/src/java/org/apache/solr/common/util/TextWriter.java index 6901b2db5ed8..ea50ab8bbbc7 100644 --- a/solr/solrj/src/java/org/apache/solr/common/util/TextWriter.java +++ b/solr/solrj/src/java/org/apache/solr/common/util/TextWriter.java @@ -27,7 +27,6 @@ import java.util.Collection; import java.util.Date; import java.util.Iterator; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; @@ -38,7 +37,6 @@ import org.apache.solr.client.api.util.ReflectWritable; import org.apache.solr.common.EnumFieldValue; import org.apache.solr.common.IteratorWriter; -import org.apache.solr.common.MapSerializable; import org.apache.solr.common.MapWriter; import org.apache.solr.common.PushWriter; @@ -89,9 +87,6 @@ default void writeVal(String name, Object val, boolean raw) throws IOException { writeMap(name, (MapWriter) val); } else if (val instanceof ReflectWritable) { writeVal(name, Utils.getReflectWriter(val)); - } else if (val instanceof MapSerializable) { - // todo find a better way to reuse the map more efficiently - writeMap(name, ((MapSerializable) val).toMap(new LinkedHashMap<>()), false, true); } else if (val instanceof Map) { writeMap(name, (Map) val, false, true); } else if (val instanceof Collection cval) { // very generic; keep towards the end diff --git a/solr/solrj/src/java/org/apache/solr/common/util/Utils.java b/solr/solrj/src/java/org/apache/solr/common/util/Utils.java index 1e2f69da9727..a44596a216de 100644 --- a/solr/solrj/src/java/org/apache/solr/common/util/Utils.java +++ b/solr/solrj/src/java/org/apache/solr/common/util/Utils.java @@ -179,7 +179,7 @@ public MapWriter.EntryWriter put(CharSequence k, Object v) { private static Object makeDeepCopy(Object v, int maxDepth, boolean mutable, boolean sorted) { if (v instanceof MapWriter && maxDepth > 1) { - v = ((MapWriter) v).toMap(new LinkedHashMap<>()); + v = new SimpleOrderedMap<>((MapWriter) v); } else if (v instanceof IteratorWriter && maxDepth > 1) { List l = ((IteratorWriter) v).toList(new ArrayList<>()); if (sorted) { @@ -1027,7 +1027,7 @@ private static void addCatchAllFieldWriter( *

The provided object is not required to be a {@link MapWriter}. */ public static Map reflectToMap(Object toReflect) { - return ((Utils.DelegateReflectWriter) Utils.getReflectWriter(toReflect)).toMap(new HashMap<>()); + return convertToMap((MapWriter) Utils.getReflectWriter(toReflect), new HashMap<>()); } @SuppressWarnings({"unchecked", "rawtypes"}) @@ -1041,12 +1041,13 @@ public MapWriter.EntryWriter put(CharSequence k, Object v) { } private MapWriter.EntryWriter writeEntry(CharSequence k, Object v) { - if (v instanceof MapWriter) v = ((MapWriter) v).toMap(new LinkedHashMap<>()); + if (v instanceof MapWriter) v = convertToMap((MapWriter) v, new LinkedHashMap<>()); if (v instanceof IteratorWriter) v = ((IteratorWriter) v).toList(new ArrayList<>()); if (v instanceof Iterable) { List lst = new ArrayList(); for (Object vv : (Iterable) v) { - if (vv instanceof MapWriter) vv = ((MapWriter) vv).toMap(new LinkedHashMap<>()); + if (vv instanceof MapWriter) + vv = convertToMap((MapWriter) vv, new LinkedHashMap<>()); if (vv instanceof IteratorWriter) vv = ((IteratorWriter) vv).toList(new ArrayList<>()); lst.add(vv); @@ -1057,7 +1058,8 @@ private MapWriter.EntryWriter writeEntry(CharSequence k, Object v) { Map map = new LinkedHashMap(); for (Map.Entry entry : ((Map) v).entrySet()) { Object vv = entry.getValue(); - if (vv instanceof MapWriter) vv = ((MapWriter) vv).toMap(new LinkedHashMap<>()); + if (vv instanceof MapWriter) + vv = convertToMap((MapWriter) vv, new LinkedHashMap<>()); if (vv instanceof IteratorWriter) vv = ((IteratorWriter) vv).toList(new ArrayList<>()); map.put(entry.getKey(), vv); diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleCborTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleCborTest.java index b281a4557ce5..888e7160518a 100644 --- a/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleCborTest.java +++ b/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleCborTest.java @@ -23,7 +23,6 @@ import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; @@ -36,6 +35,7 @@ import org.apache.solr.common.SolrDocumentList; import org.apache.solr.common.SolrInputDocument; import org.apache.solr.common.util.NamedList; +import org.apache.solr.common.util.SimpleOrderedMap; import org.junit.BeforeClass; import org.junit.Ignore; @@ -254,7 +254,7 @@ public void write(OutputStream os) throws IOException { List mapDocs = new ArrayList<>(); for (SolrInputDocument doc : docs) { - mapDocs.add(doc.toMap(new LinkedHashMap<>())); + mapDocs.add(new SimpleOrderedMap(doc)); } ObjectMapper cborMapper = diff --git a/solr/test-framework/src/java/org/apache/solr/common/cloud/ClusterStateUtil.java b/solr/test-framework/src/java/org/apache/solr/common/cloud/ClusterStateUtil.java index 9ecfe57379dc..fe5e724db2d1 100644 --- a/solr/test-framework/src/java/org/apache/solr/common/cloud/ClusterStateUtil.java +++ b/solr/test-framework/src/java/org/apache/solr/common/cloud/ClusterStateUtil.java @@ -25,6 +25,7 @@ import java.util.stream.Stream; import org.apache.solr.common.SolrException; import org.apache.solr.common.SolrException.ErrorCode; +import org.apache.solr.common.util.SimpleOrderedMap; import org.apache.solr.common.util.Utils; public class ClusterStateUtil { @@ -178,7 +179,7 @@ public static String toDebugAllStatesString(ClusterState clusterState) { .collectionStream() .collect( LinkedHashMap::new, - (map, state) -> map.put(state.getName(), state.toMap(new LinkedHashMap<>())), + (map, state) -> map.put(state.getName(), new SimpleOrderedMap<>(state)), Map::putAll); // toJSON requires standard types like Map; doesn't know about DocCollection etc. return Utils.toJSONString(stateMap);