Parent-Child-Hierarchien und deren Relationen miteinander verknüpft darzustellen und diese am besten auch noch dynamisch, nach ihrem Vorkommen zusammenzubauen, ist meist keine erfreuliche Aufgabe. Wir haben in diesem Artikel eine Lösung ausgearbeitet und beispielhaft in Talend umgesetzt.

Zuerst klären wir einmal die Begrifflichkeiten:

Was ist eine Hashmap?

Laut Definition von Talend ist eine Hashmap eine Möglichkeit, Daten direkt in den Speicher zu schreiben und vorzuhalten, um die Daten von dort performant auszulesen, sie zu bearbeiten oder sie zu verändern.

Was ist eigentlich Rekursion?

Unter dem Begriff Rekursion versteht man den Aufruf einer Funktion, die einen Teil der Arbeit ermittelt und sich dann selbst aufruft, um diese Teilbereiche noch weiter zu verkleinern. Dies wird so oft fortgeführt, bis entweder das Ziel – die Abschlussbedingung – erfüllt ist oder kein Aufruf mehr möglich ist. Daher muss genau darauf geachtet werden, dass die Rekursion nicht in einer Endlosschleife endet. Wie zum Beispiel eine Abschlussbedingung, die einen Wert beobachtet, welcher sich in der Rekursion aber gar nicht verändert.

Warum beides kombinieren?

Der erste naheliegende Grund ist wohl die Performance. Wenn schon die großen Datenmengen durch die Hashmap im Speicher liegen, können wir diese dort wesentlich schneller nutzen, als wenn wir diese jedes Mal aus einer Datei oder Datenbank lesen müssen. Um eine Rekursion mit Hilfe einer tHashMap zu realisieren, müssen lediglich die tHashInput- und die tHashOutput-Komponente das gleiche Ziel haben.

Abbildung 1: Beispiel einer Rekursiven Hashmap

Damit es deutlich wird schauen wir uns eine Hierarchiestruktur an. Ein Krankenhaus hat bspw. verschiedene Abteilungen, die hierarchisch miteinander verbunden sind. In der Hashmap (tHashInput_1) stehen zu Anfang die Daten zur Verfügung, die im Job berechnet werden sollen. In unserem Beispiel möchten wir für eine Abteilung ermitteln, welche übergeordneten Abteilungen vorhanden sind. Durch die zusätzliche Quelle (tMSSqlInput_1) wird die Datenmenge um eine Hierarchiestruktur erweitert und am Ende in dem Outputpfad wieder in derselben Hashmap gespeichert. Wir wandern die Hierarchie dynamisch nach oben. Durch das Herausleiten in dieselbe Hashmap werden die gerade geschrieben Daten (blauer Pfeil) am Anfang als neu angesehen und wieder verarbeitet. Somit wächst die Anzahl an Daten in der Hashmap. Da wir nicht wissen welche Abteilung wir gerade beobachten und wie viele Abteilungen in der Hierarchie nach oben vorhanden sind, wird dieser Kreislauf immer weiter fortgeführt. Wenn die Hierarchie zu Ende ist, also keine weitere übergeordnete Abteilung mehr gefunden wird, ist die Abschlussbedingung erfüllt. Dann werden die gesammelten Information ausgegeben und die Rekursion wird beendet.

Nachteil

Das erste große Problem bei einer Rekursion ist die Rekursion selbst. Wurde eine falsche Abschlussbedingung verwendet, um die Rekursion zu beenden, wird diese so lange weiter laufen, bis der Speicher voll ist und der Job abbricht. Sind die Datenmengen zu groß, kann trotz großer Speicherverfügbarkeit der Job abbrechen, da alle Daten im Speicher gehalten werden. Trotz sorgfältigster Prüfung muss klar sein, dass eine Rekursion immer Gefahren birgt. So viel sie die mögliche Performance verbessern kann, kann diese durch einen kleinen Fehler auch sehr schnell viel kaputt machen, da in der Rekursion schnell viele Daten zusammen kommen können.

Vorteil

Es besteht eine Zeitersparnis beim Erstellen eines Jobs, da dieser Subjob wiederverwendet und nicht die komplette Aufgabe designed werden muss. Alle Daten, die verarbeitet werden, liegen im Speicher und sind somit performant abrufbar. In dem Beispiel wandern wir dynamisch in einer Hierarchie nach oben, wobei wir nicht wissen wie viele Elemente noch kommen. Das gleiche Ergebnis sequenziell abzuarbeiten bzw. einen Job zu erstellen, der dies tut, wird sehr viel länger dauern. Und ist auch nur für diesen einen Fall nutzbar.

Fazit

Mit rekursiven Hashmaps haben wir eine Möglichkeit, performant dynamische Strukturen unbekannter Größenordnungen zu durchlaufen. Die Modellierung als Talend-Job ermöglicht dies ohne spezialisierten Quellcode für diese Aufgabe schreiben zu müssen. Auch wenn Vorsicht bei der Definition der Abschlussbedingung geboten ist, vereinfachen rekursive Hashmaps diese Aufgabenstellung deutlich.