d.h. der usage context entscheidet, ob wir einen Wert,

eine Referenz oder einen konstanten Wert verwenden

Record selber ist immuable

aber hat eine Builder-Mechanik

eigentlich fehlte nur die get()-Operation

erledigt... ähm vertagt

aber nicht wirklich; der workaround könnte schon die Lösung sein #963

ich hatte damals beim Variant und zugehörigen Buffer die Sorge,

daß ich die Implikationen einer generischen Lösung nicht durchdringen kann.

Und ich wollte keine Zeit auf einen exzessiven Unit-Test verwenden

generische Lösung verschoben #963

C++11 erlaubt =default

nicht klar, ob wir das überhaupt brauchen

  • entweder nur die unmittelbaren Kinder -> komplexe Logik fällt auf den Client
  • oder nur die Blätter -> man kann die Baum-Struktur nicht wirklich nutzen

Entscheidung

was wir brauchen

geht nicht:

rekursiver Abstieg in der Mitte eines Iterators

das war die Quintessenz der ganzen Entwicklung zum IterExplorer

Nachdem ich die depth-first / breadth-first -Strategien systematisch aufgebaut hatte,

habe ich das dann reduziert und kompakt nochmal geschrieben.

Sehr schön!

übrigens: genau den verwenden wir auch zur Job-Planung

...denn wir müssen den Weg zurück finden.

Wenn also eine Datenstruktur nur einfach verzeigert ist, oder direkt rekursiv (wie bei uns),

dann ist es absolut unmöglich, eine Traversierung mit konstantem Speicher zu machen.

Das geht nur bei einer Struktur mit Rückreferenzen -- diese enthalten dann nämlich genau den Speicher,

der während dem Einstieg in die einfach verzeigerte Struktur auf dem Stack liegt. Aber letztere

braucht nur eine logarithmische Menge an Speicher, und das auch nur während der Traversierung.

Dies ist die Abwägung, und darunter läßt sich nichts weghandeln.

Der einzige verbleibende Freiheitsgrad ist, bei einer unmittelbaren rekursiven Programmierung

direkt den Prozessor-Stack für die Speicherung des Rückweges mitzuverwenden;

in dem Moment, wo ich mich für einen Iterator entscheide, ist diese Möglichkeit weg.

kann genauso effizient werden

aber nur, wenn man die Initialisierung hinbekommt

oder diese Logik

fest verdrahten

da es sich um einen disjunktiven Typ (entweder-oder-Typ) handelt,

könnte man die Storage mit beiden Bedeutungen überlagern.

Voraussetzung wäre, daß man anhand der konkreten Daten gefahrlos  jeweils herausfinden kann,

welcher Zweig grade gilt. Da wir aber keine Introspektion haben (und auch nicht wollen!),

würde das auf Taschenspielertricks mit der Implementierung hinauslaufen

  • GenNode und Record beginnen beide fraktisch mit einem String. Man müßte diesen interpretieren können
  • oder man nutzt die letzten Bits des Pointers, um sich dort eine Flag zu speichern...

Damit ist schon klar: sowas macht man nicht ohne Grund

Entscheidung: falls eingebetteter Record

Begründung: das Durchlaufen und Rekonstruieren eines Baumes

ist letztlich doch ein sehr spezieller Fall, und rechtfertigt nicht,

den HierarchyOrientationIndicator in jeden Iterator einzubetten.

Zumal -- wenn der level zugänglich ist -- kann man diese Mechanik genauso gut

dort direkt ansiedeln, wo sie gebraucht wird.

also keine Monade

Gleichheit

kombiniert den Wert-Match mit der Iteration

Zweck: kompaktes Anschreiben

von literalen Daten

Object builder

Problem ist, wir definieren den Typ Record generisch,

verwenden dann aber nur die Spezialisierung Record<GenNode>

Und die Builder-Funktionen brauchen eigentlich spezielles Wissen über den zu konstruierenden Zieltyp

Mutator selber is noncopyable

Ergebnis move

pro / contra

Move ist gefährlich

aber auch deutlich effizienter,

denn wir müssen sonst das ganze erzeugte Ergebnis einmal kopieren.

Nicht sicher, ob der Optimiser das hinbekommt

nur auf dem Mutator

dieser ist nicht kopierbar

und muß dediziert erstellt werden

möglicherweise schon gelöst,

denn Record ist insgesamt immutable.

Also können wir einen Find mit einem const_iterator machen

was sinnvoll ist,

hängt vom Payload-Typ ab

bei einer 'key = value' -Syntax mit strings

ist nur ein Value-Rückgabewert sinnvoll

...auch kann man auf diesem Weg die Storage konfigurierbar machten

da wir einen IterAdapter verwenden, können wir nur eine 'pos' (einen Quell-Iterator)

