Esempio n. 1
0
QModelIndex TreeListModel::parent(const QModelIndex &index) const
{
  if (!index.isValid())
    return QModelIndex();

  TreeList *childItem = static_cast<TreeList*>(index.internalPointer());
  if (childItem == rootItem)
    return QModelIndex();

  TreeList *parentItem = childItem->parent();

  if (parentItem == rootItem)
    return QModelIndex();

  return createIndex(parentItem->row(), 0, parentItem);
}
TreeList* TreeList::removeChunkReplaceIfNeeded(TreeChunk* tc) {

  TreeList* retTL = this;
  FreeChunk* list = head();
  assert(!list || list != list->next(), "Chunk on list twice");
  assert(tc != NULL, "Chunk being removed is NULL");
  assert(parent() == NULL || this == parent()->left() || 
    this == parent()->right(), "list is inconsistent");
  assert(tc->isFree(), "Header is not marked correctly");
  assert(head() == NULL || head()->prev() == NULL, "list invariant");
  assert(tail() == NULL || tail()->next() == NULL, "list invariant");

  FreeChunk* prevFC = tc->prev();
  TreeChunk* nextTC = TreeChunk::as_TreeChunk(tc->next());
  assert(list != NULL, "should have at least the target chunk");

  // Is this the first item on the list?
  if (tc == list) {
    // The "getChunk..." functions for a TreeList will not return the
    // first chunk in the list unless it is the last chunk in the list
    // because the first chunk is also acting as the tree node.
    // When coalescing happens, however, the first chunk in the a tree
    // list can be the start of a free range.  Free ranges are removed
    // from the free lists so that they are not available to be 
    // allocated when the sweeper yields (giving up the free list lock)
    // to allow mutator activity.  If this chunk is the first in the
    // list and is not the last in the list, do the work to copy the
    // TreeList from the first chunk to the next chunk and update all
    // the TreeList pointers in the chunks in the list.
    if (nextTC == NULL) {
      assert(prevFC == NULL, "Not last chunk in the list")
      set_tail(NULL);
      set_head(NULL);
    } else {
      debug_only(
        if (PrintGC && Verbose) {
  	gclog_or_tty->print_cr("Removing first but not only chunk in TreeList");
        gclog_or_tty->print_cr("Node: " INTPTR_FORMAT " parent: " INTPTR_FORMAT
            " right: " INTPTR_FORMAT " left: " INTPTR_FORMAT, 
            tc, tc->list()->parent(), tc->list()->right(), tc->list()->left());
        gclog_or_tty->print_cr("Next before: " INTPTR_FORMAT " parent: " 
            INTPTR_FORMAT " right: " INTPTR_FORMAT " left: " INTPTR_FORMAT,
            nextTC, nextTC->list()->parent(), nextTC->list()->right(), 
  	  nextTC->list()->left());
        gclog_or_tty->print_cr("	head: " INTPTR_FORMAT " tail: " 
            INTPTR_FORMAT, nextTC->list()->head(), nextTC->list()->tail());
        }
      )
      // copy embedded list.
      nextTC->set_embedded_list(tc->embedded_list());
      retTL = nextTC->embedded_list();
      // Fix the pointer to the list in each chunk in the list.
      // This can be slow for a long list.  Consider having
      // an option that does not allow the first chunk on the
      // list to be coalesced.
      for (TreeChunk* curTC = nextTC; curTC != NULL; 
	  curTC = TreeChunk::as_TreeChunk(curTC->next())) {
        curTC->set_list(retTL);
      }
      // Fix the parent to point to the new TreeList.
      if (retTL->parent() != NULL) {
	if (this == retTL->parent()->left()) {
	  retTL->parent()->setLeft(retTL);
	} else {
	  assert(this == retTL->parent()->right(), "Parent is incorrect");
	  retTL->parent()->setRight(retTL);
	}
      }
      // Fix the children's parent pointers to point to the
      // new list.
      assert(right() == retTL->right(), "Should have been copied");
      if (retTL->right() != NULL) {
	retTL->right()->setParent(retTL);
      }
      assert(left() == retTL->left(), "Should have been copied");
      if (retTL->left() != NULL) {
	retTL->left()->setParent(retTL);
      }
      retTL->link_head(nextTC);
      debug_only(
        if (PrintGC && Verbose) {
          gclog_or_tty->print_cr("Next after: " INTPTR_FORMAT " parent: " 
            INTPTR_FORMAT " right: " INTPTR_FORMAT " left: " INTPTR_FORMAT,
            nextTC, nextTC->list()->parent(), nextTC->list()->right(), 
  	    nextTC->list()->left());
          gclog_or_tty->print_cr("	head: " INTPTR_FORMAT " tail: " 
            INTPTR_FORMAT, nextTC->list()->head(), nextTC->list()->tail());
        }
      )
      assert(nextTC->isFree(), "Should be a free chunk");
    }