in src/main/java/org/apache/datasketches/server/MergeHandler.java [140:201]
private Family prepareSketches(final JsonArray sources, Family family, final String dst, final ArrayList<MergeEntry> sketchList) {
final HashSet<String> namedSet = new HashSet<>();
// TODO: Check for sketch value types with distinct counting?
// Less obvious how to handle serialized sketch input in that case
// add destination if one exists just in case it's also listed as a source
if (dst != null) {
namedSet.add(dst);
}
for (final JsonElement elmt : sources) {
if (elmt.isJsonPrimitive()) {
// check family
final String key = elmt.getAsString();
final SketchStorage.SketchEntry entry = sketches.getSketch(key);
if (entry == null || (family != null && family != entry.family_)) {
throw new SketchesException("Input sketches must exist and be of the same family as the target");
}
// add to set, save family if we didn't have one yet
if (!namedSet.contains(key)) {
namedSet.add(key);
if (family == null) {
family = entry.family_;
}
// if we have a theta Union we need to get the result first
if (entry.family_ == Family.UNION) {
sketchList.add(new MergeEntry(key, ((Union) entry.sketch_).getResult()));
} else {
sketchList.add(new MergeEntry(key, entry.sketch_));
}
}
} else { // is JsonObject
// need special handling for theta as we store Unions?
final JsonObject sourceObj = elmt.getAsJsonObject();
if (!sourceObj.has(SketchConstants.QUERY_FAMILY_FIELD)
|| !sourceObj.has(SketchConstants.QUERY_DATA_FIELD)) {
throw new SketchesException("Base64 sketch used as merge input must specify both \""
+ SketchConstants.QUERY_FAMILY_FIELD + "\" and \"" + SketchConstants.QUERY_DATA_FIELD + "\"");
}
final Family skFamily = familyFromString(sourceObj.get(SketchConstants.QUERY_FAMILY_FIELD).getAsString());
final String skString = sourceObj.get(SketchConstants.QUERY_DATA_FIELD).getAsString();
if (skString == null || (family != null
&& ((family != Family.UNION && family != skFamily) || (family == Family.UNION && skFamily != Family.QUICKSELECT)))) {
throw new SketchesException("Input sketches must exist and be of the same family as the target");
}
// add to list, save family if we didn't have one yet
// use hashcode of sketch as name -- we'll later create a needless lock but cleaner than conditional locking
final Object sketch = deserializeSketch(skFamily, skString);
sketchList.add(new MergeEntry(Integer.toString(sketch.hashCode()), sketch));
if (family == null) {
family = skFamily;
}
}
}
return family;
}