Skip to content

Commit c8565f7

Browse files
committed
Resolving iterator TODO in "initCovering()" of EdgeQuery
1 parent 09e2dd3 commit c8565f7

File tree

1 file changed

+55
-46
lines changed

1 file changed

+55
-46
lines changed

s2/edge_query.go

Lines changed: 55 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -689,58 +689,67 @@ func (e *EdgeQuery) initCovering() {
689689
// this will save work on every subsequent query.
690690
e.indexCovering = make([]CellID, 0, 6)
691691

692-
// TODO(roberts): Use a single iterator below and save position
693-
// information using pair {CellID, ShapeIndexCell}.
694-
next := NewShapeIndexIterator(e.index, IteratorBegin)
695-
last := NewShapeIndexIterator(e.index, IteratorEnd)
696-
last.Prev()
697-
if next.CellID() != last.CellID() {
698-
// The index has at least two cells. Choose a level such that the entire
699-
// index can be spanned with at most 6 cells (if the index spans multiple
700-
// faces) or 4 cells (it the index spans a single face).
701-
level, ok := next.CellID().CommonAncestorLevel(last.CellID())
702-
if !ok {
703-
level = 0
704-
} else {
705-
level++
706-
}
692+
iter := NewShapeIndexIterator(e.index, IteratorBegin)
707693

708-
// Visit each potential top-level cell except the last (handled below).
709-
lastID := last.CellID().Parent(level)
710-
for id := next.CellID().Parent(level); id != lastID; id = id.Next() {
711-
// Skip any top-level cells that don't contain any index cells.
712-
if id.RangeMax() < next.CellID() {
713-
continue
714-
}
694+
type indexPosition struct {
695+
id CellID
696+
cell *ShapeIndexCell
697+
}
715698

716-
// Find the range of index cells contained by this top-level cell and
717-
// then shrink the cell if necessary so that it just covers them.
718-
cellFirst := next.clone()
719-
next.seek(id.RangeMax().Next())
720-
cellLast := next.clone()
721-
cellLast.Prev()
722-
e.addInitialRange(cellFirst, cellLast)
723-
break
724-
}
699+
first := indexPosition{iter.CellID(), iter.IndexCell()}
700+
iter.End()
701+
iter.Prev()
702+
last := indexPosition{iter.CellID(), iter.IndexCell()}
725703

704+
if first.id == last.id {
705+
e.indexCovering = append(e.indexCovering, first.id)
706+
e.indexCells = append(e.indexCells, first.cell)
707+
return
726708
}
727-
e.addInitialRange(next, last)
728-
}
729709

730-
// addInitialRange adds an entry to the indexCovering and indexCells that covers the given
731-
// inclusive range of cells.
732-
//
733-
// This requires that first and last cells have a common ancestor.
734-
func (e *EdgeQuery) addInitialRange(first, last *ShapeIndexIterator) {
735-
if first.CellID() == last.CellID() {
736-
// The range consists of a single index cell.
737-
e.indexCovering = append(e.indexCovering, first.CellID())
738-
e.indexCells = append(e.indexCells, first.IndexCell())
710+
// The index has at least two cells. Choose a level such that the entire
711+
// index can be spanned with at most 6 cells (if the index spans multiple
712+
// faces) or 4 cells (if the index spans a single face).
713+
level, ok := first.id.CommonAncestorLevel(last.id)
714+
if !ok {
715+
level = 0
739716
} else {
740-
// Add the lowest common ancestor of the given range.
741-
level, _ := first.CellID().CommonAncestorLevel(last.CellID())
742-
e.indexCovering = append(e.indexCovering, first.CellID().Parent(level))
743-
e.indexCells = append(e.indexCells, nil)
717+
level++
718+
}
719+
720+
// Visit each top-level cell.
721+
iter.Begin()
722+
lastTopLevel := last.id.Parent(level)
723+
for id := first.id.Parent(level); ; id = id.Next() {
724+
// Skip any top-level cells that don't contain any index cells.
725+
if id.RangeMax() < iter.CellID() {
726+
if id == lastTopLevel {
727+
break
728+
}
729+
continue
730+
}
731+
732+
// Find the range of index cells contained by this top-level cell and
733+
// then shrink the cell if necessary so that it just covers them.
734+
cellFirst := indexPosition{iter.CellID(), iter.IndexCell()}
735+
iter.seek(id.RangeMax().Next())
736+
iter.Prev()
737+
cellLast := indexPosition{iter.CellID(), iter.IndexCell()}
738+
739+
if cellFirst.id == cellLast.id {
740+
e.indexCovering = append(e.indexCovering, cellFirst.id)
741+
e.indexCells = append(e.indexCells, cellFirst.cell)
742+
} else {
743+
ancestorLevel, _ := cellFirst.id.CommonAncestorLevel(cellLast.id)
744+
e.indexCovering = append(e.indexCovering, cellFirst.id.Parent(ancestorLevel))
745+
e.indexCells = append(e.indexCells, nil)
746+
}
747+
748+
if id == lastTopLevel {
749+
break
750+
}
751+
752+
iter.Next()
744753
}
745754
}
746755

0 commit comments

Comments
 (0)