From: Art Olin <olin@triumf.ca>
Date: Thu, 24 Jun 1999 22:31:29 -0700 (PDT)
To: E614Software@relay.phys.ualberta.ca
Subject: More on data structures

In his cogent analysis of the data structure that I suggested, Paul touched 
on all the key points. 

   A linked list is good if you need to dynamically allocate
   memory. We can easily anticipate the maximum number of hits in the
   detector. 

We agree here. My proposal creates dc_ptl(nmgw), a massive static
array of the hit data including backward and forward pointers. So
it's a linked list, but not a dynamically allocated one, limited by
a maximum hit value.
   
   Moving hits from one list to another imposes some constraints
   on the tracking logic that I don't think we want. When making a
   fit for a track you may want to consider ALL hits, even if those
   hits are already associated with another track.

This is exactly the thing we have to work through. The advantage
of my approach is that we move things into the track hits from the
hits list, thus shortening the search through the list of unused
hits. If we need to search through the entire hit list, we can
do it through a loop on dc_ptl(1:nmgw), but there is no advantage
over Paul's suggestion. If we want to loop through all the
unassigned hits, then we loop through the pointers in the dc_ptl 
array.

   The computing overhead for removing a hit from a list and
   inserting it into another is LARGE; 2 function calls, 6
   de-references of prev and next pointers, reassignment of values in
   6 pointers, IF conditionals to check for NULL pointer values at
   each step, etc. This is tough to justify for easy transfer of 4
   REALS, a LOGICAL, a CHAR, and a POINTER.

My count is 8 pointer reassignments and one IF conditional starting
with dc_ptc pointing to the hit to be moved and trk_pt to the end of
the track list, and ending with dc_ptc to the next hit:

    dc_ptc%prev%next =>dc_ptc%next   !Reassign the dc_ptl pointers
    dc_ptc%next%prev =>dc_ptc%prev   !to skip this hit
    temp => dc_ptc%next   
    IF (ASSOCIATED(trk_pt) then      !Test if not first track point
      dc_ptc%next => trk_pt          !Assign pointers for track list
      trk_pt%prev => dc_ptc
    ELSE
      NULLIFY(dc_ptc%next)
    END IF
    NULLIFY(dc_ptc%prev)             !point added is top of track list
    trk_pt => dc_ptc                 !
    dc_ptc => temp                   !dc_ptc to next hit.

We would make this into a movehit(dc_ptc, trk_pt) subroutine.  If we
used a normal linked list, omitting the dc_ptr%prev component, then
the movehit procedure would be shortened by several operations, but
it would have to start with dc_ptc pointing to the previous hit. I
think we lose some flexibility, but have not yet ruled out this
possibility.
   
   FORTRAN programmers won't understand linked lists.


As a FORTRAN programmer I guess I'm testing this hypothesis. 

   I'd suggest the following alternative.


   Implement most all of the structures in the current COMMON
   blocks, but put them into MODULES so that their function is
   logically tied together. (Note: there are more characteristics of
   a WIRE that are not included below -- CENTER, END1, END2.)

Yes I was simplifying a bit. Do you mean the actual arrays or
do you see an advantage to defining hit and wire structures?
   
   Put all hits in a massive array and create pointers to
   elements in that array to associate them with individual wires and
   tracks. This way we can create any list of hits, and sort those
   lists quickly.

I think this is what I am proposing. The difference is that in
your proposal the pointers are in the track structure rather than
the hit structure. If we don't actually want to remove the hits
as we use them, then this is more efficient, and simpler. 






More on data structures / Art Olin

Created for the The Center for Subatomic Research E614 Project Projects Page.
Created by The CoCoBoard.