From 9323c1405d658837f4070f4550cccaffcf3ace9d Mon Sep 17 00:00:00 2001 From: David Hampton Date: Sat, 6 May 2006 06:01:14 +0000 Subject: [PATCH] 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. git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@13926 57a11ea4-9604-0410-9ed3-97b8803252fd --- ChangeLog | 13 +++++++++++++ lib/libqof/qof/qofbook.c | 12 ++++++++++-- lib/libqof/qof/qofbook.h | 1 + lib/libqof/qof/qofid-p.h | 1 + lib/libqof/qof/qofid.c | 32 +++++++++++++++++++++++++++++--- lib/libqof/qof/qofid.h | 17 +++++++++++++++++ lib/libqof/qof/qofinstance.c | 18 ++++++++++++++++-- lib/libqof/qof/qofinstance.h | 2 ++ lib/libqof/qof/qofutil.c | 4 ++++ 9 files changed, 93 insertions(+), 7 deletions(-) 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;