Dirty entity identification.

Neil Williams linux at codehelp.co.uk
Fri Jul 22 04:10:13 EDT 2005

On Friday 22 July 2005 1:01 am, you wrote:
> You clearly haven't understood my statements.  I don't want to have to
> run the list of collections each time I ask if the book is dirty.
> That's too much work.

It's not. At no time do you iterate through the entire collections to do this. 
The code does iterate over the tiny number of primary collections but that 
takes no time at all. It takes longer to call the function itself than it 
does to check 12 or so boolean pointers, especially once that function is in 
a shared library.

> I want to short circuit that entire process by 
> checking *one* *flag* in the book.  Not the collections.  The book.  I
> would like the code that marks the collection as dirty to also mark the
> book as dirty.  None of the code I'm working on cares what has changed,
> only that something has.

The only problem with that is that the dirty flag in the book is not exposed 
directly (or won't be once I've cleaned up the private header file issue). 
You need to call a function via the API and that function will check the 
collections. It really is no overhead.

> Yes, thanks.  I've seen that code.  (Insert wry face here.)  Nowhere
> have you stated that setting the dirty flag on a collection will also
> set book->inst.dirty.  In fact, you've gone through some serious
> contortions to avoid saying it.

Because, as yet, it doesn't but neither does that matter.

The book reports as dirty if the collections are dirty. As there are so few 
collections, it makes more sense to check each collection when asked rather 
than continuously set the book dirty flag every time another collection has 

It's retrospective, not prospective. I see no need to check or set the book 
dirty flag every single time a single entity is changed, again and again and 
again throughout the entire session. Propagating the flag to the collection 
is sufficient.

The API is: If the book detects that a collection is dirty, the book reports 
itself as dirty.

Reading the dirty flag directly will not be possible (as this would expose the 
entire private QofBook struct in the API).

It shouldn't have been exposed and UI source files should not be including 
qofbook-p.h, it will not be available when using QOF as a library.

> O.K.  Lets try another approach.  The following is what I want.  Tell me
> why you can't implement it.
> gboolean
> qof_book_is_dirty (QofBook *book)
> {
> 	return book->inst.dirty;
> }

That's currently called qof_book_not_saved().

> guint
> qof_book_get_dirty_time (QofBook *book)
> {
> 	return book->dirty_time;
> }

I'll consider that.

> void
> qof_book_set_dirty (QofBook *book)
> {
> 	book->inst.dirty = TRUE;
> 	if (book->dirty_time == 0)
> 		book->dirty_time = time();
> }

But it's pointless even checking this EVERY single time an entity changes. 
Nobody wants that information, all we want is to detect the FIRST change.

This function would get called every time qof_instance_set_dirty() is called 
and that's just overkill.

Instead of calling the collections ONCE each, you want the instance to call 
the book EVERY single time it changes! Instead of 12 or so calls, you are 
recommending tens of thousands when only ONE is necessary.

That's like the foot soldier telling the major-general every time he starts to 

Instances get dirty, it's their job, it's what they do. Books don't need to 
know every single time. Once is perfectly adequate.

There could be tens of thousands of calls that set an instance dirty during a 
user session - many instances are set dirty repeatedly already. The book 
simply doesn't need to be told, it can ask when it needs the information 
(which is far less often than it may appear).

Better, IMHO, to check the collections and cache the value - after all it is 
the UI that controls WHEN the data is saved and how. Until the UI issues a 
save command, the first dirty flag is the same as the last, there's no point 
calling set() every single time.

There's also no point in asking the book if it is dirty once you've got the 
answer YES. It will stay dirty until the UI issues the qof_session_save(). 
The book itself has no control over the save operations - it cannot clear 
it's own flag and it cannot force a save. This function shouldn't need to be 
called every few seconds or at every window paint. Cache it and wait for a 

There's no point asking the book if it is dirty again and again and again. 
It's told you once, that's all it can do.

Therefore, qof_book_not_saved needs to be called far fewer times than you seem 
to imagine.

> void
> qof_book_set_clean (QofBook *book)
> {
> 	book->inst.dirty = FALSE;
> 	book->dirty_time = 0;
> }

At no time can the set_clean functions be public, these are reserved for the 
backends. There is no situation where the UI can be allowed to set the book 
to clean without going through a Save.

> It totally baffles me why this has taken more than three email messages.
> Do you not have a back pointer from the collection to the book?  That
> seems like a *HUGE* oversight if that's the problem.

Yes, each collection has a pointer to it's book. I just don't see the need to 
pass that flag back every single time an entity is ever changed. When you 
need to know that information (which is after the first change ONLY), the 
collections can be checked. I believe it is more efficient for the UI to 
cache this value until such time as the UI issues a Save command when it is 

We should be providing information when it is requested, not setting it 
repeatedly when nobody cares anymore.


Neil Williams

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://lists.gnucash.org/pipermail/gnucash-devel/attachments/20050722/6bfe1508/attachment.bin

More information about the gnucash-devel mailing list