tihom88 commented on code in PR #2302: URL: https://github.com/apache/jackrabbit-oak/pull/2302#discussion_r2101817966
########## oak-run/src/main/java/org/apache/jackrabbit/oak/index/merge/IndexDefMergerUtils.java: ########## @@ -287,6 +292,81 @@ private static JsonObject mergeChild(String path, String child, int level, JsonO } } + private static JsonObject mergeAggregates(String path, String child, int level, JsonObject ancestor, JsonObject custom, JsonObject product, + ArrayList<String> conflicts) { + + // merge, with level + 1 so that we don't recurse into this function again + // conflicts are redirected to a new, temporary list + ArrayList<String> aggregateConflicts = new ArrayList<>(); + JsonObject merged = mergeChild(path, child, level + 1, ancestor, custom, product, aggregateConflicts); + + // if there were conflicts, resolve them + if (!aggregateConflicts.isEmpty()) { + + // list of "include" elements to move to the end + ArrayList<JsonObject> elementToMove = new ArrayList<>(); + + // which is the next id for "include" (eg. 12) + long nextIncludeId = getNextIncludeId(ancestor.getChildren().get(child)); + nextIncludeId = Math.max(nextIncludeId, getNextIncludeId(custom.getChildren().get(child))); + nextIncludeId = Math.max(nextIncludeId, getNextIncludeId(product.getChildren().get(child))); + + // loop over conflicts, and find + remove these + // the aggregateConflicts will contain entries that look like this: + // "Could not merge value; path=/oak:index/assets-11/aggregates/asset/include11 + // property=path; ancestor=null; custom=...; product=..." + // and we need to extract the path + for (String n : aggregateConflicts) { + String regex = "path=([^\\s]+)\\sproperty="; Review Comment: I think instead of conflict string, we should conflict json or a serialised object and get rid of regex conditions. ########## oak-run/src/main/java/org/apache/jackrabbit/oak/index/merge/IndexDefMergerUtils.java: ########## @@ -287,6 +292,81 @@ private static JsonObject mergeChild(String path, String child, int level, JsonO } } + private static JsonObject mergeAggregates(String path, String child, int level, JsonObject ancestor, JsonObject custom, JsonObject product, + ArrayList<String> conflicts) { + + // merge, with level + 1 so that we don't recurse into this function again + // conflicts are redirected to a new, temporary list + ArrayList<String> aggregateConflicts = new ArrayList<>(); + JsonObject merged = mergeChild(path, child, level + 1, ancestor, custom, product, aggregateConflicts); + + // if there were conflicts, resolve them + if (!aggregateConflicts.isEmpty()) { + + // list of "include" elements to move to the end + ArrayList<JsonObject> elementToMove = new ArrayList<>(); + + // which is the next id for "include" (eg. 12) + long nextIncludeId = getNextIncludeId(ancestor.getChildren().get(child)); + nextIncludeId = Math.max(nextIncludeId, getNextIncludeId(custom.getChildren().get(child))); + nextIncludeId = Math.max(nextIncludeId, getNextIncludeId(product.getChildren().get(child))); + + // loop over conflicts, and find + remove these + // the aggregateConflicts will contain entries that look like this: + // "Could not merge value; path=/oak:index/assets-11/aggregates/asset/include11 + // property=path; ancestor=null; custom=...; product=..." + // and we need to extract the path + for (String n : aggregateConflicts) { + String regex = "path=([^\\s]+)\\sproperty="; + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(n); + if (matcher.find()) { + // the path of the conflicting aggregation node + String extractedPath = matcher.group(1); + String[] elements = extractedPath.split("/"); + String conflictElement = elements[elements.length - 1]; + + // remove from the custom list + JsonObject conflict = custom.getChildren().get(child).getChildren().remove(conflictElement); + + // remember the element, to put it back later + elementToMove.add(conflict); + } + } + + // merge again, with conflicts resolved now + // (if there are other conflicts unrelated to aggregation, + // those will not be resolved) + merged = mergeChild(path, child, level + 1, ancestor, custom, product, conflicts); + + // add the aggregation conflict at the end, with new ids + // first we need to clone the merged object, + // because it might be the same object as the product currently + merged = JsonObject.fromJson(merged.toString(), true); + for (JsonObject json : elementToMove) { + merged.getChildren().put("include" + nextIncludeId, json); + nextIncludeId++; + } + } + return merged; + } + + private static long getNextIncludeId(JsonObject json) { + long max = 0; + for(String n : json.getChildren().keySet()) { + if (n.startsWith("include")) { + n = n.substring("include".length()); + try { + long id = Long.parseLong(n); + max = Math.max(max, id); + } catch (NumberFormatException e) { + // ignore Review Comment: Log this info. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: oak-dev-unsubscr...@jackrabbit.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org