Skip to content

Commit

Permalink
Cache string values to reduce memory footprint.
Browse files Browse the repository at this point in the history
  • Loading branch information
Tomasz Bak committed Feb 24, 2015
1 parent 2f656f8 commit 4cdf7aa
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,11 @@ public Object unmarshal(HierarchicalStreamReader reader,
public static class ApplicationConverter implements Converter {

private static final String ELEM_NAME = "name";
private final StringCache cache;

public ApplicationConverter(StringCache cache) {
this.cache = cache;
}

/*
* (non-Javadoc)
Expand Down Expand Up @@ -214,7 +219,7 @@ public Object unmarshal(HierarchicalStreamReader reader,
String nodeName = reader.getNodeName();

if (ELEM_NAME.equals(nodeName)) {
app.setName(reader.getValue());
app.setName(cache.cachedValueOf(reader.getValue()));
} else if (NODE_INSTANCE.equals(nodeName)) {
app.addInstance((InstanceInfo) context.convertAnother(app,
InstanceInfo.class));
Expand Down Expand Up @@ -242,6 +247,12 @@ public static class InstanceInfoConverter implements Converter {
private static final String ELEM_IDENTIFYING_ATTR = "identifyingAttribute";
private static final String ATTR_ENABLED = "enabled";

private final StringCache cache;

public InstanceInfoConverter(StringCache cache) {
this.cache = cache;
}

/*
* (non-Javadoc)
*
Expand Down Expand Up @@ -366,13 +377,13 @@ public Object unmarshal(HierarchicalStreamReader reader,
String nodeName = reader.getNodeName();

if (ELEM_HOST.equals(nodeName)) {
builder.setHostName(reader.getValue());
builder.setHostName(cache.cachedValueOf(reader.getValue()));
} else if (ELEM_APP.equals(nodeName)) {
builder.setAppName(reader.getValue());
builder.setAppName(cache.cachedValueOf(reader.getValue()));
} else if (ELEM_IP.equals(nodeName)) {
builder.setIPAddr(reader.getValue());
builder.setIPAddr(cache.cachedValueOf(reader.getValue()));
} else if (ELEM_SID.equals(nodeName)) {
builder.setSID(reader.getValue());
builder.setSID(cache.cachedValueOf(reader.getValue()));
} else if (ELEM_IDENTIFYING_ATTR.equals(nodeName)) {
// nothing;
} else if (ELEM_STATUS.equals(nodeName)) {
Expand Down Expand Up @@ -421,6 +432,11 @@ public Object unmarshal(HierarchicalStreamReader reader,
public static class DataCenterInfoConverter implements Converter {

private static final String ELEM_NAME = "name";
private final StringCache cache;

public DataCenterInfoConverter(StringCache cache) {
this.cache = cache;
}

/*
* (non-Javadoc)
Expand Down Expand Up @@ -499,9 +515,13 @@ public Name getName() {
}
} else if (NODE_METADATA.equals(reader.getNodeName())) {
if (info.getName() == Name.Amazon) {
((AmazonInfo) info)
.setMetadata((Map<String, String>) context
.convertAnother(info, Map.class));
Map<String, String> metadataMap = (Map<String, String>) context
.convertAnother(info, Map.class);
Map<String, String> metadataMapInter = new HashMap<>(metadataMap.size());
for(Map.Entry<String, String> entry: metadataMap.entrySet()) {
metadataMapInter.put(cache.cachedValueOf(entry.getKey()), cache.cachedValueOf(entry.getValue()));
}
((AmazonInfo) info).setMetadata(metadataMapInter);
}
}

Expand Down Expand Up @@ -629,6 +649,12 @@ public Object unmarshal(HierarchicalStreamReader reader,
*/
public static class MetadataConverter implements Converter {

private final StringCache cache;

public MetadataConverter(StringCache cache) {
this.cache = cache;
}

/*
* (non-Javadoc)
*
Expand Down Expand Up @@ -693,7 +719,7 @@ private Map<String, String> unmarshalMap(
String value = reader.getValue();
reader.moveUp();

map.put(key, value);
map.put(cache.cachedValueOf(key), cache.cachedValueOf(value));
}
return map;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,26 +49,30 @@ protected NameCoder getNameCoder() {
return this.coder;
}
});
registerConverter(new Converters.ApplicationConverter());

StringCache cache = new StringCache();

registerConverter(new Converters.ApplicationConverter(cache));
registerConverter(new Converters.ApplicationsConverter());
registerConverter(new Converters.DataCenterInfoConverter());
registerConverter(new Converters.InstanceInfoConverter());
registerConverter(new Converters.DataCenterInfoConverter(cache));
registerConverter(new Converters.InstanceInfoConverter(cache));
registerConverter(new Converters.LeaseInfoConverter());
registerConverter(new Converters.MetadataConverter());
registerConverter(new Converters.MetadataConverter(cache));
setMode(XStream.NO_REFERENCES);
processAnnotations(new Class[] {InstanceInfo.class, Application.class, Applications.class});
processAnnotations(new Class[]{InstanceInfo.class, Application.class, Applications.class});
}

public static JsonXStream getInstance() {
return s_instance;
}

private static XmlFriendlyNameCoder initializeNameCoder(){
private static XmlFriendlyNameCoder initializeNameCoder() {
EurekaClientConfig clientConfig = DiscoveryManager
.getInstance().getEurekaClientConfig();
if (clientConfig == null) {
return new XmlFriendlyNameCoder();
}
return new XmlFriendlyNameCoder(clientConfig.getDollarReplacement(), clientConfig.getEscapeCharReplacement());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.netflix.discovery.converters;

import java.util.Map;
import java.util.WeakHashMap;

/**
* @author Tomasz Bak
*/
public class StringCache {

public static final int LENGTH_LIMIT = 38;

private final Map<String, String> cache = new WeakHashMap<>();
private final int lengthLimit;

public StringCache() {
this(LENGTH_LIMIT);
}

public StringCache(int lengthLimit) {
this.lengthLimit = lengthLimit;
}

public String cachedValueOf(final String str) {
if (str != null && (lengthLimit < 0 || str.length() <= lengthLimit)) {
String s;
synchronized (cache) {
s = cache.get(str);
if (s == null) {
cache.put(str, str);
s = str;
}
}
return s;
}
return str;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,14 @@ public class XmlXStream extends XStream {
public XmlXStream() {
super(new DomDriver(null, initializeNameCoder()));

registerConverter(new Converters.ApplicationConverter());
StringCache cache = new StringCache();

registerConverter(new Converters.ApplicationConverter(cache));
registerConverter(new Converters.ApplicationsConverter());
registerConverter(new Converters.DataCenterInfoConverter());
registerConverter(new Converters.InstanceInfoConverter());
registerConverter(new Converters.DataCenterInfoConverter(cache));
registerConverter(new Converters.InstanceInfoConverter(cache));
registerConverter(new Converters.LeaseInfoConverter());
registerConverter(new Converters.MetadataConverter());
registerConverter(new Converters.MetadataConverter(cache));
setMode(XStream.NO_REFERENCES);
processAnnotations(new Class[] {InstanceInfo.class, Application.class,
Applications.class});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import com.netflix.discovery.converters.StringCache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -77,6 +78,8 @@ public class EurekaBootStrap implements ServletContextListener {
private static final int EIP_BIND_SLEEP_TIME_MS = 1000;
private static final Timer timer = new Timer("Eureka-EIPBinder", true);

private final StringCache stringCache = new StringCache();

/**
* Initializes Eureka, including syncing up with other Eureka peers and publishing the registry.
*
Expand All @@ -89,10 +92,10 @@ public void contextInitialized(ServletContextEvent event) {

// For backward compatibility
JsonXStream.getInstance().registerConverter(
new V1AwareInstanceInfoConverter(),
new V1AwareInstanceInfoConverter(stringCache),
XStream.PRIORITY_VERY_HIGH);
XmlXStream.getInstance().registerConverter(
new V1AwareInstanceInfoConverter(),
new V1AwareInstanceInfoConverter(stringCache),
XStream.PRIORITY_VERY_HIGH);
InstanceInfo info = ApplicationInfoManager.getInstance().getInfo();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import com.netflix.appinfo.InstanceInfo;
import com.netflix.appinfo.InstanceInfo.InstanceStatus;
import com.netflix.discovery.converters.Converters.InstanceInfoConverter;
import com.netflix.discovery.converters.StringCache;

/**
* Support for {@link Version#V1}. {@link Version#V2} introduces a new status
Expand All @@ -29,6 +30,10 @@
*/
public class V1AwareInstanceInfoConverter extends InstanceInfoConverter {

public V1AwareInstanceInfoConverter(StringCache cache) {
super(cache);
}

@Override
public String getStatus(InstanceInfo info) {
Version version = CurrentRequestVersion.get();
Expand Down

0 comments on commit 4cdf7aa

Please sign in to comment.