diff --git a/src/main/java/com/nfl/dm/shield/dynamic/config/HashConfig.java b/src/main/java/com/nfl/dm/shield/dynamic/config/HashConfig.java new file mode 100644 index 0000000..4044513 --- /dev/null +++ b/src/main/java/com/nfl/dm/shield/dynamic/config/HashConfig.java @@ -0,0 +1,15 @@ +package com.nfl.dm.shield.dynamic.config; + +/** + * In order to get even distribution of hash codes (avoiding linear performance O(n)), it is best to initialize to + * a prime number. As a hash table grows, one default algorithm increases size by 2n + 1. Sun developers initially + * chose 101 as the default number. However, the growth characteristics of 101 are not as good as other selections. + * + * The book Java 2 Performance and Idiom Guide on page 73 offers the following as optimal initial bucket size: + * 89, 179, 359, 719, 1439, 2879, 11519, 23029, 737279, 1474559, 2949119. + * + * We have chosen 89 as the starting place for all hash tables. + */ +public final class HashConfig { + public static final int DEFAULT_HASH_TABLE_SIZE = 89; +} diff --git a/src/main/java/com/nfl/dm/shield/dynamic/domain/instance/SchemaInstance.java b/src/main/java/com/nfl/dm/shield/dynamic/domain/instance/SchemaInstance.java index e2941df..9be4f55 100644 --- a/src/main/java/com/nfl/dm/shield/dynamic/domain/instance/SchemaInstance.java +++ b/src/main/java/com/nfl/dm/shield/dynamic/domain/instance/SchemaInstance.java @@ -2,6 +2,8 @@ import java.util.*; import java.util.concurrent.ConcurrentHashMap; +import static com.nfl.dm.shield.dynamic.config.HashConfig.*; + public class SchemaInstance implements Map { public static final String ID = "id"; @@ -12,7 +14,7 @@ public class SchemaInstance implements Map { public static final String UPDATE_DATE_FIELD = "updateDate"; - private Map fieldValues = new ConcurrentHashMap<>(89); + private Map fieldValues = new ConcurrentHashMap<>(DEFAULT_HASH_TABLE_SIZE); private SchemaInstanceKey schemaInstanceKey; diff --git a/src/main/java/com/nfl/dm/shield/dynamic/domain/schema/SchemaDescription.java b/src/main/java/com/nfl/dm/shield/dynamic/domain/schema/SchemaDescription.java index 966c685..31973b2 100644 --- a/src/main/java/com/nfl/dm/shield/dynamic/domain/schema/SchemaDescription.java +++ b/src/main/java/com/nfl/dm/shield/dynamic/domain/schema/SchemaDescription.java @@ -14,6 +14,7 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; +import static com.nfl.dm.shield.dynamic.config.HashConfig.DEFAULT_HASH_TABLE_SIZE; import static com.nfl.dm.shield.dynamic.domain.schema.instancefield.SchemaInstanceField.MEMBER_TYPE_FIELD; import static graphql.Scalars.GraphQLID; import static graphql.Scalars.GraphQLLong; @@ -63,13 +64,13 @@ public class SchemaDescription { private IdGeneration idGeneration = IdGeneration.SERVICE_GENERATED_GUID; - private List domainFields = new ArrayList<>(89); + private List domainFields = new ArrayList<>(DEFAULT_HASH_TABLE_SIZE); - private List valueDefinitions = new ArrayList<>(89); + private List valueDefinitions = new ArrayList<>(DEFAULT_HASH_TABLE_SIZE); private String memberConfiguration; - private List filterConfigurations = new ArrayList<>(89); + private List filterConfigurations = new ArrayList<>(DEFAULT_HASH_TABLE_SIZE); public SchemaDescription() { } @@ -94,7 +95,7 @@ private void initMembers(Map initValues, InstanceOutputTypeServi } private void initValuesDefinitions(List> valueDefinitions, InstanceOutputTypeService instanceOutputTypeService) { - setValueDefinitions(new ArrayList<>(89)); + setValueDefinitions(new ArrayList<>(DEFAULT_HASH_TABLE_SIZE)); valueDefinitions.forEach(valueDef -> addValueDefinition(new ValueObjectField(this, valueDef, instanceOutputTypeService))); } diff --git a/src/main/java/com/nfl/dm/shield/dynamic/domain/schema/ValueObjectField.java b/src/main/java/com/nfl/dm/shield/dynamic/domain/schema/ValueObjectField.java index c38111e..8533115 100644 --- a/src/main/java/com/nfl/dm/shield/dynamic/domain/schema/ValueObjectField.java +++ b/src/main/java/com/nfl/dm/shield/dynamic/domain/schema/ValueObjectField.java @@ -10,6 +10,7 @@ import java.util.List; import java.util.Map; +import static com.nfl.dm.shield.dynamic.config.HashConfig.DEFAULT_HASH_TABLE_SIZE; import static graphql.Scalars.GraphQLString; import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition; import static graphql.schema.GraphQLInputObjectField.newInputObjectField; @@ -24,7 +25,7 @@ public class ValueObjectField { private String name; - private List valueFields = new ArrayList<>(89); + private List valueFields = new ArrayList<>(DEFAULT_HASH_TABLE_SIZE); public ValueObjectField() { // For persistence diff --git a/src/main/java/com/nfl/dm/shield/dynamic/domain/schema/instancefield/ExternalReferenceType.java b/src/main/java/com/nfl/dm/shield/dynamic/domain/schema/instancefield/ExternalReferenceType.java index c37113d..55428d6 100644 --- a/src/main/java/com/nfl/dm/shield/dynamic/domain/schema/instancefield/ExternalReferenceType.java +++ b/src/main/java/com/nfl/dm/shield/dynamic/domain/schema/instancefield/ExternalReferenceType.java @@ -9,6 +9,7 @@ import java.util.List; import java.util.Map; +import static com.nfl.dm.shield.dynamic.config.HashConfig.DEFAULT_HASH_TABLE_SIZE; import static graphql.Scalars.GraphQLID; import static graphql.Scalars.GraphQLString; import static graphql.schema.GraphQLInputObjectField.newInputObjectField; @@ -55,7 +56,7 @@ public GraphQLOutputType buildInstanceOutputType(InstanceFieldBuilderContext ins @Override Map buildPossibleTypeMap(List possibleTypes, InstanceFieldBuilderContext instanceFieldBuilderContext, InstanceOutputTypeService instanceOutputTypeService) { - Map retMap = new HashMap<>(89); + Map retMap = new HashMap<>(DEFAULT_HASH_TABLE_SIZE); possibleTypes.forEach(possible -> retMap.put(possible, (GraphQLObjectType) instanceOutputTypeService.deriveFromExternalTypeName(possible))); return retMap; diff --git a/src/main/java/com/nfl/dm/shield/dynamic/domain/schema/instancefield/MultiTypeDynamicReferenceType.java b/src/main/java/com/nfl/dm/shield/dynamic/domain/schema/instancefield/MultiTypeDynamicReferenceType.java index cbe8793..4438997 100644 --- a/src/main/java/com/nfl/dm/shield/dynamic/domain/schema/instancefield/MultiTypeDynamicReferenceType.java +++ b/src/main/java/com/nfl/dm/shield/dynamic/domain/schema/instancefield/MultiTypeDynamicReferenceType.java @@ -20,6 +20,7 @@ import java.util.List; import java.util.Map; +import static com.nfl.dm.shield.dynamic.config.HashConfig.DEFAULT_HASH_TABLE_SIZE; import static com.nfl.dm.shield.dynamic.domain.BaseKey.SCHEMA_NAME_FIELD; import static com.nfl.dm.shield.dynamic.domain.instance.SchemaInstance.SCHEMA_INSTANCE_KEY_FIELD; import static graphql.Scalars.GraphQLID; @@ -60,7 +61,7 @@ public GraphQLOutputType buildInstanceOutputType(InstanceFieldBuilderContext ins Map buildPossibleTypeMap(List possibleTypes, InstanceFieldBuilderContext instanceFieldBuilderContext, InstanceOutputTypeService instanceOutputTypeService) { - Map retMap = new HashMap<>(89); + Map retMap = new HashMap<>(DEFAULT_HASH_TABLE_SIZE); possibleTypes.forEach(possible -> { SchemaKey schemaKey = new SchemaKey(possible, instanceFieldBuilderContext.getSchemaNamespace()); SchemaDescription schemaDescription = instanceOutputTypeService.findSchemaDescriptionByName(schemaKey); diff --git a/src/main/java/com/nfl/dm/shield/dynamic/domain/schema/instancefield/SchemaInstanceField.java b/src/main/java/com/nfl/dm/shield/dynamic/domain/schema/instancefield/SchemaInstanceField.java index 319d2cf..e681cbd 100644 --- a/src/main/java/com/nfl/dm/shield/dynamic/domain/schema/instancefield/SchemaInstanceField.java +++ b/src/main/java/com/nfl/dm/shield/dynamic/domain/schema/instancefield/SchemaInstanceField.java @@ -13,6 +13,7 @@ import java.util.*; import java.util.stream.Collectors; +import static com.nfl.dm.shield.dynamic.config.HashConfig.DEFAULT_HASH_TABLE_SIZE; import static graphql.Scalars.GraphQLString; import static graphql.schema.GraphQLEnumType.newEnum; import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition; @@ -46,7 +47,7 @@ public class SchemaInstanceField { private String otherTypeName = ""; - private List enumValues = new ArrayList<>(89); + private List enumValues = new ArrayList<>(DEFAULT_HASH_TABLE_SIZE); private String serviceKey; diff --git a/src/main/java/com/nfl/dm/shield/dynamic/repository/InMemorySchemaRepository.java b/src/main/java/com/nfl/dm/shield/dynamic/repository/InMemorySchemaRepository.java index 78aa5e4..6ab6f38 100644 --- a/src/main/java/com/nfl/dm/shield/dynamic/repository/InMemorySchemaRepository.java +++ b/src/main/java/com/nfl/dm/shield/dynamic/repository/InMemorySchemaRepository.java @@ -16,6 +16,7 @@ import java.util.stream.Stream; import static com.google.common.collect.Lists.transform; +import static com.nfl.dm.shield.dynamic.config.HashConfig.DEFAULT_HASH_TABLE_SIZE; import static com.nfl.dm.shield.dynamic.domain.instance.SchemaInstance.UPDATE_DATE_FIELD; import static java.util.Collections.emptyList; import static java.util.Collections.emptyMap; @@ -25,10 +26,10 @@ public class InMemorySchemaRepository extends BaseRepositoryImpl implements SchemaRepository, SchemaInstanceRepository { - private final Map allTheSchemas = new ConcurrentHashMap<>(89); + private final Map allTheSchemas = new ConcurrentHashMap<>(DEFAULT_HASH_TABLE_SIZE); private final Map> instances - = new ConcurrentHashMap<>(89); + = new ConcurrentHashMap<>(DEFAULT_HASH_TABLE_SIZE); public InMemorySchemaRepository() { } @@ -137,7 +138,7 @@ public SchemaInstance upsert(SchemaInstanceKey schemaInstanceKey, SchemaInstance } private Map initInstance(SchemaInstanceKey schemaInstanceKey) { - Map retMap = new ConcurrentHashMap<>(89); + Map retMap = new ConcurrentHashMap<>(DEFAULT_HASH_TABLE_SIZE); instances.put(schemaInstanceKey, retMap); return retMap; } diff --git a/src/main/java/com/nfl/dm/shield/dynamic/repository/StubbedExternalReferenceRepository.java b/src/main/java/com/nfl/dm/shield/dynamic/repository/StubbedExternalReferenceRepository.java index 6d80c4c..8a4ae05 100644 --- a/src/main/java/com/nfl/dm/shield/dynamic/repository/StubbedExternalReferenceRepository.java +++ b/src/main/java/com/nfl/dm/shield/dynamic/repository/StubbedExternalReferenceRepository.java @@ -9,6 +9,7 @@ import java.util.*; import java.util.concurrent.ConcurrentHashMap; +import static com.nfl.dm.shield.dynamic.config.HashConfig.DEFAULT_HASH_TABLE_SIZE; import static com.nfl.dm.shield.dynamic.domain.schema.instancefield.AbstractReferenceType.REFERENCE_ID; import static com.nfl.dm.shield.dynamic.domain.schema.instancefield.AbstractReferenceType.REFERENCE_TYPE; import static graphql.Scalars.GraphQLID; @@ -21,7 +22,7 @@ public class StubbedExternalReferenceRepository implements ExternalReferenceRepository { private final Map>> externalInstances - = new ConcurrentHashMap<>(89); + = new ConcurrentHashMap<>(DEFAULT_HASH_TABLE_SIZE); private final Map outputTypeMap = new ConcurrentHashMap<>(89); @@ -54,7 +55,7 @@ public Map findById(SelectionSet selections, Map public void loadExternalInstance(String typeName, String id, Map instance) { if (!externalInstances.containsKey(typeName)) { - externalInstances.put(typeName, new HashMap<>(89)); + externalInstances.put(typeName, new HashMap<>(DEFAULT_HASH_TABLE_SIZE)); } externalInstances.get(typeName).put(id, instance); diff --git a/src/main/java/com/nfl/dm/shield/dynamic/security/SchemaWriteAccess.java b/src/main/java/com/nfl/dm/shield/dynamic/security/SchemaWriteAccess.java index f66eeb0..948748d 100644 --- a/src/main/java/com/nfl/dm/shield/dynamic/security/SchemaWriteAccess.java +++ b/src/main/java/com/nfl/dm/shield/dynamic/security/SchemaWriteAccess.java @@ -4,6 +4,8 @@ import java.util.Map; import java.util.Set; +import static com.nfl.dm.shield.dynamic.config.HashConfig.DEFAULT_HASH_TABLE_SIZE; + public class SchemaWriteAccess { public static final String SCHEMA_MODIFY = "SCHEMA_MODIFY"; @@ -13,7 +15,7 @@ public class SchemaWriteAccess { private final String authHeader; - private final Map> permissions = new HashMap<>(89); + private final Map> permissions = new HashMap<>(DEFAULT_HASH_TABLE_SIZE); public SchemaWriteAccess() { authHeader = "Testing only."; @@ -27,7 +29,7 @@ public void addPermission(String namespace, String permissionName) { // Initialize if (!permissions.containsKey(namespace)) { - permissions.put(namespace, new HashSet<>(89)); + permissions.put(namespace, new HashSet<>(DEFAULT_HASH_TABLE_SIZE)); } permissions.get(namespace).add(permissionName);