als Zustands-Markierung verwenden; die gleiche 'pos' wird aber auch inkrementiert und dereferenziert.

Daher ist die einzige praktikable Lösung, daß die Typ-ID in einem weiteren Vektor gespeichert wird.

Das könnte dann ein Metadaten-Vektor sein.

Natürlich ist dieser Ansatz nur sinnvoll, wenn wir wirklich Metadaten brauchen.

Denn jeder Record zahlt den Preis für die komplexere (zusätzliche) Datenstruktur!

scheidet aus, wegen Wertsemantik

mit speziellem Ref-Typ

-- im DataCap

heißt: in der Diff-Verarbeitung wird dieser spezielle check verwendet

m.E. die einzig saubere Desgin-Variante!

gemeint ist:

  • man kann alternativ auch eine RecordRef direkt in eine elementare GenNode packen
  • diese verhält sich dann nicht transparent, denn sie hat eine andere Identität als ihr Ziel
  • das kann aber als spezielles Ausdrucksmittel genutzt werden

heißt: wird direkt von standard-equality so behandelt

brauche speziellen Builder,

der das so fabriziert

bekomme einen

"ungenutzten" DataCap

Idee: Ref-GenNode

als Ref erkennbar

(Prädikat)

hash-identische

Ziel-ID ableitbar

Verarbeiten

von Teilbäumen

Interpreter definiert Sprache

ROOT

INIT

leeres

Objekt

pick(Ref::CHILD)

würde sagen: ja, aber auch nur für das after-Verb!

allgemein halte ich einen wrap-around für keine gute Idee,

weil er zu Zweideutigekeigen führt und daher Struktur oder Konsistenzfehler überspielt

läßt sich stets duch eine inverse Folge von find und pick  emulieren

vorerst verworfen, da zusätzlicher Prüf-Aufwand

...Grund: sie werden durch einen jeweils komplett anderen Ansatz implementiert

  • "Liste" beruht auf dem Attribut-Iterator und dem Aufbauen einer neuen Attribut-Sammlung
  • "Map" beruht darauf, alle Operationen an die Storage zu delegieren

das heißt, man kann Attribute in einer "sinnvoll lesbaren" Ordnung anschreiben

und später angefügte Attribute bleiben so erkennbar.

Vorteilhaft für Version-Management

profitiert also von allen Verbesserungen des allgemeinen Algorithmus

"hoch effizient", unter der Annahme, daß fast immer nur konforme Änderungen kommen.

Weil dann nämlich die in unserer Implementierung ggfs. kostspieligen Umordnungen entfallen,

kommen wir auf lineare Komplexität für die Verarbeitung

+ NlogN f ür den Index zur Diff-Erzeugung

unsere Impl der Diff-Erzeugung (!)

baut einen Index auf (N*logN), um Einfügungen/Entfernungen zu erkennen und Umordnungs-Suche zu unterstützen.

Wenn wir aber von ausschließlich konformen Operationen ausgehen,

wird dieser Index nicht benötigt. Leider können wir das aber nicht garantieren, denn

es könnte ja zwischenzeitlich ein Attribut gelöscht und dann später (am Ende) wieder

angehängt worden sein, was dann eben doch einen Index erfordert, um einen

korrekten Listen-Diff zu erzeugen

d.h. wenn die Storage hoch-optimiert ist,

dann überträgt sich das auf die Diff-Behandlung

da wir Attribute in einer Liste speichern,

müssen wir für jede Einfügung eine vollständige Suche machen

...gemeint ist: extra, anders als die normale Listenverarbeitung.

Auch wenn diese andere Implementierung nur delegiert

danach noch auftretende Attribute

erfordern Sonder-Behandlung,

indem sie an die Attributs-Liste angehängt werden

wegen Entscheidung für das "Listen"-Modell zur Attribut-Handhabung

...da das Kind in der Liste der Attribute nämlich garnicht gefunden wird

...wenn wir am Ende der Attribut-Zone stehen,

und die nächste Operation ein fetch eines Kindes ist, müssen wir implizit den

Wechsel in den Scope vollziehen und die Operation dort ausführen.

Aber an allen anderen Stellen in der Attribut-Zone ist ein solcher Fetch ein Fehler!

standardmäßig strikt

List-Diff

als Spezialfall

kann auch nicht

wegen dem Interpreter

leicht auf generischen Container

zu verallgemeinern

Erkennung hat die Sprache als Parameter,

und verwendet sie zur Token-Generierung

man kann auch dem List-Detector

eine Tree-Diff-Language geben

Frage: in-Place?

entscheidende Frage: wie addressieren?

und wird durch die Diff-Anwendung konsumiert

Immutablility erzwingt

  • persistente Datenstrukturen
  • garbage-collector

Lösung: wir arbeiten auf einem Mutator

