views:

253

answers:

2

Hi all, I depend on VirtualTreeView to display thousands of items which are bound to change occasionally and when this happens the tree is cleaned and populated again.

Sorting is done automatically (toAutoSort flag set) but this has an unwanted effect of initializing all the nodes recursively and this is a very expensive operation as you can imagine.

So when should I call the .Sort method when toAutoSort is off? (DoInitChildren looked plausible but I got weird results like reversed results occasionaly so I assume that's no good event to sort the children.)

+3  A: 

The general rule in this sort of scenario is to sort after all the new items have been added. That way you only sort (and initialize) once.

Mason Wheeler
There's no "new" items to speak of. The tree is simply revamped and reconstructed (as the data structures backing the tree completely change in my case).
utku_karatas
"Reconstructing" the tree is equivalent to creating a new one. The principle is the same: Suspend sorting, begin construction, add all nodes, end construction, then sort.
Mason Wheeler
+1  A: 

Unless the entire tree is completely different every time, you can get better performance by not clearing the tree, but by separately building a new list of items (just identification of the items), sorting that list, then walking both trees in order... the general algorithm looks something like this (the left list is the "new list" and the right list is the "existing list"):

LeftCur := 0;
RightCur := 0;
while (LeftCur < TotalLeft) and (RightCur < TotalRight) then
  begin
    if LeftList[LeftCur] = RightList[RightCur] then
      begin
        // matches, so just advance 
        Inc(LeftCur);
        Inc(RightCur);            
      end
    else if LeftList[LeftCur] < RightList[RightCur] then
      begin
        // insert happens BEFORE RightCur
        InsertLeftItemToRight;
        Inc(RightCur);
        Inc(TotalRight);
      end
    else if LeftList[LeftCur] > RightList[RightCur] then
      begin
        DeleteRightItem;
        Dec(TotalRight);
      end;
  end;
  While RightCur < TotalRight do
    begin
      DeleteRightItem;
      Dec(TotalRight);
    end;
  While LeftCur < TotalLeft do
    AppendLeftItemToRight;

This way the list remains sorted, and you only have to complete loading an item in the InsertLeftItemToRight steps. In a tree, whenever you match, you run a similar routine for the children. This concept is weighted against the fact that items in the existing list are not going to change much or may be expensive to fully load.

skamradt
Thanks for the detailed answer but VirtualTreeView is so blazing fast, simple Clear/Reload tactic seems enough. (apparently except sorting though :)
utku_karatas