Skip to content

Commit 66daf5e

Browse files
committed
[dnm] sort stringified set elements
Stringified set elements are now outputted in sorted order according to their stringified representation, where previously the output order was determined by the record ordinals. Note that this doesn't sort number elements correctly, e.g., ``` "10" "2" ```
1 parent a64f19e commit 66daf5e

File tree

5 files changed

+107
-8
lines changed

5 files changed

+107
-8
lines changed

hollow/src/main/java/com/netflix/hollow/tools/stringifier/HollowRecordJsonStringifier.java

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import java.util.Collections;
4141
import java.util.HashSet;
4242
import java.util.Iterator;
43+
import java.util.List;
4344
import java.util.Set;
4445

4546
/**
@@ -284,15 +285,28 @@ private void appendSetStringify(Writer writer, HollowDataAccess dataAccess, Holl
284285

285286
int elementOrdinal = iter.next();
286287

287-
if (elementOrdinal == HollowOrdinalIterator.NO_MORE_ORDINALS) {
288+
289+
List<Integer> elementOrdinals = new java.util.ArrayList<>();
290+
while (elementOrdinal != HollowOrdinalIterator.NO_MORE_ORDINALS) {
291+
elementOrdinals.add(elementOrdinal);
292+
elementOrdinal = iter.next();
293+
}
294+
295+
elementOrdinals.sort((o1, o2) -> {
296+
String element1 = stringify(dataAccess, elementType, o1);
297+
String element2 = stringify(dataAccess, elementType, o2);
298+
return element1.compareTo(element2);
299+
});
300+
301+
if (elementOrdinals.isEmpty()) {
288302
writer.append("[]");
289303
} else {
290304
boolean firstElement = true;
291305
writer.append("[");
292306
if (prettyPrint)
293307
writer.append(NEWLINE);
294308

295-
while(elementOrdinal != HollowOrdinalIterator.NO_MORE_ORDINALS) {
309+
for (int ord : elementOrdinals) {
296310
if (firstElement)
297311
firstElement = false;
298312
else
@@ -301,9 +315,7 @@ private void appendSetStringify(Writer writer, HollowDataAccess dataAccess, Holl
301315
if (prettyPrint)
302316
appendIndentation(writer, indentation);
303317

304-
appendStringify(writer, dataAccess, elementType, elementOrdinal, indentation);
305-
306-
elementOrdinal = iter.next();
318+
appendStringify(writer, dataAccess, elementType, ord, indentation);
307319
}
308320

309321
if (prettyPrint) {

hollow/src/main/java/com/netflix/hollow/tools/stringifier/HollowRecordStringifier.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import java.util.Arrays;
3939
import java.util.HashSet;
4040
import java.util.Iterator;
41+
import java.util.List;
4142
import java.util.Set;
4243

4344
/**
@@ -184,15 +185,25 @@ private void appendSetStringify(Writer writer, HollowDataAccess dataAccess,
184185

185186
int elementOrdinal = iter.next();
186187

188+
List<Integer> elementOrdinals = new java.util.ArrayList<>();
187189
while(elementOrdinal != NO_MORE_ORDINALS) {
190+
elementOrdinals.add(elementOrdinal);
191+
elementOrdinal = iter.next();
192+
}
193+
194+
elementOrdinals.sort((o1, o2) -> {
195+
String element1 = stringify(dataAccess, elementType, o1);
196+
String element2 = stringify(dataAccess, elementType, o2);
197+
return element1.compareTo(element2);
198+
});
199+
200+
for (Integer sortedElementOrd : elementOrdinals) {
188201
writer.append(NEWLINE);
189202

190203
appendIndentation(writer, indentation);
191204
writer.append("e: ");
192205

193-
appendStringify(writer, dataAccess, elementType, elementOrdinal, indentation);
194-
195-
elementOrdinal = iter.next();
206+
appendStringify(writer, dataAccess, elementType, sortedElementOrd, indentation);
196207
}
197208
}
198209

hollow/src/test/java/com/netflix/hollow/tools/stringifier/AbstractHollowRecordStringifierTest.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import com.netflix.hollow.core.write.objectmapper.HollowObjectMapper;
2525
import java.io.IOException;
2626
import java.io.StringWriter;
27+
import java.util.Set;
2728

2829
/**
2930
* Code shared between HollowRecordStringifierTest and HollowRecordJsonStringifierTest.
@@ -73,6 +74,21 @@ public TypeWithNestedNonPrimitive(Double value, TypeWithNonPrimitive nestedType)
7374
}
7475
}
7576

77+
static class TypeWithSetOfPrimitives {
78+
private final Set<TypeWithPrimitive> values;
79+
80+
public TypeWithSetOfPrimitives(Set<TypeWithPrimitive> values) {
81+
this.values = values;
82+
}
83+
}
84+
85+
static class TypeWithSetOfStrings {
86+
private final Set<TypeWithString> values;
87+
88+
public TypeWithSetOfStrings(Set<TypeWithString> values) {
89+
this.values = values;
90+
}
91+
}
7692

7793
/**
7894
* Sends instances of a type through the HollowRecordStringifier. This concatenates records

hollow/src/test/java/com/netflix/hollow/tools/stringifier/HollowRecordJsonStringifierTest.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,34 @@ public void testStringifyStringWithEscapeChars() throws IOException {
206206
stringifyType(TypeWithString.class, true, false, new TypeWithString(testString)));
207207
}
208208

209+
@Test
210+
public void testStringifySetOfPrimitives() throws IOException {
211+
// We expect the set of primitives to be sorted (by their string representation).
212+
Assert.assertEquals("Set of primitives should be printed correctly",
213+
"[100,200,300]",
214+
stringifyType(TypeWithSetOfPrimitives.class, false, false,
215+
new TypeWithSetOfPrimitives(
216+
new java.util.HashSet<>(Arrays.asList(
217+
new TypeWithPrimitive(100),
218+
new TypeWithPrimitive(300),
219+
new TypeWithPrimitive(200)
220+
)))));
221+
}
222+
223+
@Test
224+
public void testStringifySetOfStrings() throws IOException {
225+
// We expect that the set of strings will be sorted.
226+
Assert.assertEquals("Set of strings should be printed correctly",
227+
"[\"a\",\"b\",\"c\"]",
228+
stringifyType(TypeWithSetOfStrings.class, false, false,
229+
new TypeWithSetOfStrings(
230+
new java.util.HashSet<>(Arrays.asList(
231+
new TypeWithString("c"),
232+
new TypeWithString("a"),
233+
new TypeWithString("b")
234+
)))));
235+
}
236+
209237
private static <T> String stringifyType(Class<T> clazz, boolean prettyPrint, boolean expanded, T... instances) throws IOException {
210238
HollowRecordJsonStringifier stringifier = new HollowRecordJsonStringifier(prettyPrint, !expanded);
211239
// HollowRecordJsonStringifier stringifier = expanded

hollow/src/test/java/com/netflix/hollow/tools/stringifier/HollowRecordStringifierTest.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,38 @@ public void testStringifyIterator() throws IOException {
135135
"\n]", writer.toString());
136136
}
137137

138+
@Test
139+
public void testStringifySetOfPrimitives() throws IOException {
140+
// We expect the set of primitives to be sorted (by their string representation).
141+
Assert.assertEquals("Set of primitives should be printed correctly",
142+
"\n e: 100\n" +
143+
" e: 200\n" +
144+
" e: 300",
145+
stringifyType(TypeWithSetOfPrimitives.class, false,
146+
new TypeWithSetOfPrimitives(
147+
new java.util.HashSet<>(Arrays.asList(
148+
new TypeWithPrimitive(100),
149+
new TypeWithPrimitive(300),
150+
new TypeWithPrimitive(200)
151+
)))));
152+
}
153+
154+
@Test
155+
public void testStringifySetOfStrings() throws IOException {
156+
// We expect the set of strings to be sorted.
157+
Assert.assertEquals("Set of strings should be printed correctly",
158+
"\n e: a\n" +
159+
" e: b\n" +
160+
" e: c",
161+
stringifyType(TypeWithSetOfStrings.class, false,
162+
new TypeWithSetOfStrings(
163+
new java.util.HashSet<>(Arrays.asList(
164+
new TypeWithString("c"),
165+
new TypeWithString("a"),
166+
new TypeWithString("b")
167+
)))));
168+
}
169+
138170
private static <T> String stringifyType(Class<T> clazz, boolean expanded, T... instances) throws IOException {
139171
HollowRecordStringifier stringifier = expanded
140172
? new HollowRecordStringifier(true, true, false) : new HollowRecordStringifier();

0 commit comments

Comments
 (0)