Skip to content

Commit cb16615

Browse files
committed
Add benchmarking to DDB v2 mapper
1 parent f81c42b commit cb16615

46 files changed

Lines changed: 7953 additions & 14 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979
<module>test/service-test-utils</module>
8080
<module>test/test-utils</module>
8181
<module>test/codegen-generated-classes-test</module>
82+
<module>test/dynamodb-mapper-v2</module>
8283
<module>test/sdk-benchmarks</module>
8384
<module>test/http-client-benchmarks</module>
8485
<module>test/module-path-tests</module>

test/dynamodb-mapper-v2/pom.xml

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<groupId>software.amazon.awssdk</groupId>
8+
<artifactId>dynamodb-mapper-v2</artifactId>
9+
<version>1.0.0-SNAPSHOT</version>
10+
<packaging>jar</packaging>
11+
12+
<name>DynamoDB Mapper for AWS SDK v2</name>
13+
<description>Port of the v1 DynamoDBMapper to work with the v2 DynamoDbClient</description>
14+
15+
<properties>
16+
<maven.compiler.source>1.8</maven.compiler.source>
17+
<maven.compiler.target>1.8</maven.compiler.target>
18+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
19+
<awssdk.version>2.31.9</awssdk.version>
20+
</properties>
21+
22+
<dependencies>
23+
<dependency>
24+
<groupId>software.amazon.awssdk</groupId>
25+
<artifactId>dynamodb</artifactId>
26+
<version>${awssdk.version}</version>
27+
</dependency>
28+
<dependency>
29+
<groupId>org.slf4j</groupId>
30+
<artifactId>slf4j-api</artifactId>
31+
<version>1.7.36</version>
32+
</dependency>
33+
34+
<dependency>
35+
<groupId>joda-time</groupId>
36+
<artifactId>joda-time</artifactId>
37+
<version>2.12.5</version>
38+
<optional>true</optional>
39+
</dependency>
40+
41+
<!-- Test -->
42+
<dependency>
43+
<groupId>junit</groupId>
44+
<artifactId>junit</artifactId>
45+
<version>4.13.2</version>
46+
<scope>test</scope>
47+
</dependency>
48+
<dependency>
49+
<groupId>org.hamcrest</groupId>
50+
<artifactId>hamcrest</artifactId>
51+
<version>2.2</version>
52+
<scope>test</scope>
53+
</dependency>
54+
<dependency>
55+
<groupId>org.mockito</groupId>
56+
<artifactId>mockito-core</artifactId>
57+
<version>4.11.0</version>
58+
<scope>test</scope>
59+
</dependency>
60+
<dependency>
61+
<groupId>org.slf4j</groupId>
62+
<artifactId>slf4j-simple</artifactId>
63+
<version>1.7.36</version>
64+
<scope>test</scope>
65+
</dependency>
66+
<dependency>
67+
<groupId>com.amazonaws</groupId>
68+
<artifactId>DynamoDBLocal</artifactId>
69+
<version>1.25.0</version>
70+
<scope>test</scope>
71+
</dependency>
72+
<dependency>
73+
<groupId>com.almworks.sqlite4java</groupId>
74+
<artifactId>sqlite4java</artifactId>
75+
<version>1.0.392</version>
76+
<scope>test</scope>
77+
</dependency>
78+
</dependencies>
79+
80+
<build>
81+
<plugins>
82+
<plugin>
83+
<groupId>org.apache.maven.plugins</groupId>
84+
<artifactId>maven-dependency-plugin</artifactId>
85+
<executions>
86+
<execution>
87+
<id>copy-native-libs</id>
88+
<phase>process-test-resources</phase>
89+
<goals>
90+
<goal>copy-dependencies</goal>
91+
</goals>
92+
<configuration>
93+
<includeScope>test</includeScope>
94+
<includeTypes>so,dll,dylib</includeTypes>
95+
<outputDirectory>${project.build.directory}/native-libs</outputDirectory>
96+
</configuration>
97+
</execution>
98+
</executions>
99+
</plugin>
100+
<plugin>
101+
<groupId>org.apache.maven.plugins</groupId>
102+
<artifactId>maven-surefire-plugin</artifactId>
103+
<configuration>
104+
<systemPropertyVariables>
105+
<sqlite4java.library.path>${project.build.directory}/native-libs</sqlite4java.library.path>
106+
</systemPropertyVariables>
107+
<environmentVariables>
108+
<DDB_LOCAL_TELEMETRY>0</DDB_LOCAL_TELEMETRY>
109+
</environmentVariables>
110+
</configuration>
111+
</plugin>
112+
</plugins>
113+
</build>
114+
</project>
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/*
2+
* Copyright 2015-2025 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at:
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
11+
* OR CONDITIONS OF ANY KIND, either express or implied. See the
12+
* License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
package software.amazon.awssdk.dynamodb.datamodeling;
16+
17+
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
18+
import java.util.Map;
19+
20+
/**
21+
* Abstract implementation of {@code IDynamoDBMapper}. Stripped to load path for POC.
22+
*/
23+
public abstract class AbstractDynamoDBMapper implements IDynamoDBMapper {
24+
25+
private final DynamoDBMapperConfig config;
26+
27+
protected AbstractDynamoDBMapper(final DynamoDBMapperConfig defaults) {
28+
this.config = DynamoDBMapperConfig.DEFAULT.merge(defaults);
29+
}
30+
31+
protected AbstractDynamoDBMapper() {
32+
this(DynamoDBMapperConfig.DEFAULT);
33+
}
34+
35+
protected final String getTableName(Class<?> clazz, Object object, DynamoDBMapperConfig config) {
36+
if (config.getObjectTableNameResolver() != null && object != null) {
37+
return config.getObjectTableNameResolver().getTableName(object, config);
38+
}
39+
return getTableName(clazz, config);
40+
}
41+
42+
protected final String getTableName(Class<?> clazz, DynamoDBMapperConfig config) {
43+
if (config.getTableNameResolver() == null) {
44+
return DynamoDBMapperConfig.DefaultTableNameResolver.INSTANCE.getTableName(clazz, config);
45+
}
46+
return config.getTableNameResolver().getTableName(clazz, config);
47+
}
48+
49+
protected final DynamoDBMapperConfig mergeConfig(DynamoDBMapperConfig overrides) {
50+
return this.config.merge(overrides);
51+
}
52+
53+
@Override
54+
public <T> DynamoDBMapperTableModel<T> getTableModel(Class<T> clazz) {
55+
return getTableModel(clazz, config);
56+
}
57+
58+
@Override
59+
public <T> DynamoDBMapperTableModel<T> getTableModel(Class<T> clazz, DynamoDBMapperConfig config) {
60+
throw new UnsupportedOperationException("operation not supported in " + getClass());
61+
}
62+
63+
@Override
64+
public <T> T load(Class<T> clazz, Object hashKey, DynamoDBMapperConfig config) {
65+
return load(clazz, hashKey, (Object)null, config);
66+
}
67+
68+
@Override
69+
public <T> T load(Class<T> clazz, Object hashKey) {
70+
return load(clazz, hashKey, (Object)null, config);
71+
}
72+
73+
@Override
74+
public <T> T load(Class<T> clazz, Object hashKey, Object rangeKey) {
75+
return load(clazz, hashKey, rangeKey, config);
76+
}
77+
78+
@Override
79+
public <T> T load(Class<T> clazz, Object hashKey, Object rangeKey, DynamoDBMapperConfig config) {
80+
throw new UnsupportedOperationException("operation not supported in " + getClass());
81+
}
82+
83+
@Override
84+
public <T> T load(T keyObject) {
85+
return load(keyObject, config);
86+
}
87+
88+
@Override
89+
public <T> T load(T keyObject, DynamoDBMapperConfig config) {
90+
throw new UnsupportedOperationException("operation not supported in " + getClass());
91+
}
92+
93+
@Override
94+
public <T> T marshallIntoObject(Class<T> clazz, Map<String, AttributeValue> itemAttributes) {
95+
return marshallIntoObject(clazz, itemAttributes, config);
96+
}
97+
98+
public <T> T marshallIntoObject(Class<T> clazz, Map<String, AttributeValue> itemAttributes, DynamoDBMapperConfig config) {
99+
throw new UnsupportedOperationException("operation not supported in " + getClass());
100+
}
101+
}
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/*
2+
* Copyright 2013-2025 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at:
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
11+
* OR CONDITIONS OF ANY KIND, either express or implied. See the
12+
* License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
package software.amazon.awssdk.dynamodb.datamodeling;
16+
17+
import java.util.Map;
18+
19+
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
20+
21+
/**
22+
* A hook allowing a custom transform/untransform of the raw attribute
23+
* values immediately before writing them into DynamoDB and immediately
24+
* after reading them out of DynamoDB, but with extra context about
25+
* the model class not available at the raw AmazonDynamoDB level.
26+
* <p>
27+
* This interface contains both a {@code transform} method and a corresponding
28+
* {@code untransform} method. These methods SHOULD be inverses, such that
29+
* untransform(transform(value)) == value.
30+
*/
31+
public interface AttributeTransformer {
32+
/**
33+
* Parameters for the {@code transform} and {@code untransform} methods,
34+
* so we don't have to break the interface in order to add additional
35+
* parameters.
36+
* <p>
37+
* Consuming code should NOT implement this interface.
38+
*/
39+
interface Parameters<T> {
40+
/**
41+
* Returns the raw attribute values to be transformed or untransformed.
42+
* The returned map is not modifiable.
43+
*
44+
* @return the raw attribute values to transform or untransform
45+
*/
46+
Map<String, AttributeValue> getAttributeValues();
47+
48+
/**
49+
* Returns true if this transformation is being called as part of a
50+
* partial update operation. If true, the attributes returned by
51+
* {@link #getAttributeValues()} do not represent the entire new
52+
* item, but only a snapshot of the attributes which are getting
53+
* new values.
54+
* <p>
55+
* Implementations which do not support transforming a partial
56+
* view of an item (for example, because they need to calculate a
57+
* signature based on all of the item's attributes that won't be valid
58+
* if only a subset of the attributes are taken into consideration)
59+
* should check this flag and throw an exception rather than than
60+
* corrupting the data in DynamoDB.
61+
* <p>
62+
* This method always returns {@code false} for instances passed to
63+
* {@link AttributeTransformer#untransform(Parameters)}.
64+
*
65+
* @return true if this operation is a partial update, false otherwise
66+
*/
67+
boolean isPartialUpdate();
68+
69+
/**
70+
* @return the type of the model class we're transforming to or from
71+
*/
72+
Class<T> getModelClass();
73+
74+
/**
75+
* @return the mapper config for this operation
76+
*/
77+
DynamoDBMapperConfig getMapperConfig();
78+
79+
/**
80+
* @return the name of the DynamoDB table the attributes were read
81+
* from or will be written to
82+
*/
83+
String getTableName();
84+
85+
/**
86+
* @return the name of the hash key for the table
87+
*/
88+
String getHashKeyName();
89+
90+
/**
91+
* @return the name of the range key for the table, if it has one,
92+
* otherwise {@code null}
93+
*/
94+
String getRangeKeyName();
95+
}
96+
97+
/**
98+
* Transforms the input set of attribute values derived from the model
99+
* object before writing them into DynamoDB.
100+
*
101+
* @param parameters transformation parameters
102+
* @return the transformed attribute value map
103+
*/
104+
Map<String, AttributeValue> transform(Parameters<?> parameters);
105+
106+
/**
107+
* Untransform the input set of attribute values read from DynamoDB before
108+
* creating a model object from them.
109+
*
110+
* @param parameters transformation parameters
111+
* @return the untransformed attribute value map
112+
*/
113+
Map<String, AttributeValue> untransform(Parameters<?> parameters);
114+
}

0 commit comments

Comments
 (0)