Добрый день. Возникло вот такое затруднение, возможно кто-то знает грамотное решение.
Существует иерархическая структура данных, которая периодически обновляется на основе выгрузки из внешнего источника. Выгрузка может быть полная или по одному конкретному узлу.
Каждый узел имеет булевский аттрибут 'hidden', который приходит в выгрузке. Также узел имеет некий контент, который может быть и пустым. Также каждый узел имеет булевский аттрибут 'empty', который нужно заново рассчитать в момент синхронизации.
Аттрибут empty должен быть выставлен true, если узел соответствует всем условиям:
- Узел имеет пустой контент
- Узел не имеет не-empty и не-hidden потомков
В выгрузке потомки идут гарантированно после своих родителей, поэтому раньше определение empty осуществлялось так:
Программа проходит последовательно по выгрузке, каждый узел добавляет в базу или обновляет, если он там уже есть. Смотрит в выгрузке, пустой ли у него контент. Делает выборку в своей базе непосредственных потомков этого узла, которые не empty и не hidden. На основе этого выставляет значение empty.
После этого программа последовательно проходит вверх по цепочке родителей этого узла и проделывает для них ту же процедуру. Это нужно потому, что в пока не отработанной части выгрузки будет информация о потомках, и если обновился их список или их значения empty и hidden, то это может сделать невалидным значение empty родителя, и его нужно пересчитать.
Знаю, что алгоритм выглядит неоптимальным, но его писал не я.
Сейчас пришла задача: сделать так, чтобы узёл могли являться как бы алиасом (ссылкой) на другой узел. Это нужно для реализации параллельной иерархии.
Соответственно, в расчёте empty нужно учитывать, что узел должен быть не-empty, если ссылается на не-empty узел. Проблема в том, что в выгрузке алиас может присутствовать как раньше, так и позже того узла, на который он ссылается.
Как правильнее всего реализовать такую структуру с учётом описанных требований?