in runtime/src/main/java/com/google/cloud/verticals/foundations/dataharmonization/builtins/Core.java [402:449]
private static void hashObj(Data obj, Hasher h) {
if (obj.isNullOrEmpty()) {
hashBytes(NIL.getBytes(UTF_8), new byte[] {}, h);
} else if (obj.isPrimitive()) {
Primitive primitiveObj = obj.asPrimitive();
if (primitiveObj.string() != null) {
hashBytes(STR.getBytes(UTF_8), primitiveObj.string().getBytes(UTF_8), h);
} else if (primitiveObj.num() != null) {
byte[] b = ByteBuffer.wrap(new byte[8]).putDouble(primitiveObj.num()).array();
hashBytes(NUM.getBytes(UTF_8), b, h);
} else { // Primitive represents boolean value
byte[] b = new byte[1];
b[0] = 1;
if (primitiveObj.bool()) {
b[0] = 2;
}
hashBytes(BOOL.getBytes(UTF_8), b, h);
}
} else if (obj.isArray()) {
Array arrayObj = obj.asArray();
for (int i = 0; i < arrayObj.size(); ++i) {
hashObj(arrayObj.getElement(i), h);
}
} else if (obj.isContainer()) {
Container containerObj = obj.asContainer();
@Var Map<String, Data> sorted = new HashMap<>();
for (String field : containerObj.nonNullFields()) {
sorted.put(field, containerObj.getField(field));
}
sorted =
sorted.entrySet().stream()
.sorted(comparingByKey())
.collect(
toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(e1 /* merge value old */, e2 /* merge value new */) -> e2 /* keep new */,
LinkedHashMap::new));
sorted.forEach(
(key, val) -> {
hashBytes(KEY.getBytes(UTF_8), key.getBytes(UTF_8), h);
hashObj(val, h);
});
} else {
throw new UnsupportedOperationException("Unsupported type to hash: " + obj.getClass() + ".");
}
}