Skip to content

Commit 121be88

Browse files
committed
Refactor Serializer to share factory
1 parent 6b2036a commit 121be88

File tree

9 files changed

+165
-7
lines changed

9 files changed

+165
-7
lines changed

services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/internal/document/DefaultEnhancedDocument.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ public String getJson(String attributeName) {
193193
if (attributeValue == null) {
194194
return null;
195195
}
196-
return stringValue(JSON_ATTRIBUTE_CONVERTER.transformTo(attributeValue));
196+
return StrategyJsonSerializer.serializeSingleAttributeValue(attributeValue);
197197
}
198198

199199
@Override

services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/internal/document/StrategyJsonSerializer.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010

1111
@SdkInternalApi
1212
public final class StrategyJsonSerializer {
13+
private static final JsonFactory jsonFactory = new JsonFactory();
14+
15+
private StrategyJsonSerializer() {
16+
}
1317

1418
private enum JsonSerializationStrategy {
1519
NULL,
@@ -25,7 +29,7 @@ private enum JsonSerializationStrategy {
2529
}
2630

2731
public static String serializeAttributeValueMap(Map<String, AttributeValue> map) {
28-
SdkJsonGenerator jsonGen = new SdkJsonGenerator(new JsonFactory(), "application/json");
32+
SdkJsonGenerator jsonGen = new SdkJsonGenerator(jsonFactory, "application/json"); // re-use factory
2933

3034
jsonGen.writeStartObject();
3135
map.forEach((key, value) -> {
@@ -37,6 +41,12 @@ public static String serializeAttributeValueMap(Map<String, AttributeValue> map)
3741
return new String(jsonGen.getBytes(), StandardCharsets.UTF_8);
3842
}
3943

44+
public static String serializeSingleAttributeValue(AttributeValue av) {
45+
SdkJsonGenerator jsonGen = new SdkJsonGenerator(jsonFactory, "application/json"); // re-use factory
46+
serializeAttributeValue(jsonGen, av);
47+
return new String(jsonGen.getBytes(), StandardCharsets.UTF_8);
48+
}
49+
4050
public static void serializeAttributeValue(SdkJsonGenerator generator, AttributeValue av) {
4151
JsonSerializationStrategy strategy = getStrategy(av);
4252

services-custom/dynamodb-enhanced/src/test/java/software/amazon/awssdk/enhanced/dynamodb/document/EnhancedDocumentTest.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,4 +632,26 @@ void toJson_emoji() {
632632
assertThat(json).isEqualTo("{\"emoji\":" + emoji + "}");
633633
}
634634

635+
@Test
636+
void getJson_returnsRawValue() {
637+
EnhancedDocument doc = EnhancedDocument.builder()
638+
.attributeConverterProviders(defaultProvider())
639+
.putString("key", "value")
640+
.build();
641+
642+
String result = doc.getJson("key");
643+
assertThat(result).isEqualTo("\"value\"");
644+
}
645+
646+
@Test
647+
void getJson_nonExistentAttribute() {
648+
EnhancedDocument doc = EnhancedDocument.builder()
649+
.attributeConverterProviders(defaultProvider())
650+
.putString("exists", "value")
651+
.build();
652+
653+
String result = doc.getJson("doesNotExist");
654+
assertThat(result).isNull();
655+
}
656+
635657
}

test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/enhanced/dynamodb/JsonConversionBenchmark.java

Lines changed: 126 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.openjdk.jmh.annotations.Setup;
2626
import org.openjdk.jmh.annotations.State;
2727
import org.openjdk.jmh.annotations.Warmup;
28+
import software.amazon.awssdk.enhanced.dynamodb.AttributeConverterProvider;
2829
import software.amazon.awssdk.enhanced.dynamodb.document.EnhancedDocument;
2930
import com.amazonaws.services.dynamodbv2.document.Item;
3031

@@ -41,18 +42,137 @@
4142
@State(Scope.Benchmark)
4243
public class JsonConversionBenchmark {
4344

44-
private String jsonString;
4545
private EnhancedDocument v2Document;
4646
private Item v1Item;
4747

48+
private EnhancedDocument entireDoc;
49+
private EnhancedDocument doc50b;
50+
private EnhancedDocument doc100b;
51+
private EnhancedDocument doc500b;
52+
private EnhancedDocument doc1kb;
53+
private Item v1Item50b;
54+
private Item v1Item100b;
55+
private Item v1Item500b;
56+
private Item v1Item1kb;
57+
4858
@Setup
4959
public void setup() throws IOException {
50-
jsonString = new String(Files
51-
.readAllBytes(Paths.get("src/main/java/software/amazon/awssdk/benchmark/enhanced/dynamodb/large_data.json")));
52-
v2Document = EnhancedDocument.fromJson(jsonString);
53-
v1Item = Item.fromJSON(jsonString);
60+
String entireJsonString = new String(Files
61+
.readAllBytes(Paths.get("src/main/java/software/amazon/awssdk/benchmark/enhanced/dynamodb/large_data.json")));
62+
String payload50b = new String(Files
63+
.readAllBytes(Paths.get("src/main/java/software/amazon/awssdk/benchmark/enhanced/dynamodb/payload_50b.json")));
64+
String payload100b = new String(Files
65+
.readAllBytes(Paths.get("src/main/java/software/amazon/awssdk/benchmark/enhanced/dynamodb/payload_100b.json")));
66+
String payload500b = new String(Files
67+
.readAllBytes(Paths.get("src/main/java/software/amazon/awssdk/benchmark/enhanced/dynamodb/payload_500b.json")));
68+
String payload1kb = new String(Files
69+
.readAllBytes(Paths.get("src/main/java/software/amazon/awssdk/benchmark/enhanced/dynamodb/payload_1kb.json")));
70+
71+
72+
v2Document = EnhancedDocument.fromJson(entireJsonString);
73+
v1Item = Item.fromJSON(entireJsonString);
74+
75+
v1Item.withJSON("entireDocument", entireJsonString);
76+
77+
entireDoc = EnhancedDocument.builder()
78+
.addAttributeConverterProvider(AttributeConverterProvider.defaultProvider())
79+
.putString("id", "entireDoc")
80+
.putJson("entireDocument", entireJsonString)
81+
.build();
82+
83+
doc50b = EnhancedDocument.builder()
84+
.addAttributeConverterProvider(AttributeConverterProvider.defaultProvider())
85+
.putString("id", "test")
86+
.putJson("data", payload50b)
87+
.build();
88+
89+
doc100b = EnhancedDocument.builder()
90+
.addAttributeConverterProvider(AttributeConverterProvider.defaultProvider())
91+
.putString("id", "test")
92+
.putJson("data", payload100b)
93+
.build();
94+
95+
doc500b = EnhancedDocument.builder()
96+
.addAttributeConverterProvider(AttributeConverterProvider.defaultProvider())
97+
.putString("id", "test")
98+
.putJson("data", payload500b)
99+
.build();
100+
101+
doc1kb = EnhancedDocument.builder()
102+
.addAttributeConverterProvider(AttributeConverterProvider.defaultProvider())
103+
.putString("id", "test")
104+
.putJson("data", payload1kb)
105+
.build();
106+
107+
v1Item50b = new Item()
108+
.withString("id", "test")
109+
.withJSON("data", payload50b);
110+
111+
v1Item100b = new Item()
112+
.withString("id", "test")
113+
.withJSON("data", payload100b);
114+
115+
v1Item500b = new Item()
116+
.withString("id", "test")
117+
.withJSON("data", payload500b);
118+
119+
v1Item1kb = new Item()
120+
.withString("id", "test")
121+
.withJSON("data", payload1kb);
122+
}
123+
124+
// getJson() meant to get a sub structure of a larger json file. testing with different sizes.
125+
@Benchmark
126+
public String getJson50b() {
127+
return doc50b.getJson("data");
128+
}
129+
130+
@Benchmark
131+
public String getJson100b() {
132+
return doc100b.getJson("data");
133+
}
134+
135+
@Benchmark
136+
public String getJson500b() {
137+
return doc500b.getJson("data");
54138
}
55139

140+
@Benchmark
141+
public String getJson1kb() {
142+
return doc1kb.getJson("data");
143+
}
144+
145+
@Benchmark
146+
public String v1GetJson50b() {
147+
return v1Item50b.getJSON("data");
148+
}
149+
150+
@Benchmark
151+
public String v1GetJson100b() {
152+
return v1Item100b.getJSON("data");
153+
}
154+
155+
@Benchmark
156+
public String v1GetJson500b() {
157+
return v1Item500b.getJSON("data");
158+
}
159+
160+
@Benchmark
161+
public String v1GetJson1kb() {
162+
return v1Item1kb.getJSON("data");
163+
}
164+
165+
@Benchmark
166+
public String v1GetJsonEntireDoc() {
167+
return v1Item.getJSON("entireDocument");
168+
}
169+
170+
@Benchmark
171+
public String v2GetJsonEntireDoc() {
172+
return entireDoc.getJson("entireDocument");
173+
}
174+
175+
// toJson() benchmarking (only for large data set)
56176
@Benchmark
57177
public String v1ToJson() {
58178
return v1Item.toJSON();
@@ -62,4 +182,5 @@ public String v1ToJson() {
62182
public String v2ToJson() {
63183
return v2Document.toJson();
64184
}
185+
65186
}

test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/enhanced/dynamodb/large_data.json

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"id":"test-100","name":"Sample Document","version":1,"tags":["tag1","tag2","tag3"],"active":true}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"orderId":"ORD-2024-10-28-001","customer":{"customerId":"CUST-98765","name":"Jane Smith","email":"[email protected]","phone":"+1-555-9876","shippingAddress":{"street":"456 Oak Avenue","city":"Portland","state":"OR","zip":"97201","country":"USA"},"billingAddress":{"street":"456 Oak Avenue","city":"Portland","state":"OR","zip":"97201","country":"USA"}},"items":[{"sku":"PROD-001","name":"Wireless Headphones","quantity":2,"price":79.99,"discount":10.0},{"sku":"PROD-002","name":"USB-C Cable","quantity":3,"price":12.99,"discount":0.0},{"sku":"PROD-003","name":"Phone Case","quantity":1,"price":24.99,"discount":5.0}],"payment":{"method":"credit_card","cardLast4":"4242","amount":234.92,"currency":"USD","transactionId":"TXN-ABC123XYZ"},"shipping":{"carrier":"UPS","trackingNumber":"1Z999AA10123456784","estimatedDelivery":"2024-11-02T17:00:00Z","shippingCost":8.99},"metadata":{"orderDate":"2024-10-28T11:15:00Z","status":"processing","notes":"Gift wrap requested","tags":["priority","gift","insured"]}}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"userId":"user-12345","profile":{"firstName":"John","lastName":"Doe","email":"[email protected]","phone":"+1-555-0123","address":{"street":"123 Main St","city":"Seattle","state":"WA","zip":"98101"},"preferences":{"theme":"dark","notifications":true,"language":"en-US"}},"metadata":{"createdAt":"2024-01-15T10:30:00Z","lastLogin":"2024-10-28T09:15:00Z","loginCount":247,"accountType":"premium","tags":["verified","active","beta-tester"]}}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"id":"u123","name":"Alice","active":true}

0 commit comments

Comments
 (0)