Christopher Browne cbbrowne
Thu Mar 2 15:51:26 PST 2006
Christopher Browne wrote

>I whiteboarded a couple of attempts at algorithms for this, this
>afternoon.  It needs a bit more thought, I think, to come up with
>something final...
>  
>
Here's what I have at this point...

The notion that seems to make sense, here, is to construct all of the
possible maximum-length paths from each origin.  Note that this is a
loose mix of C-like and pl/pgsql-like code; I'm not yet expecting it to
be exactly right...

create sequence vtr_seq;
create table vtraversals (id integer primary key default nextval
('vtr_seq'),
                                          origin integer, final integer);
create table vpaths (id integer,
                                  position integer not null unique,
                                  node integer not null,
                                  primary key(id, position));


So, we start by initializing each with the origin node...

insert into vtraversals (id, origin, final) select nextval('vtr_seq'),
no_id, no_id from sl_node;
insert into vpaths (id, position, node) select id, 0, origin from
vtraversals;

Now, we iterate, until the traversals stop changing...
done := false;
while (not done) do {
   done := true;
   for trec in select * from vtraversals loop
      -- Let's try to extend this path...
      quantity := 0;
      for prec in select * from sl_path where pa_server = trec.final  
-- Needs to link in at the end
                          and pa_client not in (select node from vpaths
vp where vp.id = trec.id) loop
                              -- Needs NOT to generate a cycle
                              -- An extra clause to eliminate cases
where we are crossing paths with subscription might go here
              done := false;
              if quantity := 0 then
                -- extend the existing traversal
                update vtraversals set final = prec.pa_client where id =
trec.id;
                insert into vpaths (id,position,node) values (trec.id,
select max(position)+1 from vpaths where id = trec.id, pa_client);
              else
                -- create a new traversal, copying the old one, and
changing the last entry
                new_trav := nextval('vtr_seq');
                insert into vpaths select new_trav, position, node from
vpaths where id = trec.id;
                insert into vtraversals (id, origin, final) values
(new_trav, trec.origin, prec.pa_client);
                update vpaths set node = prec.pa_client where id =
new_trav and position = (select position from vpaths where id = new_trav
order by position descending limit 1);
              end if;
         end loop;
   end loop;
}

That gives us a list of all the longest possible traversals.

*Maybe* at this point, we remove the traversals that contain cases where
a node is subscribing to a set originating from the origin, but that
goes around the shaping of the subscription sets.  Possibly that could
get handled in the loop where the feasible paths were being selected...

We then walk backwards through them to generate listener entries; I'll
not bother looking at that until proper holes have been shot in the above...



More information about the Slony1-general mailing list