2012-11-14 7 views
5

Questo può sembrare strano, ma proverò a razionalizzarlo. Attualmente utilizzo boost.object_pool in modo congiunto con shared_ptr, e recentemente ho riscontrato una situazione che ho bisogno di scattare istantanee degli stati del programma corrente, al fine di rendere funzionanti come la riproduzione in scala reale replay/rollback/fast forward.Qualsiasi implementazione di pool di oggetti clonabili in C o C++?

Quindi non sto cercando di clonare un pool di oggetti da usare altrove, che non funzionerà ovviamente perché anche se sono autorizzato a farlo dall'interfaccia di boost.pool (che non sono), non ci sarà alcun valido puntatori che puntavano a pezzi in quella piscina appena clonata e sarebbe semplicemente inutile. Ma il mio caso d'uso qui è che voglio "incolla" nel pool originale se c'è bisogno di replay/rollback.

Posso certamente copiare e clonare tutti gli stati, gli oggetti e i sotto-stati, sotto-oggetti e sotto-sotto ... manualmente e quindi comprimerli in un'istantanea, e sperare che tutto vada bene, ma che è errore- soggetto alla complessità del progetto, e deve essere molto più lento di quanto non sia possibile copiare direttamente la memoria. L'uso di Command pattern (o simili) per ottenere l'annullamento della redire è alquanto fuori discussione perché il meccanismo di annullamento del ripristino non è la mia intenzione.

Mi stavo chiedendo se faccio di nuovo il progetto da zero usando un modo tradizionale C inattaccabile, e una chiamata semplice memcpy (istantanea, all_state, dimensioni) farebbe quasi tutto il lavoro.

C'è qualche altra opzione che mi manca ancora? C'è qualche boost.object_pool come l'implementazione che ti permette di clonare l'area di memoria sottostante? È intrusivamente hacking boost.object_pool un'opzione plausibile considerando la situazione?

+0

Scrivere il proprio pool di oggetti, copiabile, con un'interfaccia simile non sembra difficile o richiede molto tempo. – Pubby

+0

@Pubby: le strutture di tipo grafico non sono mai facili da clonare. Gli errori più comuni si bloccano in un ciclo infinito e rompere involontariamente il grafico. È dannoso anche il debug. –

risposta

2

Non che io sappia.

Come notato, il problema principale qui è la presenza di possibili interdipendenze tra gli oggetti che richiedono l'aggiornamento dei puntatori mentre si effettua la copia. Sicuramente non banale.

Mi vengono in mente due possibili soluzioni:

  • Persistenza
  • serializzazione

Persistenza è mai la mutazione stato esistente. Quando si modifica lo stato, si crea quindi una nuova istantanea che fa riferimento allo stato precedente ad eccezione dei nuovi bit. È tipicamente utilizzato nelle implementazioni MVCC di database, ad esempio, ed è pervasivo nel mondo della programmazione funzionale. È anche un buon modo per ottenere perdite di spazio se si tenta di mantenere troppi riferimenti. Infine, richiede una profonda reingegnerizzazione.

Serializzazione riguarda lo stato di persistenza, ma in un formato diverso. Si scarica lo stato corrente nel formato di serializzazione (sia testuale o binario), e si è in grado di ricrearlo leggendo il buffer serializzato. È anche possibile applicare un passaggio di compressione sul buffer serializzato per risparmiare memoria.

Dato che si sta già utilizzando Boost, sii contento di sapere che Boost.Serialization gestisce automaticamente i grafici degli oggetti (eh!) E penso che si tratti già correttamente con boost::shared_ptr. Potrebbe essere la tua migliore opzione qui.