mirror of https://github.com/apache/lucene.git
SOLR-9657: Use cache for templates
This commit is contained in:
parent
14b6d93db4
commit
127bf9f772
|
@ -25,6 +25,8 @@ import java.util.function.Function;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.apache.solr.common.util.Cache;
|
||||||
|
import org.apache.solr.common.util.MapBackedCache;
|
||||||
import org.apache.solr.update.processor.TemplateUpdateProcessorFactory;
|
import org.apache.solr.update.processor.TemplateUpdateProcessorFactory;
|
||||||
|
|
||||||
import static org.apache.solr.update.processor.TemplateUpdateProcessorFactory.Resolved;
|
import static org.apache.solr.update.processor.TemplateUpdateProcessorFactory.Resolved;
|
||||||
|
@ -55,7 +57,7 @@ public class VariableResolver {
|
||||||
.compile("^(\\w*?)\\((.*?)\\)$");
|
.compile("^(\\w*?)\\((.*?)\\)$");
|
||||||
private Map<String,Object> rootNamespace;
|
private Map<String,Object> rootNamespace;
|
||||||
private Map<String,Evaluator> evaluators;
|
private Map<String,Evaluator> evaluators;
|
||||||
private Map<String,Resolved> cache = new WeakHashMap<>();
|
private Cache<String,Resolved> cache = new MapBackedCache<>(new WeakHashMap<>());
|
||||||
private Function<String,Object> fun = this::resolve;
|
private Function<String,Object> fun = this::resolve;
|
||||||
|
|
||||||
public static final String FUNCTIONS_NAMESPACE = "dataimporter.functions.";
|
public static final String FUNCTIONS_NAMESPACE = "dataimporter.functions.";
|
||||||
|
|
|
@ -20,18 +20,21 @@ package org.apache.solr.update.processor;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.apache.solr.common.SolrInputDocument;
|
import org.apache.solr.common.SolrInputDocument;
|
||||||
|
import org.apache.solr.common.util.Cache;
|
||||||
import org.apache.solr.request.SolrQueryRequest;
|
import org.apache.solr.request.SolrQueryRequest;
|
||||||
import org.apache.solr.response.SolrQueryResponse;
|
import org.apache.solr.response.SolrQueryResponse;
|
||||||
import org.apache.solr.update.AddUpdateCommand;
|
import org.apache.solr.update.AddUpdateCommand;
|
||||||
|
import org.apache.solr.util.ConcurrentLRUCache;
|
||||||
|
|
||||||
//Adds new fields to documents based on a template pattern specified via Template.field
|
//Adds new fields to documents based on a template pattern specified via Template.field
|
||||||
// request parameters (multi-valued) or 'field' value specified in initArgs
|
// request parameters (multi-valued) or 'field' value specified in initArgs
|
||||||
public class TemplateUpdateProcessorFactory extends SimpleUpdateProcessorFactory {
|
public class TemplateUpdateProcessorFactory extends SimpleUpdateProcessorFactory {
|
||||||
|
private Cache<String, Resolved> templateCache = new ConcurrentLRUCache<>(1000, 800, 900, 10, false, false, null);
|
||||||
@Override
|
@Override
|
||||||
protected void process(AddUpdateCommand cmd, SolrQueryRequest req, SolrQueryResponse rsp) {
|
protected void process(AddUpdateCommand cmd, SolrQueryRequest req, SolrQueryResponse rsp) {
|
||||||
String[] vals = getParams("field");
|
String[] vals = getParams("field");
|
||||||
|
@ -45,7 +48,7 @@ public class TemplateUpdateProcessorFactory extends SimpleUpdateProcessorFactory
|
||||||
|
|
||||||
String fName = val.substring(0, idx);
|
String fName = val.substring(0, idx);
|
||||||
String template = val.substring(idx + 1);
|
String template = val.substring(idx + 1);
|
||||||
doc.addField(fName, replaceTokens(template, null, s -> {
|
doc.addField(fName, replaceTokens(template, templateCache, s -> {
|
||||||
Object v = doc.getFieldValue(s);
|
Object v = doc.getFieldValue(s);
|
||||||
return v == null ? "" : v;
|
return v == null ? "" : v;
|
||||||
}));
|
}));
|
||||||
|
@ -55,7 +58,7 @@ public class TemplateUpdateProcessorFactory extends SimpleUpdateProcessorFactory
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static Resolved getResolved(String template, Map<String, Resolved> cache) {
|
public static Resolved getResolved(String template, Cache<String, Resolved> cache) {
|
||||||
Resolved r = cache == null ? null : cache.get(template);
|
Resolved r = cache == null ? null : cache.get(template);
|
||||||
if (r == null) {
|
if (r == null) {
|
||||||
r = new Resolved();
|
r = new Resolved();
|
||||||
|
@ -74,7 +77,7 @@ public class TemplateUpdateProcessorFactory extends SimpleUpdateProcessorFactory
|
||||||
/**
|
/**
|
||||||
* Get a list of variables embedded in the template string.
|
* Get a list of variables embedded in the template string.
|
||||||
*/
|
*/
|
||||||
public static List<String> getVariables(String template, Map<String, Resolved> cache) {
|
public static List<String> getVariables(String template, Cache<String, Resolved> cache) {
|
||||||
Resolved r = getResolved(template, cache);
|
Resolved r = getResolved(template, cache);
|
||||||
if (r == null) {
|
if (r == null) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
|
@ -82,7 +85,7 @@ public class TemplateUpdateProcessorFactory extends SimpleUpdateProcessorFactory
|
||||||
return new ArrayList<>(r.variables);
|
return new ArrayList<>(r.variables);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String replaceTokens(String template, Map<String, Resolved> cache, Function<String, Object> fun) {
|
public static String replaceTokens(String template, Cache<String, Resolved> cache, Function<String, Object> fun) {
|
||||||
if (template == null) {
|
if (template == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,13 +16,31 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.solr.common.util;
|
package org.apache.solr.common.util;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
public interface Cache<K, V> {
|
public interface Cache<K, V> {
|
||||||
public V put(K key, V val);
|
V put(K key, V val);
|
||||||
|
|
||||||
public V get(K key);
|
V get(K key);
|
||||||
|
|
||||||
public V remove(K key);
|
V remove(K key);
|
||||||
|
|
||||||
public void clear();
|
void clear();
|
||||||
|
|
||||||
|
default V computeIfAbsent(K key,
|
||||||
|
Function<? super K, ? extends V> mappingFunction) {
|
||||||
|
Objects.requireNonNull(mappingFunction);
|
||||||
|
V v;
|
||||||
|
if ((v = get(key)) == null) {
|
||||||
|
V newValue;
|
||||||
|
if ((newValue = mappingFunction.apply(key)) != null) {
|
||||||
|
put(key, newValue);
|
||||||
|
return newValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* 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.util;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
// A cache backed by a map
|
||||||
|
public class MapBackedCache<K, V> implements Cache<K, V> {
|
||||||
|
|
||||||
|
private final Map<K, V> map;
|
||||||
|
|
||||||
|
public MapBackedCache(Map<K, V> map) {
|
||||||
|
this.map = map;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public V put(K key, V val) {
|
||||||
|
return map.put(key, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public V get(K key) {
|
||||||
|
return map.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public V remove(K key) {
|
||||||
|
return map.remove(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clear() {
|
||||||
|
map.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
|
||||||
|
return map.computeIfAbsent(key, mappingFunction);
|
||||||
|
}
|
||||||
|
}
|
|
@ -340,30 +340,7 @@ public class TestJavaBinCodec extends SolrTestCaseJ4 {
|
||||||
assertTrue(l1.get(1).equals(l2.get(1)));
|
assertTrue(l1.get(1).equals(l2.get(1)));
|
||||||
assertFalse(l1.get(1) == l2.get(1));
|
assertFalse(l1.get(1) == l2.get(1));
|
||||||
|
|
||||||
JavaBinCodec.StringCache stringCache = new JavaBinCodec.StringCache(new Cache<JavaBinCodec.StringBytes, String>() {
|
JavaBinCodec.StringCache stringCache = new JavaBinCodec.StringCache(new MapBackedCache<>(new HashMap<>()));
|
||||||
private HashMap<JavaBinCodec.StringBytes, String> cache = new HashMap<>();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String put(JavaBinCodec.StringBytes key, String val) {
|
|
||||||
return cache.put(key, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String get(JavaBinCodec.StringBytes key) {
|
|
||||||
return cache.get(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String remove(JavaBinCodec.StringBytes key) {
|
|
||||||
return cache.remove(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void clear() {
|
|
||||||
cache.clear();
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
m1 = (Map) new JavaBinCodec(null, stringCache).unmarshal(new ByteArrayInputStream(b1));
|
m1 = (Map) new JavaBinCodec(null, stringCache).unmarshal(new ByteArrayInputStream(b1));
|
||||||
|
@ -409,32 +386,7 @@ public class TestJavaBinCodec extends SolrTestCaseJ4 {
|
||||||
Runtime.getRuntime().gc();
|
Runtime.getRuntime().gc();
|
||||||
printMem("before cache init");
|
printMem("before cache init");
|
||||||
|
|
||||||
Cache<JavaBinCodec.StringBytes, String> cache1 = new Cache<JavaBinCodec.StringBytes, String>() {
|
Cache<JavaBinCodec.StringBytes, String> cache1 = new MapBackedCache<>(new HashMap<>()) ;
|
||||||
private HashMap<JavaBinCodec.StringBytes, String> cache = new HashMap<>();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String put(JavaBinCodec.StringBytes key, String val) {
|
|
||||||
l.add(key);
|
|
||||||
return cache.put(key, val);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String get(JavaBinCodec.StringBytes key) {
|
|
||||||
return cache.get(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String remove(JavaBinCodec.StringBytes key) {
|
|
||||||
return cache.remove(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void clear() {
|
|
||||||
cache.clear();
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
final JavaBinCodec.StringCache STRING_CACHE = new JavaBinCodec.StringCache(cache1);
|
final JavaBinCodec.StringCache STRING_CACHE = new JavaBinCodec.StringCache(cache1);
|
||||||
|
|
||||||
// STRING_CACHE = new JavaBinCodec.StringCache(cache);
|
// STRING_CACHE = new JavaBinCodec.StringCache(cache);
|
||||||
|
|
Loading…
Reference in New Issue