auf dem Umweg über einen ContentMutator

Innereien des alten Record verbrauchen

Problem: Rekursion

wenn ein MUT kommt

erzeugt man lokal einen DiffApplikator für den geschachtelten Kontext

und gibt ihm rekursiv den Diff hinein. Wenn dieser Aufruf zurückkehrt

ist der gesammte Diff für den eingeschachtelten Kontext konsumiert

wenn ein MUT kommt,

pusht der Applikator seinen privaten Zustand

auf einen explizit im Heap verwalteten std::stack

und legt einen neuen Mutator an für den nested scope

Entscheidung:

interner Stack

....begründet duch die generische Architektur.

Die Trennung von Diff-Iteration und dem Interpreter ermöglicht verschiedene Sprach-Ebenen.

Allerdings werde ich für die Anwendung auf konkrete Datenstrukturen,

also den TreeMutator, vermutlich das andere Modell (rekursiv konsumieren) verwenden.

Problem sind mal wieder die automatisch generierten IDs.

Die sind natürlich anders, wenn wir die ganze Testsuite ausführen...

saugeil

...im Besonderen die guten Diagramme für Pulse, ALSA und Jack

bekannter Bug binutils #16936

Lumiera-Ticket #965

gelöst in 4e8e63ebe

...man "hilft" dem Linker mit

"-Wl,-rpath-link=target/modules"

laufen wieder alle

test.sh Zeile 138

Debian-Bug #724461

nebenbei ohweh:

ulimit -t 1 ist wirkungslos

Christian:  bash -c "ulimit -t 1; while :; do :; done"

und wir verbringen unsere Zeit mit contention

ist klar, hab ich gebrochen

siehe Ticket #587

Kollisionen jetzt bereits nach 4000 lfd. Nummern

Vorher hatte ich erste Kollisionen nach 25000 Nummern

erinnere mich an den

guten alten "Knuth-Trick"

wow: es genügt,

die letzten beiden Zeichen mit der Knuth-Konstante zu spreizen,

und ich komme locker auf 100000 Nummern ohne Kollision

Aug 10 04:51:39 flaucher kernel: gdb[8234]: segfault at 7ffe3fa79f50 ip 0000000000718b95 sp 00007ffe3fa79f40 error 6 in gdb[400000+574000]

Aug 10 04:51:39 flaucher kernel: traps: test-suite[8249] trap int3 ip:7ffff7deb241 sp:7fffffffe5c8 error:0

function gebunden an ein lambda

wobei ein Argument-Typ als vom Template-Argument

der umschließenden Funktion aufgegriffen wird

Bugreport für Debian/Jessie #795445

Git: debBild/Gdb_DEB.git

bison dejagnu flex gobjc libncurses5-dev libreadline-dev liblzma-dev libbabeltrace-dev libbabeltrace-ctf-dev python3-dev

dutzende Tests scheitern

verräterrischer Code im debian/rules

check-stamp:

ifeq ($(run_tests),yes)

        $(MAKE) $(NJOBS) -C $(DEB_BUILDDIR)/gdb check \

          || echo "**Tests failed, of course.**"

endif

        touch $@

au weia LEUTE!

speziell: unused-function bei dem Trick mit dem std::hash macht mir Sorgen.

und tatsächlich: das ist daneben, GCC hat Recht!

aktualisieren und neu bauen

Doku durchkämmen nach Müll

hier nach offensichtlich obsoleter Info checken

WICHTIG: keine vorgreifende Infor publizieren!!!!!

die explizit angegebenen Paketnamen schon mal vorchecken

die Abschnitte zu den LIbraries prüfen / umschreiben

insgesamt sorgfältig durchlesen

knappe Kennzeichnung des Releases in den Kommentar

hier geht es darum, Konsistenz im Git herzustellen.

Wenn alles korrekt gemacht wurde, dürfte es hier keinen Rückfluß von Änderungen geben.

Bitte auch daran denken, zuerst den DEB-Zweig zu prüfen. Diesen aber nicht zurückmergen,

denn wir wollen keine DEB-Info im Master haben!

einzeilige Kennzeichnung wiederholen

die unmittelbaren Release-Dokumente durchgehen

Merge-commit auf den Release-Zweig.

Sollte konfliktfrei sein

...das heißt bauen und hochladen

totmachen: Debian/Wheezy (stable) : i386 and x86_64 deprecated: to be discontinued

Referenz: Debian/Jessie (stable) : i386 and x86_64 (currently broken)

Wichtig: hier nur was wirklich gebaut ist und funktioniert!

eigentlich war die nur notwendig für das Video-Viewer Widget,

was nun leider tot ist. Wir haben noch keinen Ersatz. Deshalb lasse ich die Abhängigkeit

bestehen, aber irgendwann müssen wir das schon glattziehen