|
@@ -13,36 +13,51 @@ import org.elasticsearch.xcontent.XContentParserConfiguration;
|
|
|
import org.elasticsearch.xcontent.XContentType;
|
|
|
|
|
|
import java.io.IOException;
|
|
|
-import java.io.UncheckedIOException;
|
|
|
import java.util.HashMap;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
+import java.util.function.Function;
|
|
|
import java.util.zip.GZIPInputStream;
|
|
|
|
|
|
-public class InstanceTypeService {
|
|
|
- private final Map<InstanceType, CostEntry> costsPerDatacenter = new HashMap<>();
|
|
|
-
|
|
|
- public void load() {
|
|
|
- try (
|
|
|
- GZIPInputStream in = new GZIPInputStream(
|
|
|
- InstanceTypeService.class.getClassLoader().getResourceAsStream("profiling-costs.json.gz")
|
|
|
- )
|
|
|
- ) {
|
|
|
- XContentParser parser = XContentType.JSON.xContent().createParser(XContentParserConfiguration.EMPTY, in);
|
|
|
- if (parser.currentToken() == null) {
|
|
|
- parser.nextToken();
|
|
|
- }
|
|
|
- List<Map<String, Object>> rawData = XContentParserUtils.parseList(parser, XContentParser::map);
|
|
|
- for (Map<String, Object> entry : rawData) {
|
|
|
- costsPerDatacenter.put(InstanceType.fromCostSource(entry), CostEntry.fromSource(entry));
|
|
|
- }
|
|
|
+public final class InstanceTypeService {
|
|
|
+
|
|
|
+ private InstanceTypeService() {}
|
|
|
|
|
|
- } catch (IOException e) {
|
|
|
- throw new UncheckedIOException(e);
|
|
|
+ private static final class Holder {
|
|
|
+ private static final Map<InstanceType, CostEntry> costsPerDatacenter;
|
|
|
+
|
|
|
+ static {
|
|
|
+ final Map<Object, Object> objects = new HashMap<>();
|
|
|
+ final Function<String, String> dedupString = s -> (String) objects.computeIfAbsent(s, Function.identity());
|
|
|
+ final Map<InstanceType, CostEntry> tmp = new HashMap<>();
|
|
|
+ try (
|
|
|
+ GZIPInputStream in = new GZIPInputStream(
|
|
|
+ InstanceTypeService.class.getClassLoader().getResourceAsStream("profiling-costs.json.gz")
|
|
|
+ );
|
|
|
+ XContentParser parser = XContentType.JSON.xContent().createParser(XContentParserConfiguration.EMPTY, in)
|
|
|
+ ) {
|
|
|
+ if (parser.currentToken() == null) {
|
|
|
+ parser.nextToken();
|
|
|
+ }
|
|
|
+ List<Map<String, Object>> rawData = XContentParserUtils.parseList(parser, XContentParser::map);
|
|
|
+ for (Map<String, Object> entry : rawData) {
|
|
|
+ tmp.put(
|
|
|
+ new InstanceType(
|
|
|
+ dedupString.apply((String) entry.get("provider")),
|
|
|
+ dedupString.apply((String) entry.get("region")),
|
|
|
+ dedupString.apply((String) entry.get("instance_type"))
|
|
|
+ ),
|
|
|
+ (CostEntry) objects.computeIfAbsent(CostEntry.fromSource(entry), Function.identity())
|
|
|
+ );
|
|
|
+ }
|
|
|
+ costsPerDatacenter = Map.copyOf(tmp);
|
|
|
+ } catch (IOException e) {
|
|
|
+ throw new ExceptionInInitializerError(e);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- public CostEntry getCosts(InstanceType instance) {
|
|
|
- return costsPerDatacenter.get(instance);
|
|
|
+ public static CostEntry getCosts(InstanceType instance) {
|
|
|
+ return Holder.costsPerDatacenter.get(instance);
|
|
|
}
|
|
|
}
|