Ignore:
Timestamp:
2009-11-09T23:58:58+01:00 (14 years ago)
Author:
hansendc
Message:

This fixes #3796.

The issue was that we somehow ended up with a branch node
that had no valid children. We assumed in the iterator
that any node with no content must have children, but
that was wrong.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/osm/QuadBuckets.java

    r2420 r2423  
    1717{
    1818    public static boolean debug = false;
    19     static boolean consistency_testing = false;
     19    static boolean consistency_testing = true;
    2020
    2121    static void abort(String s)
     
    247247                this.content = null;
    248248            }
     249            if (this.canRemove())
     250                this.remove_from_parent();
    249251            return ret;
    250252        }
     
    365367                }
    366368                if (level >= NR_LEVELS-1) {
    367                     out("can not split, but too deep: " + level + " size: " + content.size());
     369                    if (debug)
     370                        out("can not split, but too deep: " + level + " size: " + content.size());
    368371                    return;
    369372                }
     
    484487            return true;
    485488        }
     489        QBLevel nextSibling()
     490        {
     491            QBLevel next = this;
     492            QBLevel sibling = next.next_sibling();
     493            // Walk back up the tree to find the
     494            // next sibling node.  It may be either
     495            // a leaf or branch.
     496            while (sibling == null) {
     497                if (debug) {
     498                    out("no siblings at level["+next.level+"], moving to parent");
     499                    }
     500                next = next.parent;
     501                if (next == null) {
     502                    break;
     503                    }
     504                sibling = next.next_sibling();
     505            }
     506            next = sibling;
     507            return next;
     508        }
    486509        QBLevel nextContentNode()
    487510        {
    488511            QBLevel next = this;
    489             if (this.isLeaf()) {
    490                 QBLevel sibling = next.next_sibling();
    491                 // Walk back up the tree to find the
    492                 // next sibling node.  It may be either
    493                 // a leaf or branch.
    494                 while (sibling == null) {
    495                     if (debug) {
    496                         out("no siblings at level["+next.level+"], moving to parent");
    497                     }
    498                     next = next.parent;
    499                     if (next == null) {
    500                         break;
    501                     }
    502                     sibling = next.next_sibling();
    503                 }
    504                 next = sibling;
    505             }
     512            if (this.isLeaf())
     513                next = this.nextSibling();
    506514            if (next == null)
    507515                return null;
    508             // all branches are guaranteed to have
    509             // at least one leaf.  It may not have
    510             // any contents, but there *will* be a
    511             // leaf.  So, walk back down the tree
     516            // Walk back down the tree
    512517            // and find the first leaf
    513             while (!next.isLeaf()) {
    514                 if (next.hasContent() && next != this) {
     518            while (next != null && !next.isLeaf()) {
     519                if (next.hasContent() && next != this)
    515520                    break;
    516                 }
    517                 if (debug) {
     521                if (debug)
    518522                    out("["+next.level+"] next node ("+next+") is a branch (content: "+next.hasContent()+"), moving down...");
    519                 }
     523                boolean progress = false;
    520524                for (QBLevel child : next.children) {
    521                     if (child == null) {
     525                    if (child == null)
    522526                        continue;
    523                     }
    524527                    next = child;
     528                    progress = true;
    525529                    break;
    526530                }
    527             }
     531                if (!progress) {
     532                    // this should out it as not being a branch
     533                    next.children = null;
     534                    break;
     535                }
     536            }
     537            // This means that there are no leaves or branches
     538            // with content as children.  We must continue to
     539            // search siblings.
     540            if (next == this)
     541                return nextSibling().nextContentNode();
    528542            return next;
    529543        }
     
    784798            return QuadTiling.tile2LatLon(this.quad);
    785799        }
     800        void remove_from_parent()
     801        {
     802            if (parent == null)
     803                return;
     804
     805            int nr_siblings = 0;
     806            for (int i = 0; i < parent.children.length; i++) {
     807                QBLevel sibling = parent.children[i];
     808                if (sibling != null)
     809                    nr_siblings++;
     810                if (sibling != this)
     811                    continue;
     812                if (this.content != null ||
     813                    this.children != null)
     814                    abort("attempt to remove non-empty child");
     815                parent.children[i] = null;
     816                nr_siblings--;
     817            }
     818            if (parent.canRemove())
     819                parent.remove_from_parent();
     820        }
     821        boolean canRemove()
     822        {
     823            if (content != null && content.size() > 0)
     824                return false;
     825            if (children != null) {
     826                for (QBLevel child : children) {
     827                    if (child != null)
     828                        return false;
     829                }
     830            }
     831            return true;
     832        }
    786833    }
    787834
     
    10731120            //    an element
    10741121            content_index--;
    1075             peek(); //TODO Is the call to peek() necessary?
    1076             current_node.content.remove(content_index);
     1122            T object = peek(); //TODO Is the call to peek() necessary?
     1123            current_node.remove_content(object);
    10771124        }
    10781125    }
Note: See TracChangeset for help on using the changeset viewer.