[solved] Problem mit QSortFilterProxy/Optimierung



  • Ich habe Datensätze die (vereinfacht) so aussehen (+ == "mehr unterelemente", - == "ausgklappt"):

    - Datenbank1
      - Exp1
        - Ina
          - Trial01
            - Mod1
            - Mod usw
          - Trial02
            - Mod usw
          - Trial usw
        + Subjects usw
      + Exp usw
    + Datenbank usw
    

    Ich fülle ein eigenes QAbstractItemModel mit den Daten aus einer DB, es sind 5 Datenbank-Nodes mit je 10-30 Experiment-Nodes mit je 10-40 Subjekt-Nodes mit je 1-20 Trial-Nodes mit je 2-6 Modalitäten [total ~225k nodes]

    Ich möchte dem User eine Filterung anbieten, habe dazu das QSortFilterProxyModel gewählt. Mein Problem: Der User soll zB "Ina" eingeben und nun alles angezeigt bekommen was "auf dem Weg zu" Ina liegt und (ungefiltert) alles was unterhalb von "Ina" liegt (wahlweise Volltextsuche/QRegExp). Im obigen Beispiel (wenn sonst nirgends Ina vorkommt) also:

    - Datenbank1
      - Exp1
        - Ina
          - Trial01
            - Mod1
            - Mod usw
          - Trial02
            - Mod usw
          - Trial usw
    

    Mein Ansatz erreicht das, allerdings nur dadurch das jedes Element bei nicht zutreffen des Suchkriteriums solange (Kindes-)Kinder testet bis alle nicht erfüllt sind oder eines erfüllt ist. Erfüllt ein Item die Suchkriterien werden dessen QModelIndex sowie die QModelIndex'e aller Elter-Items sowie aller Kinder und Kindeskinder-Items in ein QSet gesteckt.

    filterAcceptsRow() testet ob der derzeitige QModelIndex schon im QSet ist, wenn ja wird die das Item gezeigt, ansonsten wie oben beschrieben verfahren. Mein Problem dabei: ich halte im Worstcase (QRegExp(".*")) jeden vorhandenen QModelIndexes im QSet vorrätig ... die ich ja eigentlich nur in der Filterphase des QSortFilterProxyModels brauche ...

    Derzeit freezed es teilweise ...
    Geht das nicht besser?

    Crosspost mit Code: http://www.qtforum.de/forum/viewtopic.php?t=12403



  • Statt bei einem (dem Suchausdruck genügenden) QModelIndex alle parents bis zur Wurzel und alle (Kindes-)Kinder ins QSet<QModelIndex> validOnes zu packen, merke ich mir nur den entsprechenden Index.

    In filterAcceptsRow() lasse ich 2 Methoden auf den aktuellen Index los:_

    1. eine prüft ob der aktuelle index ein Child eines bereits validen Indexes ist, dann wird dieser Index auch akzeptiert
    2. die andere prüft ob dieser Index ein parent eines der bereits als valide geprüften Indizes is, dann ist er auch valide

    bei 2) war ich mir unsicher ob das überhaupt nötig ist ... falls QSortFilterProxyModel beim Filtern top-down geht, ist das überflüssig. Habe darum mal ein paar qDebugs hinzugefügt und das scheint tatsächlich der Fall zu sein. Hab mal alles rauskommentiert was zu 2) gehört und es tut immer noch ... und ist deutlich schneller. Der Worstcase-Speicher des QSets ist auch deutlich besser (oder sagen wir mal die QRegExps die mir einfallen und zum WorstCase führen sollen sind nicht mehr so einfach (.*) liefert die Anzahl der root-nodes und (^\d+$) die Anzahl der modal-nodes (wenn modal nodes die einzigen sind die aus reinen Zahlen bestehen) und beides ist kleiner als 44100.

    Geht da noch was?

    Crosspost mit neuem Code: http://www.qtforum.de/forum/viewtopic.php?p=62318#62318


Anmelden zum Antworten