durusmail: durus-users: Re: A question about consistence in durus
A question about consistence in durus
2006-04-21
2006-04-21
2006-04-21
2006-04-21
Re: A question about consistence in durus
2006-04-22
2006-04-22
2006-04-22
2006-04-22
2006-04-22
2006-04-23
2006-04-23
2006-04-23
2006-04-23
2006-04-23
2006-04-23
Re: A question about consistence in durus
Jesus Cea
2006-04-23
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Neil Schemenauer wrote:
>> Anything more that I can do to convince you?
>
> A patch?  If it can be done cleanly and is not too expensive then I
> think it would be accepted.

I'm reading the "_persistent.c" code and seems that much of the code
needed is already there. In fact the "_p_touched" is all we need, and is
already there, for the benefice of the caching code.

That attribute is set to "1" when there is ANY read/write access to the
object. Seems trivial, in the same code, to update a "set" that would
provide the set of "accessed" objects. That set would be cleared at the
end of commit/abort and would collect the "used" objects along the
following transaction.

If you are worried about the performance of updating a "set" in every
attribute access, I guess that the C code could do the bookkeeping
inside, with no overhead, and provide that info using an iterator or a
list, via a method call.

The C code could keep each persistent instance in one of two
double-linked lists: touched and untouched. Each attribute access could
move the object to the touched list (if it is already there, it would
move it to the beginning of the list, for better efficience). The moving
to the untouched list would be a method call, and would move all the
objects at once. You can move all the touched objects to the untouched
list with a simple two pointer updates.

Each persistent instance would add two new pointers: "next" and "previous".

Sample code (or pseudocode):

Current code: (in C)
  if (!self->p_touched)   <- This comparison is unnecesary :-)
    self->p_touched = 1;

My proposal:
  self->p_touched = 1; /* we don't need the if */
  *self->previous=self->next; /* delinks from a list (touched or
untouched, we don't know) */
  if (self->next) {
    self->next->previous=self->previous;
  }
  self->next=touched_head; /* links to touched list */
  if (!touched_head)
    touched_tail=self;
  touched_head=&self;
  self->previous=touched_head;

The code is larger, but very efficient.

We can iterate along the touched objects with simple pointer following.

We can move all touched objects to the untouched list with a few pointers:

if (touched_head) { /* We have touched objects */
  touched_tail->next=untouched_head; */ We links both lists */
  untouched_head->previous=touched_tail;
  untouched_head=touched_head;
  touched_head=NULL;
}

We need to intercept object deallocation to retire the object from its
linked list. The only caveat here is to move "touched_tail" using the
backpointer if the deleted object was the "touched_tail" one.

I find this improvement pretty performing. A single python bytecode
execution would be hundred times more costly.

Please, at least consider it.

- --
Jesus Cea Avion                         _/_/      _/_/_/        _/_/_/
jcea@argo.es http://www.argo.es/~jcea/ _/_/    _/_/  _/_/    _/_/  _/_/
jabber / xmpp:jcea@jabber.org         _/_/    _/_/          _/_/_/_/_/
                               _/_/  _/_/    _/_/          _/_/  _/_/
"Things are not so easy"      _/_/  _/_/    _/_/  _/_/    _/_/  _/_/
"My name is Dump, Core Dump"   _/_/_/        _/_/_/      _/_/  _/_/
"El amor es poner tu felicidad en la felicidad de otro" - Leibniz
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.2 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iQCVAwUBREsA4Jlgi5GaxT1NAQJe7AQAgRBpj21dcbC5RopZ80Wtp3VFhl4yhMbL
QEouGNpJl8wTpttcWh25kRFf9tyNJYijom0YpJ49IrAkql1MoyysMtgxMnFlHB4v
OzdBtpLMTkeFvmWPbd0QOJ4SF27O+YiNzctPFuf3AnPUOakh6MdYdfCUgFS+G/8U
Nv9cCrUiGIs=
=kCVO
-----END PGP SIGNATURE-----
reply