diff --git a/ChangeLog b/ChangeLog index 0daa5abbbc..b8029f4cd1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2006-05-06 David Hampton + + * lib/libqof/qof/qofbook.[ch]: + * lib/libqof/qof/qofid-p.h: + * lib/libqof/qof/qofinstance.[ch]: + * lib/libqof/qof/qofid.[ch]: + * lib/libqof/qof/qofutil.c: Add an alternate mode for handling the + dirty state of instances and collections. In this mode, marking + an instance as dirty does not immediately mark the collection as + dirty. The collection is only dirtied when a dirty instance is + actually committed to the collection. Also add some debugging + functions. + 2006-05-05 David Hampton * configure.in: Bump the version number for setting the diff --git a/lib/libqof/qof/qofbook.c b/lib/libqof/qof/qofbook.c index 52e0b23bc1..10a7698aea 100644 --- a/lib/libqof/qof/qofbook.c +++ b/lib/libqof/qof/qofbook.c @@ -145,7 +145,7 @@ qof_book_equal (QofBook *book_1, QofBook *book_2) /* ====================================================================== */ gboolean -qof_book_not_saved(QofBook *book) +qof_book_not_saved (QofBook *book) { if (!book) return FALSE; @@ -153,7 +153,7 @@ qof_book_not_saved(QofBook *book) } void -qof_book_mark_saved(QofBook *book) +qof_book_mark_saved (QofBook *book) { if (!book) return; @@ -161,6 +161,14 @@ qof_book_mark_saved(QofBook *book) qof_object_mark_clean (book); } +void +qof_book_print_dirty (QofBook *book) +{ + if (book->inst.dirty) + printf("book is dirty.\n"); + qof_book_foreach_collection(book, qof_collection_print_dirty, NULL); +} + /* ====================================================================== */ /* getters */ diff --git a/lib/libqof/qof/qofbook.h b/lib/libqof/qof/qofbook.h index e96c5ab07e..37c46d15d2 100644 --- a/lib/libqof/qof/qofbook.h +++ b/lib/libqof/qof/qofbook.h @@ -154,6 +154,7 @@ gboolean qof_book_not_saved (QofBook *book); * by the frontend when the used has said to abandon any changes. */ void qof_book_mark_saved(QofBook *book); +void qof_book_print_dirty (QofBook *book); /** Call this function when you change the book kvp, to make sure the book * is marked 'dirty'. */ diff --git a/lib/libqof/qof/qofid-p.h b/lib/libqof/qof/qofid-p.h index e73ab4c422..bb34aca63a 100644 --- a/lib/libqof/qof/qofid-p.h +++ b/lib/libqof/qof/qofid-p.h @@ -49,6 +49,7 @@ void qof_collection_insert_entity (QofCollection *, QofEntity *); /** reset value of dirty flag */ void qof_collection_mark_clean (QofCollection *); void qof_collection_mark_dirty (QofCollection *); +void qof_collection_print_dirty (QofCollection *col, gpointer dummy); /* @} */ /* @} */ diff --git a/lib/libqof/qof/qofid.c b/lib/libqof/qof/qofid.c index ffe2d22977..39a39881ce 100644 --- a/lib/libqof/qof/qofid.c +++ b/lib/libqof/qof/qofid.c @@ -31,6 +31,7 @@ #include "qofid-p.h" static QofLogModule log_module = QOF_MOD_ENGINE; +static gboolean qof_alt_dirty_mode = FALSE; struct QofCollection_s { @@ -43,6 +44,20 @@ struct QofCollection_s /* =============================================================== */ +gboolean +qof_get_alt_dirty_mode (void) +{ + return qof_alt_dirty_mode; +} + +void +qof_set_alt_dirty_mode (gboolean enabled) +{ + qof_alt_dirty_mode = enabled; +} + +/* =============================================================== */ + static void qof_collection_remove_entity (QofEntity *ent); void @@ -182,7 +197,8 @@ qof_collection_remove_entity (QofEntity *ent) col = ent->collection; if (!col) return; g_hash_table_remove (col->hash_of_entities, &ent->guid); - qof_collection_mark_dirty(col); + if (!qof_alt_dirty_mode) + qof_collection_mark_dirty(col); ent->collection = NULL; } @@ -194,7 +210,8 @@ qof_collection_insert_entity (QofCollection *col, QofEntity *ent) g_return_if_fail (col->e_type == ent->e_type); qof_collection_remove_entity (ent); g_hash_table_insert (col->hash_of_entities, &ent->guid, ent); - qof_collection_mark_dirty(col); + if (!qof_alt_dirty_mode) + qof_collection_mark_dirty(col); ent->collection = col; } @@ -210,7 +227,8 @@ qof_collection_add_entity (QofCollection *coll, QofEntity *ent) e = qof_collection_lookup_entity(coll, &ent->guid); if ( e != NULL ) { return FALSE; } g_hash_table_insert (coll->hash_of_entities, &ent->guid, ent); - qof_collection_mark_dirty(coll); + if (!qof_alt_dirty_mode) + qof_collection_mark_dirty(coll); return TRUE; } @@ -342,6 +360,14 @@ qof_collection_mark_dirty (QofCollection *col) if (col) { col->is_dirty = TRUE; } } +void +qof_collection_print_dirty (QofCollection *col, gpointer dummy) +{ + if (col->is_dirty) + printf("%s collection is dirty.\n", col->e_type); + qof_collection_foreach(col, qof_instance_print_dirty, NULL); +} + /* =============================================================== */ gpointer diff --git a/lib/libqof/qof/qofid.h b/lib/libqof/qof/qofid.h index 35edbe1b5d..1c619f8811 100644 --- a/lib/libqof/qof/qofid.h +++ b/lib/libqof/qof/qofid.h @@ -160,6 +160,23 @@ void qof_entity_init (QofEntity *, QofIdType, QofCollection *); void qof_entity_release (QofEntity *); /** @} */ +/** Is QOF operating in "alternate" dirty mode. In normal mode, + * whenever an instance is dirtied, the collection (and therefore the + * book) is immediately marked as dirty. In alternate mode, the + * collection is only marked dirty when a dirty instance is + * committed. If a dirty instance is freed instead of committed, the + * dirty state of collection (and therefore the book) is never + * changed. */ +gboolean qof_get_alt_dirty_mode (void); + +/** Set QOF into "alternate" dirty mode. In normal mode, whenever an + * instance is dirtied, the collection (and therefore the book) is + * immediately marked as dirty. In alternate mode, the collection is + * only marked dirty when a dirty instance is committed. If a dirty + * instance is freed instead of committed, the dirty state of + * collection (and therefore the book) is never changed. */ +void qof_set_alt_dirty_mode (gboolean enabled); + /** Return the GUID of this entity */ const GUID * qof_entity_get_guid (QofEntity *); diff --git a/lib/libqof/qof/qofinstance.c b/lib/libqof/qof/qofinstance.c index 137d1760a8..1314a0540e 100644 --- a/lib/libqof/qof/qofinstance.c +++ b/lib/libqof/qof/qofinstance.c @@ -121,12 +121,24 @@ qof_instance_version_cmp (QofInstance *left, QofInstance *right) return 0; } +void +qof_instance_print_dirty (QofEntity *entity, gpointer dummy) +{ + QofInstance *inst = QOF_INSTANCE(entity); + + if (inst->dirty) + printf("%s instance %s is dirty.\n", inst->entity.e_type, + guid_to_string(&inst->entity.guid)); +} + gboolean qof_instance_is_dirty (QofInstance *inst) { QofCollection *coll; if (!inst) { return FALSE; } + if (qof_get_alt_dirty_mode()) + return inst->dirty; coll = inst->entity.collection; if(qof_collection_is_dirty(coll)) { return inst->dirty; } inst->dirty = FALSE; @@ -139,8 +151,10 @@ qof_instance_set_dirty(QofInstance* inst) QofCollection *coll; inst->dirty = TRUE; - coll = inst->entity.collection; - qof_collection_mark_dirty(coll); + if (!qof_get_alt_dirty_mode()) { + coll = inst->entity.collection; + qof_collection_mark_dirty(coll); + } } gboolean diff --git a/lib/libqof/qof/qofinstance.h b/lib/libqof/qof/qofinstance.h index a6c93b4cc5..8763ab0395 100644 --- a/lib/libqof/qof/qofinstance.h +++ b/lib/libqof/qof/qofinstance.h @@ -81,6 +81,8 @@ Timespec qof_instance_get_last_update (QofInstance *inst); */ int qof_instance_version_cmp (QofInstance *left, QofInstance *right); +void qof_instance_print_dirty (QofEntity *entity, gpointer dummy); + /** Return value of is_dirty flag */ gboolean qof_instance_is_dirty (QofInstance *); diff --git a/lib/libqof/qof/qofutil.c b/lib/libqof/qof/qofutil.c index d01def04c3..818120773a 100644 --- a/lib/libqof/qof/qofutil.c +++ b/lib/libqof/qof/qofutil.c @@ -269,6 +269,7 @@ qof_commit_edit_part2(QofInstance *inst, void (*on_free)(QofInstance *)) { QofBackend * be; + gboolean dirty = inst->dirty; /* See if there's a backend. If there is, invoke it. */ be = qof_book_get_backend(inst->book); @@ -300,6 +301,9 @@ qof_commit_edit_part2(QofInstance *inst, on_free(inst); return TRUE; } + + if (dirty && qof_get_alt_dirty_mode()) + qof_collection_mark_dirty(inst->entity.collection); if (on_done) on_done(inst); return TRUE;