2012-11-14 5 views
5

Das mag seltsam erscheinen, aber ich werde versuchen, es zu rationalisieren. Ich verwende derzeit boost.object_pool ausgiebig in Verbindung mit shared_ptr, und vor kurzem habe ich eine Situation, die ich Snapshots von aktuellen Programm-Staaten, um Funktionalität wie Full-Scale-Replay/Rollback/Vorlauf machen müssen getroffen.Jede klonbare Objektpoolimplementierung in C oder C++?

Also ich versuche nicht, einen Objektpool zu klonen, um woanders zu verwenden, das wird offensichtlich nicht funktionieren, denn selbst wenn ich dies durch die Schnittstelle von boost.pool tun darf (was ich nicht bin), wird es keine gültige geben Zeiger zeigen auf Stücke in diesem neu geklonten Pool und es wäre einfach sinnlos. Aber mein Anwendungsfall hier ist, ich möchte "einfügen" es zurück in den ursprünglichen Pool, wenn es Replay/Rollback benötigt.

Ich kann natürlich alle Zustände, Objekte und Unterzustände, Unterobjekte und Subsub ... einfach kopieren und klonen ... und dann packe sie in einen Schnappschuss und hoffe, dass alles richtig geht, aber das ist ein Fehler- anfällig angesichts der Komplexität, die das Projekt bereits hat, und es muss viel langsamer sein als wenn ich den Speicher direkt kopieren kann. Die Verwendung von Befehlsmustern (oder ähnlichem), um ein Rückgängig-Wiederholen zu erreichen, kommt ebenfalls nicht in Frage, da ein Rückgängigmachen-Wiederholen-Mechanismus nicht meine Absicht ist.

Ich habe mich nur gefragt, ob ich das Projekt von Grund auf neu mit einem eingefleischten traditionellen C-Weg, und eine einfache memcpy (Snapshot, all_states, Größe) Aufruf würde fast die ganze Arbeit tun.

Gibt es noch eine andere Option, die ich noch vermisse? Gibt es eine boost.object_pool ähnliche Implementierung, mit der Sie den zugrunde liegenden Speicherbereich klonen können? Intrusiv hackt boost.object_pool eine plausible Option in Anbetracht der Situation?

+0

Das Schreiben Ihres eigenen, kopierbaren Objektpools mit einer ähnlichen Schnittstelle scheint nicht sehr mühsam oder zeitraubend zu sein. – Pubby

+0

@Pubby: Graph-ähnliche Strukturen sind nie einfach zu klonen. Die häufigsten Fehler sind, dass sie in einem unendlichen Zyklus stecken bleiben und den Graphen unbeabsichtigt durchbrechen. Es ist höllisch zu debuggen. –

Antwort

2

Nicht, dass ich weiß.

Wie Sie bereits angemerkt haben, besteht das Hauptproblem hier in dem Vorhandensein möglicher Abhängigkeiten zwischen den Objekten, die beim Aktualisieren der Zeiger aktualisiert werden müssen. Sicherlich nicht-trivial.

Ich kann von zwei möglichen Lösungen denken:

  • Persistency
  • Serialisierung

Persistency über nie bestehenden Zustand mutiert ist. Wenn Sie den Status ändern, erstellen Sie daher einen neuen Snapshot, der sich auf den alten Zustand bezieht, mit Ausnahme der neuen Bits. Es wird typischerweise in MVCC-Implementierungen von Datenbanken verwendet und ist in der Welt der funktionalen Programmierung weit verbreitet. Es ist auch eine gute Möglichkeit, Speicherlecks zu erhalten, wenn Sie versuchen, zu viele Referenzen zu behalten. Schließlich erfordert es ein tiefgreifendes Reengineering.

Serialisierung ist über persistenten Zustand, aber in einem anderen Format. Sie geben den aktuellen Status im Serialisierungsformat (Text oder Binär) aus, und Sie können ihn durch Lesen des serialisierten Puffers neu erstellen. Sie können sogar einen Kompressionsdurchlauf auf den serialisierten Puffer anwenden, um Speicherplatz zu sparen.

Da Sie bereits Boost verwenden, dann freuen Sie sich darauf, dass Boost.Serialization automatisch Graphen von Objekten behandeln (eh!) Und ich denke, schon behandelt richtig mit boost::shared_ptr. Es könnte die beste Option sein.