Skip to content

Commit 9f19ca5

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

File tree

1 file changed

+58
-46
lines changed

1 file changed

+58
-46
lines changed

s2/edge_query.go

Lines changed: 58 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -689,58 +689,70 @@ 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)
693+
if iter.Done() {
694+
return
695+
}
707696

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-
}
697+
type indexPosition struct {
698+
id CellID
699+
cell *ShapeIndexCell
700+
}
715701

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-
}
702+
first := indexPosition{iter.CellID(), iter.IndexCell()}
703+
iter.End()
704+
iter.Prev()
705+
last := indexPosition{iter.CellID(), iter.IndexCell()}
725706

707+
if first.id == last.id {
708+
e.indexCovering = append(e.indexCovering, first.id)
709+
e.indexCells = append(e.indexCells, first.cell)
710+
return
726711
}
727-
e.addInitialRange(next, last)
728-
}
729712

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())
713+
// The index has at least two cells. Choose a level such that the entire
714+
// index can be spanned with at most 6 cells (if the index spans multiple
715+
// faces) or 4 cells (if the index spans a single face).
716+
level, ok := first.id.CommonAncestorLevel(last.id)
717+
if !ok {
718+
level = 0
739719
} 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)
720+
level++
721+
}
722+
723+
// Visit each top-level cell.
724+
iter.Begin()
725+
lastTopLevel := last.id.Parent(level)
726+
for id := first.id.Parent(level); ; id = id.Next() {
727+
// Skip any top-level cells that don't contain any index cells.
728+
if id.RangeMax() < iter.CellID() {
729+
if id == lastTopLevel {
730+
break
731+
}
732+
continue
733+
}
734+
735+
// Find the range of index cells contained by this top-level cell and
736+
// then shrink the cell if necessary so that it just covers them.
737+
cellFirst := indexPosition{iter.CellID(), iter.IndexCell()}
738+
iter.seek(id.RangeMax().Next())
739+
iter.Prev()
740+
cellLast := indexPosition{iter.CellID(), iter.IndexCell()}
741+
742+
if cellFirst.id == cellLast.id {
743+
e.indexCovering = append(e.indexCovering, cellFirst.id)
744+
e.indexCells = append(e.indexCells, cellFirst.cell)
745+
} else {
746+
ancestorLevel, _ := cellFirst.id.CommonAncestorLevel(cellLast.id)
747+
e.indexCovering = append(e.indexCovering, cellFirst.id.Parent(ancestorLevel))
748+
e.indexCells = append(e.indexCells, nil)
749+
}
750+
751+
if id == lastTopLevel {
752+
break
753+
}
754+
755+
iter.Next()
744756
}
745757
}
746758

0 commit comments

Comments
 (0)