Re: iterate over a model and remove rows




Am Freitag, den 05.10.2007, 19:48 +0200 schrieb BenoÃt Dejean:
Hello,

I'd like to know if it is safe to walk over a model and remove rows at
the same time. I'm doing this in gnome-system-monitor in many places.

Two examples:

The first function walks a list_store and removes some rows.
But i can see that multiple passes are required to drop all the old
rows, i.e. it is necessary to walk the list again to find new elements.
For example, if the list's size is ~100, a dozen of walks are required.

Actually I'd expect a half-dozen of runs, see below.

static void
remove_old_disks(GtkTreeModel *model, [...])
{
  GtkTreeIter iter;

  if (!gtk_tree_model_get_iter_first(model, &iter))
    return;

  do {
    char *dir;
    guint i;
    gboolean found;

    gtk_tree_model_get(model, &iter,
                     DISK_DIR, &dir,
                     -1);

    found = [...];

    if (!found) {
      if (!gtk_list_store_remove(GTK_LIST_STORE(model), &iter))
      break;
      else
      continue; // FIXME: leaks dir
    }

    g_free(dir);

  } while (gtk_tree_model_iter_next(model, &iter));
}

The doc of gtk_list_store_remove says that it sets the iter to the next
valid row.  Keep in mind that the "continue" statement jumps to right
before the continuation portion even for do...while loops.  This causes
the iteration to advance the iter by *two* rows when a remove happens.

Second example: recursively trim some branches in a tree_store.
This code seems to work, but may be it is silently corrupting memory.

template<typename List>
static void
remove_info_from_tree (ProcData *procdata, GtkTreeModel *model,
                     ProcInfo *current, [...])
{
  GtkTreeIter child_node;

  while (gtk_tree_model_iter_children(model, &child_node,
&current->node)) {
    ProcInfo *child = 0;
    gtk_tree_model_get(model, &child_node, COL_POINTER, &child, -1);
    remove_info_from_tree(procdata, model, child, [...]);
  }

  g_assert(not gtk_tree_model_iter_has_child(model, &current->node));

  gtk_tree_store_remove(GTK_TREE_STORE(model), &current->node);
}

Thank you.

Don't know about this one.

-- 
Regards,
  Renà Stadler





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]