Merge branch 'findRelationsRecursively_refactoring' of github.com:smatvienko-tb/thingsboard

This commit is contained in:
Andrii Shvaika 2022-11-03 17:28:21 +02:00
commit 5cbb8b8ca5

View File

@ -52,6 +52,7 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.stream.Collectors;
import static org.thingsboard.server.dao.service.Validator.validateId; import static org.thingsboard.server.dao.service.Validator.validateId;
@ -512,40 +513,42 @@ public class BaseRelationService implements RelationService {
private ListenableFuture<Set<EntityRelation>> findRelationsRecursively(final TenantId tenantId, final EntityId rootId, final EntitySearchDirection direction, private ListenableFuture<Set<EntityRelation>> findRelationsRecursively(final TenantId tenantId, final EntityId rootId, final EntitySearchDirection direction,
RelationTypeGroup relationTypeGroup, int lvl, boolean fetchLastLevelOnly, RelationTypeGroup relationTypeGroup, int lvl, boolean fetchLastLevelOnly,
final ConcurrentHashMap<EntityId, Boolean> uniqueMap) throws Exception { final ConcurrentHashMap<EntityId, Boolean> uniqueMap) {
if (lvl == 0) { if (lvl == 0) {
return Futures.immediateFuture(Collections.emptySet()); return Futures.immediateFuture(Collections.emptySet());
} }
lvl--; final int currentLvl = --lvl;
//TODO: try to remove this blocking operation final Set<EntityRelation> children = new HashSet<>();
Set<EntityRelation> children = new HashSet<>(findRelations(tenantId, rootId, direction, relationTypeGroup).get()); ListenableFuture<List<EntityRelation>> rootRelationsFuture = findRelations(tenantId, rootId, direction, relationTypeGroup);
Set<EntityId> childrenIds = new HashSet<>(); ListenableFuture<Set<EntityId>> childrenIdsFuture = Futures.transform(rootRelationsFuture, relations -> {
for (EntityRelation childRelation : children) { children.addAll(relations);
log.trace("Found Relation: {}", childRelation); Set<EntityId> childrenIds = new HashSet<>();
EntityId childId; for (EntityRelation childRelation : children) {
if (direction == EntitySearchDirection.FROM) { log.trace("Found Relation: {}", childRelation);
childId = childRelation.getTo(); EntityId childId = direction == EntitySearchDirection.FROM ? childRelation.getTo() : childRelation.getFrom();
} else { if (uniqueMap.putIfAbsent(childId, Boolean.TRUE) == null) {
childId = childRelation.getFrom(); log.trace("Adding Relation: {}", childId);
} if (childrenIds.add(childId)) {
if (uniqueMap.putIfAbsent(childId, Boolean.TRUE) == null) { log.trace("Added Relation: {}", childId);
log.trace("Adding Relation: {}", childId); }
if (childrenIds.add(childId)) {
log.trace("Added Relation: {}", childId);
} }
} }
} return childrenIds;
List<ListenableFuture<Set<EntityRelation>>> futures = new ArrayList<>(); }, MoreExecutors.directExecutor());
for (EntityId entityId : childrenIds) {
futures.add(findRelationsRecursively(tenantId, entityId, direction, relationTypeGroup, lvl, fetchLastLevelOnly, uniqueMap)); ListenableFuture<List<Set<EntityRelation>>> recursiveFutures = Futures.transformAsync(childrenIdsFuture, childrenIds ->
} Futures.successfulAsList(childrenIds.stream()
//TODO: try to remove this blocking operation .map(entityId -> findRelationsRecursively(tenantId, entityId, direction, relationTypeGroup, currentLvl, fetchLastLevelOnly, uniqueMap))
List<Set<EntityRelation>> relations = Futures.successfulAsList(futures).get(); .collect(Collectors.toList())), MoreExecutors.directExecutor());
if (fetchLastLevelOnly && lvl > 0) {
children.clear(); ListenableFuture<Set<EntityRelation>> relationsFuture = Futures.transform(recursiveFutures, recursiveRelations -> {
} if (fetchLastLevelOnly && currentLvl > 0) {
relations.forEach(r -> r.forEach(children::add)); children.clear();
return Futures.immediateFuture(children); }
recursiveRelations.forEach(children::addAll);
return children;
}, MoreExecutors.directExecutor());
return relationsFuture;
} }
private ListenableFuture<List<EntityRelation>> findRelations(final TenantId tenantId, final EntityId rootId, final EntitySearchDirection direction, RelationTypeGroup relationTypeGroup) { private ListenableFuture<List<EntityRelation>> findRelations(final TenantId tenantId, final EntityId rootId, final EntitySearchDirection direction, RelationTypeGroup relationTypeGroup) {