Skip to content

Commit

Permalink
[MS-432] Fix recursion detection of mutual parents
Browse files Browse the repository at this point in the history
Case: A has parents B and C, and B's parent is also C
This is not a recursion but was mistakenly detected as one.
  • Loading branch information
daforster committed Jul 30, 2024
1 parent 7a1b08b commit e1a574d
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 9 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)

## Unreleased

### Fixed

- Recursion detection of a mutual parent

## [9.3.0](https://github.com/dbmdz/metadata-service/releases/tag/9.3.0) - 2024-07-09

### Added
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
Expand Down Expand Up @@ -242,22 +243,24 @@ private <I extends Identifiable> void preventStackOverflow(
throw new IllegalArgumentException(
"A function to get the parents must be provided (getParents)!");
if (testObjects == null || testObjects.isEmpty()) return;
List<UUID> prohibitions = prohibitedChildUuids;
if (prohibitedChildUuids == null) {
prohibitedChildUuids = Collections.emptyList();
}
for (I t : testObjects) {
if (prohibitedChildUuids == null) {
// every "branch" gets a new list
prohibitions = new ArrayList<>();
}
if (prohibitions.contains(t.getUuid()))
if (prohibitedChildUuids.contains(t.getUuid()))
throw new ServiceException(
"Endless recursion detected at object %s related with the objects %s"
.formatted(
t.getUuid(),
prohibitions.stream().map(UUID::toString).collect(Collectors.joining(", "))));
prohibitions.add(t.getUuid());
prohibitedChildUuids.stream()
.map(UUID::toString)
.collect(Collectors.joining(", "))));
List<I> parents = getParents.apply(t);
if (parents == null || parents.isEmpty()) continue;
preventStackOverflow(parents, prohibitions, getParents);
preventStackOverflow(
parents,
Stream.concat(prohibitedChildUuids.stream(), Stream.of(t.getUuid())).toList(),
getParents);
}
}

Expand Down

0 comments on commit e1a574d

Please sign in to comment.