"Reference Counted Container Elements" !?



  • Hallo,

    ich brauche einen Container dessen Elemente reference counted sind
    und sich selbst aus dem Container löschen,wenn sie nicht mehr benötigt werden d.h. reference count = 0 ist,also ein Container mit

    "Reference Counted Container Elements" (ich nenns einfach mal so 🙂 )

    Ich möchte ungern das Rad neu erfinden.
    Dehalb meine Frage: Gibt es sowas schon,und wenn ja wo?

    Vielen Dank
    Basti



  • Nein, gibt es nicht. Aber das kann auch nicht sinnvoll sein. Erklär mal etwas mehr was du vor hast.



  • So wirklich komplex ist das dann auch nicht, wenn du es dir selbst bauen willst.
    a) weak_ptr im container speichern; wenn du sie verwenden willst, kannst du ungültige ptr einfach entfernen
    b) im Destruktor der Objekte einen normalen built-in ptr aus dem container entfernen



  • @cooky451
    Ich will eine Mesh-Klasse schreiben.
    Ich hab z.B ein Eckpunkt,der in einem Container gespeichert ist und von mehreren Dreiecken verwendet wird. Wenn jetzt ein Eckpunkt nicht mehr gebraucht wird,weil es kein Dreieck mehr gibt,das ihn verwendet,dann soll er sich "vollautomatisch" aus dem Container löschen.



  • Grundsätzlich: Warum steckt er dann überhaupt in einem Container? Das macht doch keinen Sinn. Hast du das System von shared_ptr verstanden?

    Aber: Was ein Quatsch. Jedes Dreieck in einen shared_ptr stecken und refcounten lassen? Ich kann mir nicht mal vorstellen wie langsam das ist. Eventuell lohnt das bei ganzen Models, aber doch nicht bei Punkten oder Dreiecken. Wie kommt man denn auf die Idee?



  • @cooky451
    Natürlich macht es Sinn die Vertices in einem Container zu halten, nämlich in einem std::vector.
    Die Dreieckslisten enthalten dann bloss noch Indexe. Das ist speicherschonend und cachefreundlich.
    Der OP hat auch nicht vorgeschlagen einen shared_ptr zu verwenden, das kam ja von anderen. Er will nur dass die nicht mehr gebrauchten Vertices automatisch aus dem Container gelöscht werden.

    @__Bastian__

    Bastian schrieb:

    Wenn jetzt ein Eckpunkt nicht mehr gebraucht wird,weil es kein Dreieck mehr gibt,das ihn verwendet,dann soll er sich "vollautomatisch" aus dem Container löschen.

    Ich würde auf das "vollautomatisch" verzichten, und ein "halbautomatisch" draus machen.

    Du steckst die Vertices in einen std::vector<Vertex>.
    In einen std::vector<int> steckst du dann die Index-Liste.

    Wenn du jetzt Dreiecke rausnimmst oder änderst, tust du erstmal gar nix.
    Und dann bastelst du eine "Aufräumfunktion" die ala GC guckt welche Indexe nicht mehr verwendet werden, und diese dann z.B. in eine Freelist (der nächste std::vector<int>) einträgt.

    Wenn ein neuer Vertex benötigt wird guckst du erstmal in der Freelist nach, und wenn da was drinnen ist tust du den Index wiederverwenden.
    Wenn nicht hängst du einfach nen neuen Vertex an.

    Weiters machst du noch eine Funktion die die Vertex-Liste "kompaktiert", also "Löcher" ans Ende verschiebt, und die Vertex-Liste danach "abschneidet". (D.h. die Vertex-Liste enthält danach nur noch verwendete Vertices und die Freelist ist leer.)

    Dann bringst du der Aufräumfunktion noch bei, dass sie nach dem Aufräumen nachguckt wie viele Einträge in der Freelist es gibt, und wenn ein bestimmter Schwellwert überschritten ist die Kompaktierfunktion aufruft.

    Der User der Klasse bzw. Klassen die das ganze kapseln braucht dann bloss noch hin und wieder die Aufräumfunktion aufzurufen, bzw. vor bestimmten Aktionen wie Speichern in ein File die Kompaktierfunktion. Der Rest läuft automatisch.

    Damit solltest du gute Performance bekommen. Zusätzlich kannst du dem User ziemlich direkten Zugriff auf die Index-Liste geben. D.h. er kann Einträge dort mehr oder weniger "direkt" machen, und muss nicht jedes mal über diverse AddTriangle/GetTriangleIndexes/UpdateTriangleIndexes Funktionen zugreifen.



  • p.s.

    Bastian schrieb:

    ich brauche einen Container dessen Elemente reference counted sind (...)

    Meist macht es mehr Sinn zu beschreiben was man erreichen will, nicht womit man etwas erreichen will.



  • Alternativ kannst du den vertices nen identifier geben, dann shared pointer auf ein verwaltungsobjekt das, falls das zerstört wird, das Objekt aus dem vector über die ID löscht (swap mit letztem und letztes entfernen). Das Verwaltungsobjekt sollte meiner Meinung nach das Objekt dann auch anlegen.

    Find das prinzipiell intuitiver als hustbears Lösung, von der performance her... *shrug* musst halt schaun.



  • Ich halte aber auch den Weg für besser, das ganze Mesh-basierend zu machen. Die meisten Meshes sollten groß genug sein, dass man keinen Performanceunterschied zwischen "alle meshes in einem vektor" und "alle meshes in jeweils separaten vektoren" messen kann. Natürlich kann es noch alltägliche Formen geben, die man immer mal wieder braucht und die echt klein sind, aber bei denen wiederum glaube ich, dass man die nicht vor Programmende aufräumen muss - eben weil man sie regelmäßig braucht. Die kann man dann also auch zusammen packen.

    Also: 1 Punktliste kommt in 1 std::vector. Wenn kein Indexset mehr auf den Container verweist, wird der Container aufgeräumt.



  • Vielen Dank soweit 👍
    Ich werde es wohl so machen,wie es hustbaer vorgeschlagen hat.
    Finde es trotzdem sehr schade,dass sich das "vollautomatische" Löschen nicht ganz so leicht realisieren lässt,ich hätte das eleganter gefunden.



  • Bastian schrieb:

    Finde es trotzdem sehr schade,dass sich das "vollautomatische" Löschen nicht ganz so leicht realisieren lässt,ich hätte das eleganter gefunden.

    Das ist kein Problem, nur macht es keinen Sinn, einzelne Dreiecke in einen shared_ptr zu stecken. shared_ptr<vector<Vertex>> etc. ist natürlich kein Problem. Das was hustbaer vorgeschlagen hat, ist schon eine recht spezielle Lösung. Kann sein, dass das ganze noch ordentlich besser performt, verlassen würde ich mich nicht drauf. Solange du das Ganze aber irgendwie ordentlich kapselst, sollte das kein Problem sein. Dann nimmst du halt erst mal eine ganz einfach Implementierung und wenn das tatsächlich zu langsam sein sollte, guckst du dir mal erweiterte Sachen an.


Anmelden zum Antworten